progress on diagnostic command

This commit is contained in:
alexcrea 2026-03-02 03:24:42 +01:00
parent a0654489bb
commit 6e981af017
Signed by: alexcrea
GPG key ID: E346CD16413450E3
6 changed files with 243 additions and 93 deletions

View file

@ -68,6 +68,8 @@ open class CustomAnvil : JavaPlugin() {
// Chat message listener // Chat message listener
lateinit var chatListener: ChatEventListener lateinit var chatListener: ChatEventListener
var latestVer: String? = null
/** /**
* Logging handler * Logging handler
*/ */
@ -195,10 +197,11 @@ open class CustomAnvil : JavaPlugin() {
ModrinthUpdateChecker(modrinthPluginID, loader, null) ModrinthUpdateChecker(modrinthPluginID, loader, null)
.setFeatured(featured) .setFeatured(featured)
.setOnError { logger.log(Level.WARNING, "error trying to fetch latest update", it) } .setOnError { logger.log(Level.WARNING, "error trying to fetch latest update", it) }
.checkVersion { latestver: String? -> .checkVersion { latestVer: String? ->
if(latestver == null || version.contains(latestver)) return@checkVersion CustomAnvil.latestVer = latestVer
if(latestVer == null || version.contains(latestVer)) return@checkVersion
logger.warning("An update may be available: $latestver") logger.warning("An update may be available: $latestVer")
} }
} }
@ -296,8 +299,6 @@ open class CustomAnvil : JavaPlugin() {
command = getCommand(commandConfigName) command = getCommand(commandConfigName)
command?.setExecutor(EditConfigExecutor()) command?.setExecutor(EditConfigExecutor())
println(getCommand("customanvil"))
println(getCommand("customanvila"))
CustomAnvilCmd(this) CustomAnvilCmd(this)
} }

View file

@ -33,8 +33,10 @@ abstract class CASubCommand: CommandExecutor {
return true return true
} }
open fun tabCompleter(list: MutableList<String>) { open fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>) {
} }
} }

View file

