diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt
new file mode 100644
index 0000000..be28081
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt
@@ -0,0 +1,149 @@
+/*
+ * lilJudd
+ * Copyright (C) 2023 moonleay
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package net.moonleay.lilJudd.extensions
+
+import com.kotlindiscord.kord.extensions.commands.Arguments
+import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice
+import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalString
+import com.kotlindiscord.kord.extensions.commands.converters.impl.string
+import com.kotlindiscord.kord.extensions.extensions.Extension
+import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
+import com.kotlindiscord.kord.extensions.types.respond
+import dev.kord.common.Color
+import dev.kord.core.behavior.channel.createMessage
+import dev.kord.core.behavior.createRole
+import dev.kord.rest.builder.message.create.actionRow
+import net.moonleay.lilJudd.data.tables.MatchPlanningData
+import net.moonleay.lilJudd.extensions.component.MatchTypes
+import net.moonleay.lilJudd.jobs.MatchJob
+import net.moonleay.lilJudd.jobs.component.JobManager
+import net.moonleay.lilJudd.util.EmbedUtil
+import net.moonleay.lilJudd.util.MessageUtil
+import net.moonleay.lilJudd.util.TimeUtil
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.sql.insert
+import org.jetbrains.exposed.sql.transactions.transaction
+
+class MatchExtension : Extension() {
+
+ override val name = "match"
+ override val allowApplicationCommandInDMs: Boolean
+ get() = false
+
+
+ override suspend fun setup() {
+ publicSlashCommand(::MatchArguments) {
+ name = "match"
+ description = "Create a match"
+ this.action {
+ val args = this.arguments
+ val m = this.member!!
+ val gID = this.guild!!.id.value.toString()
+ val cID = this.channel.id.value.toString()
+ val opponent = args.opponent ?: "?"
+ val msg = this.respond {
+ this.embeds.add(
+ MessageUtil.getEmbedWithTable(
+ Color(0X4C4645),
+ args.matchType.readableName,
+ "***Vs. $opponent***\n" +
+ "At ${args.timeStamp}\n" +
+ "Registered by ${m.mention}",
+ mapOf(
+ "Signed up" to listOf(),
+ )
+ )
+ )
+
+ this.actionRow {
+ this.components.addAll(EmbedUtil.getMatchButtons().components)
+ }
+ } // filter time to date:
+ val zdt = TimeUtil.getDateFromString(args.timeStamp)
+ // get the string for the cronjob
+ val jobString = TimeUtil.getCronjobStringFromDate(zdt)
+ // create the role
+ val role = this.guild!!.createRole {
+ this.name =
+ "${args.matchType.readableName} Vs ${opponent} At ${zdt.dayOfMonth}/${zdt.month}/${zdt.year} ${zdt.hour}:${zdt.minute}"
+ this.mentionable = true
+ }
+ // Check if the role was created successfully
+ if (role == null) {
+ this.channel.createMessage {
+ this.embeds.add(
+ MessageUtil.getEmbed(
+ Color(0xE0311A),
+ "500: Internal Error",
+ "Could not find created role.\n" +
+ "It seems, that said role could not be created.",
+ "system message"
+ )
+ )
+ }
+ return@action
+ }
+ lateinit var tableID: EntityID
+ transaction {
+ tableID = MatchPlanningData.insert {
+ it[MatchPlanningData.serverid] = gID
+ it[MatchPlanningData.channelid] = cID
+ it[MatchPlanningData.messageid] = msg.id.value.toString()
+ it[MatchPlanningData.matchtype] = args.matchType.readableName
+ it[MatchPlanningData.roleid] = role.id.value.toString()
+ it[MatchPlanningData.registererid] = m.id.value.toString()
+ it[MatchPlanningData.opponentName] = opponent
+ it[MatchPlanningData.timestamp] = (zdt.toEpochSecond() * 1000).toString()
+ it[MatchPlanningData.jobstr] = jobString
+ } get MatchPlanningData.id
+ }
+ if (tableID == null) {
+ return@action // Not saved to db
+ }
+ JobManager.addJob(
+ MatchJob(
+ jobString,
+ tableID.value,
+ "${args.matchType.readableName}_Vs_${opponent}_[${tableID.value}]-${gID}_${cID}"
+ )
+ )
+ }
+ }
+ }
+
+ inner class MatchArguments : Arguments() {
+
+ val matchType by enumChoice {
+ this.name = "match"
+ this.description = "The type of match"
+ this.typeName = "en_US"
+ }
+
+
+ val timeStamp by string {
+ this.name = "timestamp"
+ this.description = "The timestamp of the match. Format \"dd.MM.yyyy HH:mm\"."
+ }
+
+ val opponent by optionalString {
+ this.name = "opponent"
+ this.description = "The opponent"
+ }
+ }
+}