diff --git a/architecture/build.gradle.kts b/architecture/build.gradle.kts index 429dbca..c500fce 100644 --- a/architecture/build.gradle.kts +++ b/architecture/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -20,6 +22,7 @@ repositories { dependencies { compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -110,3 +113,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 878fb99..e20f7a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.9.0" + kotlin("jvm") version "1.9.20" id("io.codearte.nexus-staging") version "0.30.0" } diff --git a/commands/build.gradle.kts b/commands/build.gradle.kts index 544771a..c0f05ae 100644 --- a/commands/build.gradle.kts +++ b/commands/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -22,6 +24,7 @@ dependencies { compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") compileOnly(project(":extensions")) implementation(kotlin("reflect")) + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -120,4 +123,12 @@ tasks.shadowJar { } } +} +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" } \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/Command.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/Command.kt index 19aa777..ef705ad 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/Command.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/Command.kt @@ -21,7 +21,7 @@ interface Command { * @author itzRedTea * @since 1.0.0 */ - fun execute(invoker: ExecutorContext) + fun execute(context: ExecutorContext) /** * Invokes when command must be executed * @param sender who executes this command @@ -34,10 +34,7 @@ interface Command { fun tabComplete(sender: CommandSender, args: Array): List - fun hasNotPermission(sender: CommandSender): Boolean = - context.permission != "" && (!sender.hasPermission(context.permission)).also { - if(it) MessagesService.byTag("#no-perm")(sender) - } - + fun hasNotPermission(sender: CommandSender): Boolean = context.permission != "" + && (!sender.hasPermission(context.permission)) } diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/DSLCommandArguments.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/DSLCommandArguments.kt index 524e302..9062bca 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/DSLCommandArguments.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/DSLCommandArguments.kt @@ -6,45 +6,39 @@ import org.bukkit.OfflinePlayer import org.bukkit.World import org.bukkit.entity.Player import tech.carcadex.kotlinbukkitkit.commands.exceptions.ArgumentNotFoundException -import tech.carcadex.kotlinbukkitkit.commands.exceptions.TypeParseException -import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException fun ExecutorContext.string(index: Int): String = argument(index) ?: throw ArgumentNotFoundException(index) fun ExecutorContext.stringOrNull(index: Int): String? = argument(index) fun ExecutorContext.integer(index: Int): Int = try { argument(index)?.toInt() } catch (e: NumberFormatException) { - MessagesService.byTag("#not-a-number")(sender) - throw TypeParseException() + throw CommandExecuteException("#not-a-number") } ?: throw ArgumentNotFoundException(index) fun ExecutorContext.integerOrNull(index: Int): Int? = argument(index)?.toIntOrNull() fun ExecutorContext.double(index: Int): Double = try { argument(index)?.toDouble() } catch (e: NumberFormatException) { - MessagesService.byTag("#not-a-number")(sender) - throw TypeParseException() + throw CommandExecuteException("#not-a-number") } ?: throw ArgumentNotFoundException(index) fun ExecutorContext.doubleOrNull(index: Int): Double? = argument(index)?.toDoubleOrNull() fun ExecutorContext.materialOrNull(index: Int): Material? = Material.matchMaterial(string(index)) fun ExecutorContext.material(index: Int): Material = materialOrNull(index) ?: run { - MessagesService.byTag("#no-such-material")(sender) - throw TypeParseException() + throw CommandExecuteException("#no-such-material") } fun ExecutorContext.worldOrNull(index: Int): World? = Bukkit.getWorld(argument(index) ?: "") fun ExecutorContext.world(index: Int): World = worldOrNull(index) ?: run { - MessagesService.byTag("#no-such-world")(sender) - throw TypeParseException() + throw CommandExecuteException("#no-such-world") } fun ExecutorContext.playerOrNull(index: Int): Player? = Bukkit.getPlayer(argument(index) ?: "") fun ExecutorContext.player(index: Int): Player = playerOrNull(index) ?: run { - MessagesService.byTag("#no-such-player")(sender) - throw TypeParseException() + throw CommandExecuteException("#no-such-player") } fun ExecutorContext.offlinePlayer(index: Int): OfflinePlayer = Bukkit.getOfflinePlayer(argument(index) ?: "") \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/ExecutorContext.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/ExecutorContext.kt index cf9648f..620df94 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/ExecutorContext.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/ExecutorContext.kt @@ -1,21 +1,13 @@ package tech.carcadex.kotlinbukkitkit.commands.dsl -import org.bukkit.Bukkit -import org.bukkit.Material -import org.bukkit.OfflinePlayer -import org.bukkit.World import org.bukkit.command.CommandSender import org.bukkit.entity.Player -import tech.carcadex.kotlinbukkitkit.commands.exceptions.ArgumentNotFoundException import tech.carcadex.kotlinbukkitkit.commands.exceptions.NotPlayerException -import tech.carcadex.kotlinbukkitkit.commands.exceptions.TypeParseException -import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService class ExecutorContext(val sender: CommandSender, val args: Array) { val player: Player get() { if (sender !is Player) { - MessagesService.byTag("#for-player-only")(sender) throw NotPlayerException() } return sender diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/builder/CommandBuilder.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/builder/CommandBuilder.kt index fbeb993..6ce2760 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/builder/CommandBuilder.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/builder/CommandBuilder.kt @@ -1,17 +1,24 @@ package tech.carcadex.kotlinbukkitkit.commands.dsl.builder +import org.bukkit.command.CommandSender import org.bukkit.plugin.Plugin import tech.carcadex.kotlinbukkitkit.commands.dsl.Command import tech.carcadex.kotlinbukkitkit.commands.dsl.CommandContext import tech.carcadex.kotlinbukkitkit.commands.dsl.ExecutorContext import tech.carcadex.kotlinbukkitkit.commands.dsl.leaf.CommandLeaf import tech.carcadex.kotlinbukkitkit.commands.dsl.node.CommandNodeImpl +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException import tech.carcadex.kotlinbukkitkit.commands.exceptions.LeafCommandHasNotExecutorException +import tech.carcadex.kotlinbukkitkit.commands.manager.CommandManagerInternal +import tech.carcadex.kotlinbukkitkit.commands.manager.commandManager +import tech.carcadex.kotlinbukkitkit.commands.manager.commandManagerInternal import tech.carcadex.kotlinbukkitkit.commands.register.CommandRegister +import tech.carcadex.kotlinbukkitkit.commands.service.TabCompleteService class CommandBuilder( val context: CommandContext, - var tabComplete: Collection = emptyList(), + val plugin: Plugin, + var tabComplete: List<(CommandSender) -> List> = emptyList(), val subs: MutableMap = mutableMapOf(), var executor: (ExecutorContext.() -> Unit)? = null ) { @@ -22,7 +29,7 @@ class CommandBuilder( } fun CommandBuilder.subCommand(name: String, permission: String, tabComplete: Collection, invoke: CommandBuilder.() -> Unit) { - subs[name.lowercase()] = createCommand(name, permission, tabComplete, invoke) + subs[name.lowercase()] = plugin.createCommand(name, permission, tabComplete, invoke) } fun CommandBuilder.executor(executor: ExecutorContext.() -> Unit) { @@ -30,38 +37,41 @@ fun CommandBuilder.executor(executor: ExecutorContext.() -> Unit) { } -private fun createCommand(name: String, permission: String, tabComplete: Collection, invoke: CommandBuilder.() -> Unit): Command { - val builder = CommandBuilder(CommandContext(name)) +private fun Plugin.createCommand(name: String, permission: String, tabComplete: Collection, invoke: CommandBuilder.() -> Unit): Command { + val builder = CommandBuilder(CommandContext(name), this) builder.permission = permission - builder.tabComplete = tabComplete + builder.tabComplete = commandManagerInternal().tabCompleteService.parseTags(tabComplete.toList()) builder.invoke() return createCommand(builder) } private fun createCommand(builder: CommandBuilder): Command { return if (builder.subs.isEmpty()) { if (builder.executor == null) throw LeafCommandHasNotExecutorException(builder.context.name) - CommandLeaf(builder.context, builder.executor!!, builder.tabComplete.toList()) + CommandLeaf(builder.context, builder.executor!!, (builder.tabComplete.toList())) } else { - CommandNodeImpl(builder.context, builder.subs) + CommandNodeImpl(builder.context, builder.subs, + if(builder.executor != null) CommandLeaf(builder.context, builder.executor!!, builder.tabComplete) else null) } } fun Plugin.simpleCommand(name: String, permission: String, tabComplete: Collection, executor: ExecutorContext.() -> Unit) { - val command = createCommand(CommandBuilder(CommandContext(name), - executor = executor).apply { - this.permission = permission - this.tabComplete = tabComplete - }) - CommandRegister.register(this, { sender, _, _, args -> command.execute(ExecutorContext(sender, args)); true }, - command.context.aliases, command.context.description, command.context.usage, { sender, _, _, args -> - command.tabComplete(sender, args) - } - ) + registerCommand(createCommand(CommandBuilder(CommandContext(name), + executor = executor, plugin = this).apply { + this.permission = permission + this.tabComplete = commandManagerInternal().tabCompleteService.parseTags(tabComplete.toList()) + })) } fun Plugin.command(name: String, permission: String, tabComplete: Collection, invoke: CommandBuilder.() -> Unit) { - val command = createCommand(name, permission, tabComplete, invoke) - CommandRegister.register(this, { sender, _, _, args -> command.execute(ExecutorContext(sender, args)); true }, + registerCommand(createCommand(name, permission, tabComplete, invoke)) +} + +private fun Plugin.registerCommand(command: Command) { + CommandRegister.register(this, { sender, _, _, args -> try { + command.execute(ExecutorContext(sender, args)) + } catch (e: CommandExecuteException) { + commandManager().readMessage(e.messageTag)(sender) + }; true }, command.context.aliases, command.context.description, command.context.usage, { sender, _, _, args -> command.tabComplete(sender, args) } diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/leaf/CommandLeaf.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/leaf/CommandLeaf.kt index aec02fb..fe328a6 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/leaf/CommandLeaf.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/leaf/CommandLeaf.kt @@ -5,21 +5,20 @@ import tech.carcadex.kotlinbukkitkit.commands.dsl.Command import tech.carcadex.kotlinbukkitkit.commands.dsl.CommandContext import tech.carcadex.kotlinbukkitkit.commands.dsl.ExecutorContext import tech.carcadex.kotlinbukkitkit.commands.exceptions.ArgumentNotFoundException -import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService -import tech.carcadex.kotlinbukkitkit.commands.service.TabCompleteService +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException class CommandLeaf( override val context: CommandContext, private val executor: (ExecutorContext.() -> Unit), - completeTags: List = emptyList() + private val completer: List<(CommandSender) -> List> ) : Command { - private val completer = TabCompleteService.parseTags(completeTags) override fun execute(context: ExecutorContext) { - if(hasNotPermission(context.sender)) return + if(hasNotPermission(context.sender)) + throw CommandExecuteException("#no-perm") try { executor(context) } catch (e: ArgumentNotFoundException) { - MessagesService.byTag("#wrong-usage")(context.sender) + throw CommandExecuteException("#wrong-usage") } } diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/node/CommandNodeImpl.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/node/CommandNodeImpl.kt index 9385cc7..0d13e87 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/node/CommandNodeImpl.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/dsl/node/CommandNodeImpl.kt @@ -5,13 +5,15 @@ import tech.carcadex.kotlinbukkitkit.commands.dsl.Command import tech.carcadex.kotlinbukkitkit.commands.dsl.CommandContext import tech.carcadex.kotlinbukkitkit.commands.dsl.CommandNode import tech.carcadex.kotlinbukkitkit.commands.dsl.ExecutorContext +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService class CommandNodeImpl( override val context: CommandContext, - private val subs: MutableMap = mutableMapOf() + private val subs: MutableMap = mutableMapOf(), + private val default: Command? = null ) : CommandNode { - private var default: Command? = null + override fun execute(context: ExecutorContext) { if(hasNotPermission(context.sender)) return if(context.args.isNotEmpty() && context.args[0].lowercase() in subs) subs[context.args[0].lowercase()]?.execute( @@ -19,7 +21,7 @@ class CommandNodeImpl( else { if(default != null) { default!!.execute(ExecutorContext(context.sender, context.args)) - } else MessagesService.byTag("#wrong-usage")(context.sender) + } else throw CommandExecuteException("#wrong-usage") } } diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/CommandExecuteException.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/CommandExecuteException.kt new file mode 100644 index 0000000..5a05bfa --- /dev/null +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/CommandExecuteException.kt @@ -0,0 +1,4 @@ +package tech.carcadex.kotlinbukkitkit.commands.exceptions + +open class CommandExecuteException(val messageTag: String) : RuntimeException() { +} \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/NotPlayerException.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/NotPlayerException.kt index 28d810b..9452b44 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/NotPlayerException.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/NotPlayerException.kt @@ -1,6 +1,4 @@ package tech.carcadex.kotlinbukkitkit.commands.exceptions -import java.lang.RuntimeException - -class NotPlayerException : RuntimeException() { +class NotPlayerException() : CommandExecuteException(messageTag = "#for-player-only") { } \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/TypeParseException.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/TypeParseException.kt deleted file mode 100644 index 81dbe83..0000000 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/exceptions/TypeParseException.kt +++ /dev/null @@ -1,4 +0,0 @@ -package tech.carcadex.kotlinbukkitkit.commands.exceptions - -class TypeParseException() : RuntimeException() { -} \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManager.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManager.kt index 8f159ec..91bf1fd 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManager.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManager.kt @@ -10,11 +10,18 @@ interface CommandManager { fun register(func: KFunction) fun tabComplete(tag: String, func: (CommandSender) -> List) fun message(tag: String, func: (CommandSender) -> Unit) + fun readMessage(tag: String): (CommandSender) -> Unit companion object { + private val registeredManagers = mutableMapOf() @JvmStatic - fun get(plugin: Plugin): CommandManager = CommandManagerImpl(plugin) + fun get(plugin: Plugin): CommandManager = + registeredManagers[plugin] ?: run { + registeredManagers[plugin] = CommandManagerInternal(plugin) + get(plugin) + } } } -fun Plugin.commandManager(): CommandManager = CommandManagerImpl(this) \ No newline at end of file +fun Plugin.commandManager(): CommandManager = CommandManager.get(this) +internal fun Plugin.commandManagerInternal(): CommandManagerInternal = CommandManager.get(this) as CommandManagerInternal \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerImpl.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerInternal.kt similarity index 75% rename from commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerImpl.kt rename to commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerInternal.kt index 5d1c26d..3bc10c9 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerImpl.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/manager/CommandManagerInternal.kt @@ -4,26 +4,26 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter import org.bukkit.plugin.Plugin -import tech.carcadex.kotlinbukkitkit.commands.exceptions.NotPlayerException import tech.carcadex.kotlinbukkitkit.commands.reflection.CommandParams import tech.carcadex.kotlinbukkitkit.commands.reflection.Parser import tech.carcadex.kotlinbukkitkit.commands.reflection.Parser.paramsFromAnnotations import tech.carcadex.kotlinbukkitkit.commands.reflection.annotations.Command -import tech.carcadex.kotlinbukkitkit.commands.exceptions.TypeParseException +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException import tech.carcadex.kotlinbukkitkit.commands.register.CommandRegister import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService import tech.carcadex.kotlinbukkitkit.commands.reflection.service.SubCommandsService import tech.carcadex.kotlinbukkitkit.commands.service.TabCompleteService import kotlin.reflect.KFunction import kotlin.reflect.full.createType +import kotlin.reflect.full.findAnnotations import kotlin.reflect.full.hasAnnotation import kotlin.reflect.full.isSubtypeOf import kotlin.reflect.jvm.javaType - - -class CommandManagerImpl(private val plugin: Plugin) : CommandManager { - +class CommandManagerInternal(private val plugin: Plugin) : CommandManager { + val messagesService = MessagesService() + val tabCompleteService = TabCompleteService() + private val subCommandsService = SubCommandsService(messagesService, tabCompleteService) private fun register( commandExecutor: CommandExecutor, commandParams: CommandParams, tabCompleter: TabCompleter = TabCompleter { _, _, _, _ -> mutableListOf() } @@ -39,10 +39,10 @@ class CommandManagerImpl(private val plugin: Plugin) : CommandManager { } override fun register(commandClass: Any) { - if(commandClass::class.objectInstance == null) { - throw IllegalArgumentException("commandClass is not a object!") + if((commandClass::class.findAnnotations(Command::class).isEmpty())) { + throw IllegalArgumentException("commandClass has not contains Command annotation!") } - val (name, subs) = SubCommandsService.registerRootCommand(commandClass) + val (name, subs) = subCommandsService.registerRootCommand(commandClass) val subsNames = mutableListOf() subs.forEach { subsNames.addAll(it.context.aliases) @@ -50,10 +50,10 @@ class CommandManagerImpl(private val plugin: Plugin) : CommandManager { val context = paramsFromAnnotations(commandClass::class) register(CommandExecutor { sender, _, _, args -> if (context.perm != null && !sender.hasPermission(context.perm)) { - MessagesService.byTag("#no-perm")(sender) + messagesService.byTag("#no-perm")(sender) return@CommandExecutor true } - SubCommandsService.handleCommand(name, sender, args); + subCommandsService.handleCommand(name, sender, args); true }, context, @@ -87,19 +87,19 @@ class CommandManagerImpl(private val plugin: Plugin) : CommandManager { register(CommandExecutor { sender, _, _, argsFromExecutor -> if (cmd.perm != null && !sender.hasPermission(cmd.perm)) { - MessagesService.byTag("#no-perm")(sender) + messagesService.byTag("#no-perm")(sender) return@CommandExecutor true } try { func.callBy( - Parser.paramMap(cmd, argsFromExecutor, argsSize, sender, argsParsers, func) - ) - } catch (ignored: TypeParseException) { - } catch (ignored: NotPlayerException) { + } catch (e: CommandExecuteException) { + messagesService.byTag(e.messageTag)(sender) } catch (e: IllegalArgumentException) { - MessagesService.byTag("#wrong-usage")(sender) + messagesService.byTag("#wrong-usage")(sender) + } catch (e: Throwable) { + messagesService.byTag("#unknown-error")(sender) } return@CommandExecutor true @@ -107,20 +107,21 @@ class CommandManagerImpl(private val plugin: Plugin) : CommandManager { }, cmd, cmd.completeTags.let { - TabCompleteService.completerReflection(it.toMutableList(), + tabCompleteService.completerReflection(it.toMutableList(), func.parameters.map { it.type.javaType as Class<*> }) } - ?: TabCompleter { _, _, _, _ -> mutableListOf() } ) } else throw IllegalArgumentException("It must be a command!") } override fun tabComplete(tag: String, func: (CommandSender) -> List) { - TabCompleteService.register(tag, func) + tabCompleteService.register(tag, func) } override fun message(tag: String, func: (CommandSender) -> Unit) { - MessagesService.register(tag, func) + messagesService.register(tag, func) } + + override fun readMessage(tag: String): (CommandSender) -> Unit = messagesService.byTag(tag) } \ No newline at end of file diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/Parser.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/Parser.kt index c860600..fbd4fa6 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/Parser.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/Parser.kt @@ -1,7 +1,7 @@ package tech.carcadex.kotlinbukkitkit.commands.reflection import org.bukkit.command.CommandSender -import tech.carcadex.kotlinbukkitkit.commands.exceptions.TypeParseException +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException import tech.carcadex.kotlinbukkitkit.commands.exceptions.UnsupportedTypeException import tech.carcadex.kotlinbukkitkit.commands.reflection.annotations.* import tech.carcadex.kotlinbukkitkit.commands.service.MessagesService @@ -59,19 +59,17 @@ object Parser { try { TypeService.byType(argType.type)(context) } catch (e: Throwable) { - if (context.errorMessage != null) MessagesService.byTag(context.errorMessage!!)(sender) - throw TypeParseException() + throw CommandExecuteException(context.errorMessage ?: "#empty") } } } else if (!clazz.isEnum) throw UnsupportedTypeException("Type ${argType.type.javaType.typeName} is not supported") else { - enums[argIndex] = { it, sender -> + enums[argIndex] = { it, _ -> var res: Enum<*>? = null; for (e in clazz.enumConstants) { if ((e as Enum<*>).name.equals(it, ignoreCase = true)) res = e; } - if (res == null) MessagesService.byTag("#no-such-enum")(sender) - res ?: throw TypeParseException() + res ?: throw CommandExecuteException("#no-such-enum") } argsParsers.add { _, _ -> {} } } @@ -102,8 +100,6 @@ object Parser { instanceAtStart: Boolean = false, instance: Any = Any() ): MutableMap { - val tempArgs = if (cmd.isLastOptional && argsFromExecutor.size < argsSize) argsFromExecutor.copyOf(argsSize) - else argsFromExecutor val finalArgs = mutableListOf() if(instanceAtStart) finalArgs.add(instance) @@ -113,7 +109,7 @@ object Parser { ) ) finalArgs.add(sender) - finalArgs.addAll(tempArgs.mapIndexed { i, it -> + finalArgs.addAll(argsFromExecutor.mapIndexed { i, it -> if (it == null) return@mapIndexed null argsParsers[i + 1](it, sender) }) diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/service/SubCommandsService.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/service/SubCommandsService.kt index da40c61..ed16793 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/service/SubCommandsService.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/reflection/service/SubCommandsService.kt @@ -9,12 +9,12 @@ import tech.carcadex.kotlinbukkitkit.commands.reflection.CommandParams import tech.carcadex.kotlinbukkitkit.commands.reflection.Parser import tech.carcadex.kotlinbukkitkit.commands.reflection.annotations.Command import tech.carcadex.kotlinbukkitkit.commands.reflection.annotations.Default -import tech.carcadex.kotlinbukkitkit.commands.exceptions.TypeParseException +import tech.carcadex.kotlinbukkitkit.commands.exceptions.CommandExecuteException import kotlin.reflect.KFunction import kotlin.reflect.full.* import kotlin.reflect.jvm.javaType -object SubCommandsService { +class SubCommandsService(private val messagesService: MessagesService, private val tabCompleteService: TabCompleteService) { data class SubCommand(val name: String, val context: CommandParams, val executor: (sender: CommandSender, args: Array) -> Boolean, val tabCompleter: TabCompleter) @@ -44,7 +44,7 @@ object SubCommandsService { if(args.isNotEmpty()) for(sub in subs[rootCommand.lowercase()]!!) { if(sub.name == args[0]) { if (sub.context.perm != null && sub.context.perm != "" && !sender.hasPermission(sub.context.perm)) { - MessagesService.byTag("#no-perm")(sender) + messagesService.byTag("#no-perm")(sender) return } sub.executor(sender, args.copyOfRange(1, args.size)) @@ -70,18 +70,18 @@ object SubCommandsService { } val executor: (sender: CommandSender, args: Array) -> Boolean = { sender, argsFromExecutor -> if (context.perm != null && !sender.hasPermission(context.perm)) { - MessagesService.byTag("#no-perm")(sender) + messagesService.byTag("#no-perm")(sender) true } else { try { func.callBy(Parser.paramMap(context, argsFromExecutor, argsSize, sender, argsParsers, func, true, rootCommand)) true - } catch (ignored: TypeParseException) { + } catch (ignored: CommandExecuteException) { false } catch (ignored: NotPlayerException) { false } catch (e: IllegalArgumentException) { - MessagesService.byTag("#wrong-usage")(sender) + messagesService.byTag("#wrong-usage")(sender) false } @@ -89,7 +89,7 @@ object SubCommandsService { } return SubCommand(name, context, executor, context.completeTags.let { - TabCompleteService.completerReflection(it.toMutableList(), + tabCompleteService.completerReflection(it.toMutableList(), func.parameters.map { it.type.javaType as Class<*> }) } ?: TabCompleter { _, _, _, _ -> mutableListOf() }) diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/MessagesService.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/MessagesService.kt index 845e5b7..fb390fe 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/MessagesService.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/MessagesService.kt @@ -3,7 +3,7 @@ package tech.carcadex.kotlinbukkitkit.commands.service import org.bukkit.ChatColor import org.bukkit.command.CommandSender -object MessagesService { +class MessagesService { private val messages = mutableMapOf Unit>() init { @@ -15,7 +15,9 @@ object MessagesService { messages["#no-such-enum"] = { it.sendMessage("${ChatColor.RED}No such value for this enum was found") } messages["#not-a-number"] = { it.sendMessage("${ChatColor.RED}It is not a number") } messages["#wrong-usage"] = { it.sendMessage("${ChatColor.RED}Wrong usage of command") } + messages["#unknown-error"] = { it.sendMessage("${ChatColor.RED}Something went wrong") } messages["#no-perm"] = { it.sendMessage("${ChatColor.RED}You have not permissions for this command!") } + messages["#empty"] = { } } fun register(tag: String, func: (CommandSender) -> Unit) { diff --git a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/TabCompleteService.kt b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/TabCompleteService.kt index df2206d..3873db0 100644 --- a/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/TabCompleteService.kt +++ b/commands/src/main/kotlin/tech/carcadex/kotlinbukkitkit/commands/service/TabCompleteService.kt @@ -3,9 +3,8 @@ package tech.carcadex.kotlinbukkitkit.commands.service import org.bukkit.Bukkit import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter -import kotlin.collections.ArrayList -object TabCompleteService { +class TabCompleteService { private val completes = mutableMapOf List>() init { //REGISTER DEFAULT COMPLETES diff --git a/exposed/build.gradle.kts b/exposed/build.gradle.kts index e8c007f..37c643f 100644 --- a/exposed/build.gradle.kts +++ b/exposed/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -29,6 +31,7 @@ dependencies { api(project(":extensions")) api(project(":utility")) compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -119,3 +122,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/extensions/build.gradle.kts b/extensions/build.gradle.kts index 206a499..ec6c575 100644 --- a/extensions/build.gradle.kts +++ b/extensions/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -21,6 +23,7 @@ repositories { dependencies { compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") api(project(":architecture")) + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -111,3 +114,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/genref/build.gradle.kts b/genref/build.gradle.kts index 9b3827e..4c447c1 100644 --- a/genref/build.gradle.kts +++ b/genref/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -24,6 +26,7 @@ dependencies { implementation("com.google.devtools.ksp:symbol-processing-api:1.9.0-1.0.11") implementation("com.squareup:kotlinpoet:1.10.1") implementation("com.squareup:kotlinpoet-ksp:1.10.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -114,3 +117,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/PluginVisitor.kt b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/PluginVisitor.kt index 6f9e995..2fd8930 100644 --- a/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/PluginVisitor.kt +++ b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/PluginVisitor.kt @@ -15,6 +15,8 @@ import com.squareup.kotlinpoet.ksp.writeTo import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.OnDisable import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.Plugin import tech.carcadex.kotlinbukkitkit.architecture.KotlinPlugin +import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.OnConfigReload +import tech.carcadex.kotlinbukkitkit.genref.plugin.annotations.OnLoad import java.nio.file.Path import java.nio.file.Paths import kotlin.io.path.deleteIfExists @@ -71,8 +73,9 @@ class PluginVisitor(private val codeGenerator: CodeGenerator, @OptIn(KspExperimental::class) override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) { if (function.getAnnotationsByType(OnDisable::class).any()) disable(function) - if(function.getAnnotationsByType(Plugin::class).any()) enable(function) + if(function.getAnnotationsByType(OnConfigReload::class).any()) configReload(function) + if(function.getAnnotationsByType(OnLoad::class).any()) load(function) } fun disable(function: KSFunctionDeclaration) { @@ -98,6 +101,29 @@ class PluginVisitor(private val codeGenerator: CodeGenerator, .build()) } + fun load(function: KSFunctionDeclaration) { + funcs.add(FunSpec.builder("onPluginLoad") + .addCode(CodeBlock.of(""" + plugin = this + ${function.simpleName.getShortName()}() + + """.trimIndent())) + .returns(Unit::class) + .addModifiers(KModifier.OVERRIDE) + .build()) + } + + fun configReload(function: KSFunctionDeclaration) { + funcs.add(FunSpec.builder("onConfigReload") + .addCode(CodeBlock.of(""" + plugin = this + ${function.simpleName.getShortName()}() + + """.trimIndent())) + .returns(Unit::class) + .addModifiers(KModifier.OVERRIDE) + .build()) + } } diff --git a/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnConfigReload.kt b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnConfigReload.kt new file mode 100644 index 0000000..7e802bd --- /dev/null +++ b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnConfigReload.kt @@ -0,0 +1,5 @@ +package tech.carcadex.kotlinbukkitkit.genref.plugin.annotations + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +annotation class OnConfigReload() diff --git a/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnLoad.kt b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnLoad.kt new file mode 100644 index 0000000..dc0a8ca --- /dev/null +++ b/genref/src/main/kotlin/tech/carcadex/kotlinbukkitkit/genref/plugin/annotations/OnLoad.kt @@ -0,0 +1,5 @@ +package tech.carcadex.kotlinbukkitkit.genref.plugin.annotations + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +annotation class OnLoad() diff --git a/gradle.properties b/gradle.properties index 3f3c255..4d8cbbe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,18 +1,18 @@ -version=1.0.0.4-SNAPSHOT +version=lastest -signing.gnupg.executable=C:/Program Files (x86)/GnuPG/bin/gpg.exe +signing.gnupg.executable=gpg.exe signing.gnupg.useLegacyGpg=false -signing.gnupg.keyName=0D0AC475D4E1770131FF571149B3C697DD0584C4 -signing.gnupg.passphrase=ere112 +signing.gnupg.keyName=secret +signing.gnupg.passphrase=secret -ossrhUsername=itzRedTea -ossrhPassword=Au~Ra~258+++ +ossrhUsername=secret +ossrhPassword=secret -nexusUsername=itzRedTea -nexusPassword=Au~Ra~258+++ -sonatype.stagingProfileId=iRedTea +nexusUsername=secret +nexusPassword=secret +sonatype.stagingProfileId=secret -password=Au~Ra~258+++ +password=secret kotlin.code.style=official diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aba097b..20cd5a1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists \ No newline at end of file diff --git a/menu/build.gradle.kts b/menu/build.gradle.kts index 649e5aa..8dc8322 100644 --- a/menu/build.gradle.kts +++ b/menu/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -25,6 +27,7 @@ dependencies { api(project(":extensions")) api(project(":utility")) compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -115,3 +118,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/messages/build.gradle.kts b/messages/build.gradle.kts index 188cf0d..6cb31cd 100644 --- a/messages/build.gradle.kts +++ b/messages/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -31,6 +33,7 @@ dependencies { implementation("net.kyori:adventure-api:4.14.0") implementation("net.kyori:adventure-platform-bukkit:4.3.0") implementation(files(parent!!.files("messages/libs/MiniMessages.jar"))) //using universal minimessages, + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -121,3 +124,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/serialization/build.gradle.kts b/serialization/build.gradle.kts index 9019bb6..bef1fc4 100644 --- a/serialization/build.gradle.kts +++ b/serialization/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -24,6 +26,7 @@ dependencies { api(project(":architecture")) api(project(":extensions")) compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -114,3 +117,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/src/main/kotlin/tech/carcadex/kotlinbukkitkit/KBKInfo.kt b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/KBKInfo.kt new file mode 100644 index 0000000..1670f12 --- /dev/null +++ b/src/main/kotlin/tech/carcadex/kotlinbukkitkit/KBKInfo.kt @@ -0,0 +1,5 @@ +package tech.carcadex.kotlinbukkitkit + +object KBKInfo { + const val KBK_VERSION = "1.0.0.3"; +} \ No newline at end of file diff --git a/thirdparty/build.gradle.kts b/thirdparty/build.gradle.kts index 80b71cd..247c411 100644 --- a/thirdparty/build.gradle.kts +++ b/thirdparty/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -24,6 +26,7 @@ dependencies { api(project(":architecture")) api(project(":utility")) compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -114,3 +117,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file diff --git a/utility/build.gradle.kts b/utility/build.gradle.kts index c47aef5..ec0c3b2 100644 --- a/utility/build.gradle.kts +++ b/utility/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("java") kotlin("jvm") @@ -24,6 +26,7 @@ dependencies { api(project(":architecture")) api(project(":extensions")) compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -114,3 +117,11 @@ signing { useGpgCmd() sign(publishing.publications.getByName("maven")) } +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} +val compileTestKotlin: KotlinCompile by tasks +compileTestKotlin.kotlinOptions { + jvmTarget = "1.8" +} \ No newline at end of file