Skip to content

Commit

Permalink
Merge pull request #21 from Matt-MX/dev
Browse files Browse the repository at this point in the history
merge dev
  • Loading branch information
Matt-MX authored May 14, 2024
2 parents bc3a3c2 + 45c9968 commit fdc34fc
Show file tree
Hide file tree
Showing 85 changed files with 2,214 additions and 574 deletions.
3 changes: 2 additions & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ repositories {
}

dependencies {
compileOnly(kotlin("reflect"))
// compileOnly(kotlin("reflect"))
implementation(kotlin("reflect"))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10")
}

Expand Down
93 changes: 70 additions & 23 deletions api/src/main/kotlin/com/mattmx/ktgui/GuiManager.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.mattmx.ktgui

import com.mattmx.ktgui.commands.wrapper.CommandWrapper
import com.mattmx.ktgui.components.screen.IGuiScreen
import com.mattmx.ktgui.configuration.Configuration
import com.mattmx.ktgui.cooldown.ActionCoolDown
import com.mattmx.ktgui.dsl.event
import com.mattmx.ktgui.extensions.getOpenGui
import com.mattmx.ktgui.guiconfig.GuiConfigManager
import com.mattmx.ktgui.scheduling.Scheduling
import com.mattmx.ktgui.scheduling.TaskTracker
import com.mattmx.ktgui.scheduling.TaskTrackerTask
import com.mattmx.ktgui.utils.InstancePackageClassCache
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandMap
import org.bukkit.command.SimpleCommandMap
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
Expand All @@ -17,8 +22,7 @@ import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.event.server.PluginDisableEvent
import org.bukkit.plugin.java.JavaPlugin
import org.jetbrains.annotations.ApiStatus
import java.util.Collections
import java.util.*

/**
* Handles all GUI click events, as well
Expand All @@ -27,12 +31,15 @@ import java.util.Collections
object GuiManager : Listener {
private val players = Collections.synchronizedMap(hashMapOf<Player, IGuiScreen>())
private var initialized = false
private val defaultConfiguration = Configuration()
private val configurations = hashMapOf<JavaPlugin, Configuration>()
private val pluginCache = InstancePackageClassCache<JavaPlugin>()
val guiConfigManager = GuiConfigManager()
lateinit var owningPlugin: JavaPlugin

fun init(plugin: JavaPlugin): Boolean {
if (initialized) return false
if (initialized) {
pluginCache.cacheInstance(plugin::class.java, plugin)
return false
}
initialized = true
owningPlugin = plugin
Scheduling.plugin = plugin
Expand All @@ -48,22 +55,60 @@ object GuiManager : Listener {
Bukkit.getOnlinePlayers().forEach { player -> forceClose(player) }
}

/**
* Each plugin can configure generic things like feedback messages,
* that KTBukkitGui handles under the hud.
*
* @param plugin the plugin for this configuration
* @param block configuration modification
*/
@ApiStatus.Experimental
fun configure(plugin: JavaPlugin, block: Configuration.() -> Unit) {
val configuration = Configuration()
block(configuration)
configurations[plugin] = configuration
}
fun registerCommand(classOrPlugin: Class<*>, command: CommandWrapper) {
val existingCommand = Bukkit.getPluginCommand(command.name)
if (existingCommand != null) {
Bukkit.getPluginCommand(command.name)?.setExecutor(command)
} else {
if(!isInitialized()) {
throw RuntimeException("Unregistered commands are unsupported when GuiManager not initialised! Call GuiManager.init")
}

var cmdPlugin = pluginCache.getInstanceOrNull(classOrPlugin)

val prefix = if (cmdPlugin == null) {
cmdPlugin = owningPlugin

cmdPlugin.logger.warning("Unable to find owning plugin for class ${classOrPlugin.simpleName} when registering command '${command.name}'.")
cmdPlugin.name.lowercase()
} else cmdPlugin.name.lowercase()

@ApiStatus.Experimental
fun getConfiguration(plugin: JavaPlugin) = configurations[plugin] ?: defaultConfiguration
val cmdMapField = Bukkit.getServer().javaClass.getDeclaredField("commandMap")
cmdMapField.isAccessible = true

val cmdMap = cmdMapField.get(Bukkit.getServer()) as CommandMap
cmdMap.register(prefix, command)

val knownCommandsField = SimpleCommandMap::class.java.getDeclaredField("knownCommands")
knownCommandsField.isAccessible = true

val knownCommands = knownCommandsField.get(cmdMap) as MutableMap<String?, Command?>
var knownAliases: Set<String?>? = null

try {
val aliasesField = SimpleCommandMap::class.java.getDeclaredField("aliases")
aliasesField.setAccessible(true)
knownAliases = aliasesField.get(cmdMap) as MutableSet<String?>
} catch (e: NoSuchFieldException) {}

event<PluginDisableEvent>(cmdPlugin) {
if (this.plugin == cmdPlugin) {
synchronized(cmdMap) {
knownCommands.remove(command.name)
knownCommands.remove("$prefix:${command.name}")
knownAliases?.minus(command.aliases.toSet())
for (alias in command.aliases) {
knownCommands.remove(alias)
knownCommands.remove("$prefix:$alias")
}
command.unregister(cmdMap)
command.aliases = listOf()
}
cmdPlugin.logger.info("Unregistered ${command.name}")
}
}
}
}