@ -17,14 +17,14 @@ class CustomAnvilCmd(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
} }
private val editConfigCommand = EditConfigExecutor() private val editConfigCommand = EditConfigExecutor()
private val commands: ImmutableMap<String, CASubCommand> private val commands = ImmutableMap.of(
"gui", editConfigCommand,
"reload", ReloadExecutor(),
"diagnostic", DiagnosticExecutor(),
//"debug", DebugExecutor(),
)
init { init {
commands = ImmutableMap.of<String, CASubCommand>(
"gui", editConfigCommand,
"reload", ReloadExecutor(),
"diagnostic", Diagnostic(),
)
println(plugin.getCommand(genericCommandName)) println(plugin.getCommand(genericCommandName))
val self = plugin.getCommand(genericCommandName)!! val self = plugin.getCommand(genericCommandName)!!
@ -61,13 +61,17 @@ class CustomAnvilCmd(plugin: CustomAnvil) : CommandExecutor, TabCompleter {
args: Array<out String> args: Array<out String>
): MutableList<String> { ): MutableList<String> {
val result = ArrayList<String>() val result = ArrayList<String>()
if(args.isEmpty()) { if(args.size < 3) {
for (cmd in commands) { for (cmd in commands) {
result.add(cmd.key) result.add(cmd.key)
} }
} else { } else {
val subcmd = commands[args[0].lowercase()] val subcmd = commands[args[1].lowercase()]
subcmd?.tabCompleter(result)
if(subcmd != null) {
val newArgs = args.copyOfRange(1, args.size)
subcmd.tabCompleter(sender, newArgs, result)
}
} }
//assumed all provided tab completed string are lowercase //assumed all provided tab completed string are lowercase

View file

@ -0,0 +1,25 @@
package xyz.alexcrea.cuanvil.command
import io.delilaheve.CustomAnvil
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import java.util.logging.Level
class DebugExecutor : CASubCommand() {
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>
): Boolean {
CustomAnvil.instance.logger.log(Level.SEVERE, "aaaaaaaaaaaaaaaaaaa");
return true
}
override fun tabCompleter(sender: CommandSender, args: Array<out String>, list: MutableList<String>) {
//TODO
}
}

View file

@ -1,77 +0,0 @@
package xyz.alexcrea.cuanvil.command
import io.delilaheve.CustomAnvil
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent
import net.md_5.bungee.api.chat.hover.content.Text
import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity
class Diagnostic: CASubCommand() {
companion object{
private const val NO_DIAG_PERM = "You do not have permission to diagnostic this server"
}
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>
): Boolean {
if (!allowed(sender)) {
sender.sendMessage(NO_DIAG_PERM)
return false
}
val stb = StringBuilder("```\n")
try {
diagnostic(stb)
} catch(e: Exception){
// TODO append error message to diag
TODO("error not handled yet $e")
}
stb.append("\n```")
if (sender is HumanEntity) {
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data")
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy"))
sender.spigot().sendMessage(message);
} else {
sender.sendMessage(stb.toString());
}
return true
}
override fun allowed(sender: CommandSender): Boolean {
return sender.hasPermission(CustomAnvil.diagnosticPermission)
}
fun diagnostic(stb: StringBuilder){
stb.append("Server Info\n");
stb.append("Plugin Version: ").append(CustomAnvil.instance.description.version).append("\n");
stb.append("Server Version: ").append(Bukkit.getVersion()).append(" (").append(Bukkit.getName()).append(')').append("\n");
stb.append("Plugin Enabled: ").append(if(CustomAnvil.instance.isEnabled) "Yes" else "No").append("\n");
//stb.append("NMS type: ").append(NMSMapper.hasNMS() ? "Yes" : "No").append("\n");
stb.append("Java Version: ").append(System.getProperty("java.version")).append("\n");
stb.append("OS: ").append(System.getProperty("os.name")).append(" ")
.append(System.getProperty("os.version"))
.append(System.getProperty("os.arch"))
.append("\n\n");
stb.append("Architecture: ").append(System.getProperty("os.arch")).append("\n\n");
}
}

View file

@ -0,0 +1,195 @@
package xyz.alexcrea.cuanvil.command
import io.delilaheve.CustomAnvil
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent
import net.md_5.bungee.api.chat.hover.content.Text
import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.packet.NoPacketManager
import xyz.alexcrea.cuanvil.dependency.packet.ProtocoLibWrapper
import xyz.alexcrea.cuanvil.dependency.packet.versions.PaperPacketManager
import java.util.*
import java.util.stream.Collectors
class DiagnosticExecutor: CASubCommand() {
companion object{
private const val NO_DIAG_PERM = "You do not have permission to diagnostic this server"
}
enum class DiagParams(val value: String) {
OS_PRIVACY("os_privacy"),
PLUGIN_PRIVACY("plugin_privacy"),
//NO_TEST("no_anvil_test"),
}
private fun fetchParameters(args: Array<out String>): EnumSet<DiagParams> {
val result = EnumSet.noneOf(DiagParams::class.java)
val argSet = HashSet<String>()
for (string in args) {
argSet.add(string.lowercase())
}
for (param in DiagParams.entries) {
if(argSet.contains(param.value))
result.add(param)
}
return result
}
override fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>) {
if(!allowed(sender)) return
val map = fetchParameters(args)
for (param in DiagParams.entries) {
if(!map.contains(param))
list.add(param.value)
}
}
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>
): Boolean {
if (!allowed(sender)) {
sender.sendMessage(NO_DIAG_PERM)
return false
}
val stb = StringBuilder("```\n")
val params = fetchParameters(args)
try {
diagnostic(stb, params)
} catch(e: Exception){
stb.append("\n\nError happened trying to get diagnostic data:\n")
.append(e.message).append("\n")
.append(e.stackTrace.joinToString("\n"))
}
stb.append("\n```")
if (sender is HumanEntity) {
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data")
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
message.hoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, Text("§7Click to copy"))
sender.spigot().sendMessage(message);
} else {
sender.sendMessage(stb.toString());
}
return true
}
override fun allowed(sender: CommandSender): Boolean {
return sender.hasPermission(CustomAnvil.diagnosticPermission)
}
fun diagnostic(stb: StringBuilder, params: Set<DiagParams>){
stb.append("Server Info\n")
stb.append("Plugin Version: ").append(CustomAnvil.instance.description.version).append("\n")
stb.append("Latest Update: ").append(CustomAnvil.latestVer).append('\n')
stb.append("Server Version: ").append(Bukkit.getVersion()).append(" (").append(Bukkit.getName()).append(')').append("\n")
stb.append("Plugin Enabled: ").append(if(CustomAnvil.instance.isEnabled) "Yes" else "No").append("\n")
stb.append("NMS type: ").append(fetchNMSType())
if(!params.contains(DiagParams.OS_PRIVACY)) {
stb.append("Java Version: ").append(System.getProperty("java.version")).append("\n")
stb.append("OS: ").append(System.getProperty("os.name")).append(" ")
.append(System.getProperty("os.version"))
.append(System.getProperty("os.arch"))
.append("\n\n")
}
if(!params.contains(DiagParams.PLUGIN_PRIVACY)) {
pluginListDiag(stb)
}
prepareAnvilListeners(stb)
stb.append("\n\n")
}
private fun fetchNMSType(): String {
val packetManager = DependencyManager.packetManager
val packetManagerClass = packetManager.javaClass
val result: String
if(packetManagerClass == PaperPacketManager::class.java) {
result = "Paper NMS"
} else if(packetManagerClass == ProtocoLibWrapper::class.java) {
result = "Protocolib"
} else if(packetManagerClass == NoPacketManager::class.java) {
result = "None"
} else {
result = "Version Specific"
}
return "$result ${if(packetManager.canSetInstantBuild) '✅' else '❌'}"
}
private val Plugin.pluginNameDisplay: String
get() {
return this.name + " v" + this.description.version
}
private fun pluginListDiag(stb: StringBuilder) {
val enabledPlugins: MutableList<Plugin?> = ArrayList<Plugin?>()
val disabledPlugins: MutableList<Plugin?> = ArrayList<Plugin?>()
for (plugin in Bukkit.getPluginManager().plugins) {
if (plugin.isEnabled) {
enabledPlugins.add(plugin)
} else {
disabledPlugins.add(plugin)
}
}
stb.append("Enabled Plugins: ").append(
enabledPlugins.stream()
.map { plugin -> plugin!!.pluginNameDisplay }
.reduce { a: String?, b: String? -> "$a, $b" }.orElse("None")
).append("\n")
stb.append("Disabled Plugins: ").append(
disabledPlugins.stream()
.map { plugin -> plugin!!.pluginNameDisplay }
.reduce { a: String?, b: String? -> "$a, $b" }.orElse("None")
).append("\n")
}
fun prepareAnvilListeners(stb: StringBuilder) {
val eventListeners: MutableSet<Plugin?> = Arrays
.stream(
PrepareAnvilEvent
.getHandlerList()
.getRegisteredListeners()
)
.map { obj: RegisteredListener? -> obj!!.plugin }
.collect(Collectors.toSet())
eventListeners.remove(CustomAnvil.instance)
stb.append("Prepare Anvil Listeners: ").append(
if (eventListeners.isEmpty()) "None" else eventListeners.stream()
.map { plugin -> plugin!!.pluginNameDisplay }
.reduce { a: String?, b: String? -> "$a, $b" }.orElse("None")
).append("\n\n")
}
}