fun getPlayers(gui: IGuiScreen) = players.filter { it.value == gui }.keys
fun getPlayersInGui() = players.toMutableMap()
Expand Down Expand Up @@ -112,6 +157,8 @@ object GuiManager : Listener {
}
players.remove(e.player)
}

ActionCoolDown.removeUsers(e.player, e.player.uniqueId, e.player.name)
}

@EventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player

class DummyCommand(
open class DummyCommand(
val cmd: SimpleCommandBuilder
) : Command(cmd.name, cmd.description ?: "", "null", cmd.aliases.toList()) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,71 +1,30 @@
package com.mattmx.ktgui.commands

import com.mattmx.ktgui.scheduling.not
import com.mattmx.ktgui.utils.not
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter
import org.bukkit.entity.Player

class DummyCommandExecutor(
val cmd: SimpleCommandBuilder
) : CommandExecutor, TabCompleter {
// private val cooldowns = hashMapOf<String, Date>()
cmd: SimpleCommandBuilder
) : DummyCommand(cmd), CommandExecutor, TabCompleter {

override fun onCommand(
sender: CommandSender,
command: Command,
commandLabel: String,
args: Array<out String>
): Boolean {
val current = if (args.isEmpty()) ""
else args[if (args.size - 1 > 0) args.size - 1 else 0]

cmd.getCommand(args.toMutableList())?.also {
if (sender !is Player && it.playerOnly) {
sender.sendMessage(!"&cPlayer only command.")
return false
}
if (it.hasPermission(sender)) {
// Check for cooldown restrictions
// if (cooldowns.containsKey(sender.name) && cooldowns[sender.name]!!.after(Date())) {
// it.cooldownCallback(CommandInvocation(sender, args.toList(), current, commandLabel, cooldowns[sender.name]))
// return@also
// }

it.executeFor(sender, args.toList(), current, commandLabel)

// if (it.cooldown != null) {
// val now = Date().time
// val cooldownExpire = now + it.cooldown!!.toMillis()
//
// cooldowns[sender.name] = Date(cooldownExpire)
// }
} else {
cmd.noPermissions?.let { it1 -> it1(CommandInvocation(sender, args.toList(), current, commandLabel)) }
sender.sendMessage(!"&cYou do not have permissions to execute this command.")
}
} ?: run {
cmd.unknown(sender, args.toList(), current, commandLabel)
}
return false
return execute(sender, commandLabel, args)
}

override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: Array<out String>
): MutableList<String>? {
val current = if (args.isEmpty()) ""
else args[if (args.size - 1 > 0) args.size - 1 else 0]
var argss = args.toMutableList()
argss = if (argss.size - 1 < 0) mutableListOf("") else argss.subList(0, argss.size - 1)
cmd.getCommand(argss)?.let {
return it.getSuggestions(CommandInvocation(sender, args.toList(), current, alias)).toMutableList()
}
return mutableListOf()
): MutableList<String> {
return tabComplete(sender, alias, args)
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mattmx.ktgui.commands

import com.mattmx.ktgui.GuiManager
import com.mattmx.ktgui.cooldown.ActionCoolDown
import com.mattmx.ktgui.dsl.event
import org.bukkit.Bukkit
import org.bukkit.command.Command
Expand All @@ -23,12 +24,11 @@ open class SimpleCommandBuilder(
val subCommands = arrayListOf<SimpleCommandBuilder>()
var suggestSubCommands = false
var playerOnly = false
var cooldown: Duration? = null
var cooldownMessage: String? = null
private var cooldownCallback: (CommandInvocation.() -> Unit)? = null
private var suggests: (CommandInvocation.() -> List<String>?)? = null
private var execute: (CommandInvocation.() -> Unit)? = null
private var unknown: (CommandInvocation.() -> Unit)? = null
private var cooldown: Optional<ActionCoolDown<CommandSender>> = Optional.empty()
private var cooldownCallback: (CommandInvocation.() -> Unit)? = null
var noPermissions: (CommandInvocation.() -> Unit)? = null
private set

Expand Down Expand Up @@ -65,6 +65,13 @@ open class SimpleCommandBuilder(
return this
}

fun cooldown(duration: Duration?) = apply {
cooldown.ifPresent {
ActionCoolDown.unregister(it)
}
cooldown = Optional.ofNullable(duration?.let { ActionCoolDown(duration) })
}

fun cooldownCallback(invocation: CommandInvocation) {
this.cooldownCallback?.invoke(invocation)
}
Expand All @@ -74,6 +81,10 @@ open class SimpleCommandBuilder(
return this
}

fun runs(block: CommandInvocation.() -> Unit) = apply {
this.execute = block
}

fun unknownSubcommand(unknown: CommandInvocation.() -> Unit) : SimpleCommandBuilder {
this.unknown = unknown
return this
Expand All @@ -87,7 +98,11 @@ open class SimpleCommandBuilder(
execute?.let { it(CommandInvocation(executor, args, lastArg, alias)) }
}

fun suggests(suggest: (CommandInvocation) -> List<String>?) {
infix fun suggests(suggest: (CommandInvocation) -> List<String>?) = apply {
this.suggests = suggest
}

infix fun suggestion(suggest: CommandInvocation.() -> List<String>?) = apply {
this.suggests = suggest
}

Expand Down Expand Up @@ -115,7 +130,7 @@ open class SimpleCommandBuilder(
return this
}

fun register(isInConfig: Boolean = false) {
infix fun register(isInConfig: Boolean) {
if (isInConfig) {
Bukkit.getPluginCommand(name)?.setExecutor(DummyCommandExecutor(this))
} else {
Expand All @@ -128,7 +143,7 @@ open class SimpleCommandBuilder(
val dummyCmd = DummyCommand(this)
cmdMap.register(GuiManager.owningPlugin.description.name.lowercase(), dummyCmd)
val knownCommandsField = SimpleCommandMap::class.java.getDeclaredField("knownCommands")
knownCommandsField.setAccessible(true)
knownCommandsField.isAccessible = true
val knownCommands = knownCommandsField.get(cmdMap) as MutableMap<String?, Command?>
var knownAliases: Set<String?>? = null
try {
Expand Down Expand Up @@ -184,6 +199,9 @@ class CommandInvocation(
val alias: String,
val coolDownExpires: Date? = null
) {
val player: Player
get() = source as Player

fun player() : Player {
return source as Player
}
Expand All @@ -197,8 +215,12 @@ class CommandInvocation(
fun isEmpty() : Boolean = args.isEmpty()
}

@Deprecated("No longer considered a 'simple command'", ReplaceWith("rawCommand"))
inline fun simpleCommand(cmd: (SimpleCommandBuilder.() -> Unit)) : SimpleCommandBuilder {
val cmdB = SimpleCommandBuilder()
cmd(cmdB)
return cmdB
}

inline fun rawCommand(name: String, vararg alias: String, block: SimpleCommandBuilder.() -> Unit) =
SimpleCommandBuilder(name, *alias).apply(block)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mattmx.ktgui.commands.declarative
package com.mattmx.ktgui.commands.alpha

/**
* Argument class
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mattmx.ktgui.commands.declarative
package com.mattmx.ktgui.commands.alpha

enum class ArgumentType {
REQUIRED_SINGLE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mattmx.ktgui.commands.declarative
package com.mattmx.ktgui.commands.alpha

import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.mattmx.ktgui.commands.alpha

class CommandSender
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.mattmx.ktgui.commands.declarative
package com.mattmx.ktgui.commands.alpha

import com.mattmx.ktgui.configuration.Configuration
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

Expand Down Expand Up @@ -66,6 +65,8 @@ open class KtCommandBuilder<S : CommandSender>(val name: String) {
): ReadOnlyProperty<T, V> {
id = property.name

println("invoked eooeeo")

return ReadOnlyProperty { thisRef, property -> context.getValue(this) as V }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mattmx.ktgui.commands.declarative
package com.mattmx.ktgui.commands.alpha

import kotlin.concurrent.thread

Expand Down
Loading

0 comments on commit fdc34fc

Please sign in to comment.