From 420e0ec7ae2abe4679cf5768ea126ecbd98edf9d Mon Sep 17 00:00:00 2001 From: yukonisen Date: Sun, 28 Apr 2024 10:21:59 +0800 Subject: [PATCH 1/4] add clear cache command --- .../command/PotatoIpDisplayCommand.kt | 73 ++++++++++++++++--- .../potato_ip_display/util/UpdateUtil.kt | 6 +- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt index b5abcf5..11cdd03 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt @@ -24,16 +24,14 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } if (args.isEmpty()) { - sendMsg(sender, "§f版本 §b${plugin.description.version} §fby §b${plugin.description.authors.joinToString(", ")}", true) + var mode = plugin.conf.options.mode if (mode == "ip2region") { mode += " [${plugin.conf.options.xdbBuffer}]" } - val totalSize = IpAttributeMap.ip2regionRawDataMap.size + - IpAttributeMap.pconlineRawDataMap.size + - IpAttributeMap.ipApiRawDataMap.size - sendMsg(sender, "§f工作模式: §b$mode§f,总计 §b$totalSize §f条缓存项目", true) + + sendMsg(sender, "§f工作模式: §b$mode§f", true) sendMsg(sender, "§7尝试检查更新……", false) UpdateUtil.checkForUpdatesAsync { result -> sendMsg(sender, result, false) @@ -42,15 +40,28 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } when (args[0].lowercase()) { + "about" -> { + sendMsg(sender, "§f版本 §b${plugin.description.version} §fby §b${plugin.description.authors.joinToString(", ")}", true) + sendMsg(sender, "§6PotatoIPDisplay §f是§a免费§f的开源插件,详见:", false) + sendMsg(sender, "GitHub§f > §7\n https://github.com/dmzz-yyhyy/PotatoIpDisplay", false) + sendMsg(sender, "使用文档§f > §7\n https://upt.curiousers.org/docs/PotatoIpDisplay/intro", false) + return true + } "reload" -> { if (!sender.hasPermission("potatoipdisplay.reload")) { sendNoPerms(sender) return true } - plugin.reloadConfig() - plugin.conf = loadConfig(plugin.config) - plugin.initPlugin() - sendMsg(sender, "§a重载成功!", true) + plugin.log("PotatoIPDisplay (${plugin.description.version}) 正在尝试重载。若遇到插件问题,请重启服务器。") + runCatching { + plugin.reloadConfig() + plugin.conf = loadConfig(plugin.config) + plugin.initPlugin() + }.onFailure { + sendMsg(sender, "§c重载失败,请检查控制台输出信息", true) + }.onSuccess { + sendMsg(sender, "§a重载成功!", true) + } return true } "lookup" -> { @@ -80,6 +91,20 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } else sendMsg(sender, "§c查询的玩家离线,或 IPv4 无效", true) return true } + "clear" -> { + if (args.size < 2) { + val map = IpAttributeMap + val totalCacheSize = map.ip2regionRawDataMap.size + map.pconlineRawDataMap.size + map.ipApiRawDataMap.size + val playerCacheSize = map.playerIpAttributeMap.size + sendMsg(sender, "§e/$label clear player §f>> 清除玩家缓存 (当前 §b$playerCacheSize §f项)", false) + sendMsg(sender, "§e/$label clear cache §f>> 清除查询缓存 (当前 §b$totalCacheSize §f项)", false) + return true + } + + val clearedItems = clear(args[1].lowercase()) + sendMsg(sender, "§f清除完成,共清除了 §b$clearedItems §f项", true) + return true + } else -> { sendMsg(sender, "§c未知命令", true) return true @@ -90,11 +115,14 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { override fun onTabComplete(sender: CommandSender, command: Command, alias: String, args: Array): List { return when { !sender.hasPermission("potatoipdisplay.command") -> emptyList() - args.size == 1 -> listOf("lookup", "reload").filter { it.startsWith(args[0]) } + args.size == 1 -> listOf("lookup", "reload", "clear", "about").filter { it.startsWith(args[0]) } args.size == 2 && (args[0] == "lookup") -> { val matchingPlayers = plugin.server.onlinePlayers.map { it.name }.filter { it.startsWith(args[1]) } matchingPlayers + listOf("127.0.0.1") } + args.size == 2 && (args[0] == "clear") -> { + listOf("player", "cache") + } else -> emptyList() } } @@ -113,6 +141,31 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { return ip.matches(ipRegex) } + private fun clear(target: String): Int { + val map = IpAttributeMap + var clearedItems = 0 + + when (target) { + "player" -> { + clearedItems += map.playerIpAttributeMap.size + map.playerIpAttributeMap.clear() + } + "cache" -> { + clearedItems += map.ip2regionRawDataMap.size + clearedItems += map.pconlineRawDataMap.size + clearedItems += map.ipApiRawDataMap.size + map.ip2regionRawDataMap.clear() + map.pconlineRawDataMap.clear() + map.ipApiRawDataMap.clear() + } + else -> {} + } + return clearedItems + } + + + + private fun sendMsg(sender: CommandSender, msg: String, showPrefix: Boolean) { val prefix = if (showPrefix) "§7[§6PotatoIPDisplay§7] " else "" sender.sendMessage("$prefix$msg") diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt index d5be20e..aeb7da9 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt @@ -49,16 +49,16 @@ object UpdateUtil { val remote = response.body().trim().split("=")[1] when (compareVersions(local, remote)) { -1 -> onComplete("§b有可用的更新: $remote") /* local < remote */ - 0 -> onComplete("§a已是最新。") /* local = remote */ + 0 -> onComplete("§a已是最新") /* local = remote */ 1 -> onComplete("§a已是最新。远程: §f$remote") /* local > remote, NEWER than remote??? */ else -> onComplete("unknown error while comparing versions: $local vs $remote") } } else { - onComplete("§c无法获取当前远程版本。") + onComplete("§c无法获取当前远程版本") } return@Thread } catch (e: Exception) { - onComplete("§c无法从 GitHub 检查更新。") + onComplete("§c无法从 GitHub 检查更新") return@Thread } } From dda20aeeb0da27d90abfd7e7ffd9695366a16209 Mon Sep 17 00:00:00 2001 From: yukonisen Date: Sun, 28 Apr 2024 10:55:00 +0800 Subject: [PATCH 2/4] update README.md --- README.md | 14 ++++++++------ assets/chatdemo.png | Bin 6999 -> 0 bytes 2 files changed, 8 insertions(+), 6 deletions(-) delete mode 100644 assets/chatdemo.png diff --git a/README.md b/README.md index 35e97ba..09942d6 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,14 @@ ## 命令与权限 -| 命令 | 描述 | 权限 | -|:------------------------------------|:--------|:--------------------------| -| /pipd | 等效 | `potatoipdisplay.command` | -| /potatoipdisplay | 插件信息 | `potatoipdisplay.command` | -| /potatoipdisplay lookup <玩家\|IPv4 > | 查询玩家或IP | `potatoipdisplay.lookup` | -| /potatoipdisplay reload | 重载插件 | `potatoipdisplay.reload` | +| 命令 | 描述 | 权限 | 默认 | +|:--------------------------------------|:-----------------------|:--------------------------|:---| +| /pipd | 等效于 `/potatoipdisplay` | `potatoipdisplay.command` | OP | +| /potatoipdisplay | 插件信息 | `potatoipdisplay.command` | OP | +| /potatoipdisplay about | 显示关于信息 | `potatoipdisplay.command` | OP | +| /potatoipdisplay clear [player/cache] | 清除玩家/查询缓存 | `potatoipdisplay.command` | OP | +| /potatoipdisplay lookup [玩家/IPv4] | 查询玩家或IP | `potatoipdisplay.lookup` | OP | +| /potatoipdisplay reload | 重载插件 | `potatoipdisplay.reload` | OP | ## Placeholder API diff --git a/assets/chatdemo.png b/assets/chatdemo.png deleted file mode 100644 index 2d323ef443fdb94388d891f5cd2bc033b899ab97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6999 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 Date: Sun, 28 Apr 2024 11:00:00 +0800 Subject: [PATCH 3/4] fix plugin.yml --- bukkit/src/main/resources/plugin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index 1f67471..c40ac6d 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -19,6 +19,7 @@ permissions: children: - potatoipdisplay.reload - potatoipdisplay.lookup + - potatoipdisplay.command potatoipdisplay.command: description: "Run PotatoIPDisplay commands" default: op From 69ea2a77c223c1911c5bfdcce1476630c6b35f1f Mon Sep 17 00:00:00 2001 From: yukonisen Date: Tue, 30 Apr 2024 12:52:51 +0800 Subject: [PATCH 4/4] code improvements --- .../potato_ip_display/PotatoIpDisplay.kt | 48 +++++++++---------- .../command/PotatoIpDisplayCommand.kt | 48 +++++++++++++------ .../integration/PlaceholderIntergration.kt | 9 +--- .../listener/MessageListener.kt | 12 ++--- .../listener/PlayerJoinListener.kt | 9 +--- .../parser/IpParseFactory.kt | 6 +-- .../parser/provider/Ip2regionParser.kt | 13 ++--- .../parser/provider/IpApiParser.kt | 7 ++- .../parser/provider/PconlineParser.kt | 4 +- .../potato_ip_display/util/UpdateUtil.kt | 22 ++++----- 10 files changed, 88 insertions(+), 90 deletions(-) diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt index 6606402..e51d39b 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt @@ -15,6 +15,12 @@ import java.io.File import java.util.logging.Level class PotatoIpDisplay : JavaPlugin() { + + companion object Instance { + lateinit var instance: PotatoIpDisplay + val plugin by lazy { instance } + } + lateinit var conf: Config override fun onLoad() { @@ -24,13 +30,11 @@ class PotatoIpDisplay : JavaPlugin() { override fun onEnable() { super.onEnable() - + instance = this initPlugin() initResources() - if (conf.options.allowbStats) { - Metrics(this, 21473) - } + if (conf.options.allowbStats) Metrics(this, 21473) log("PotatoIpDisplay has been enabled. [mode: ${conf.options.mode}]") } @@ -42,20 +46,17 @@ class PotatoIpDisplay : JavaPlugin() { private fun initResources() { val configFile = File(dataFolder, "config.yml") val dbFile = File(dataFolder, "ip2region.xdb") - val authors = this.description.authors - if ("yukonisen" !in authors || "NightFish" !in authors) { - this.isEnabled = false - } - - if(!configFile.exists()) { - this.saveDefaultConfig() - } val isLite = false + val ip2regionDatabaseURL = + "https://raw.githubusercontent.com/lionsoul2014/ip2region/master/data/ip2region.xdb" + + if ("yukonisen" !in authors || "NightFish" !in authors) this.isEnabled = false + if (!configFile.exists()) this.saveDefaultConfig() + if (conf.options.mode == "ip2region" && !dbFile.exists()) { - if(isLite) { - UpdateUtil.downloadDatabase( - "https://raw.githubusercontent.com/lionsoul2014/ip2region/master/data/ip2region.xdb", dbFile.toPath()) + if (isLite) { + UpdateUtil.downloadDatabase(ip2regionDatabaseURL, dbFile.toPath()) // TODO: Download db files from internet for lite builds } else { /* For non-lite builds, ip2region.xdb included in jar */ saveResource("ip2region.xdb", false) @@ -69,26 +70,25 @@ class PotatoIpDisplay : JavaPlugin() { val pm = Bukkit.getPluginManager() conf = loadConfig(config) - PlaceholderIntergration(this).unregister() + PlaceholderIntergration().unregister() if (conf.papi.enabled) { if (pm.getPlugin("PlaceholderAPI") != null) { - PlaceholderIntergration(this).register() + PlaceholderIntergration().register() } else throw RuntimeException("PlaceholderAPI enabled in config but NOT installed!") } - /* Unregistering events" */ + /* Unregistering events */ HandlerList.unregisterAll() - /* Registering events" */ + /* Registering events */ if (conf.message.playerChat.enabled) - // NOTE: formerly "parseOnly", but now we determine if PIPD listens for messages depending on it - pm.registerEvents(MessageListener(this), this) + pm.registerEvents(MessageListener(), this) if (conf.message.playerLogin.enabled) - pm.registerEvents(PlayerJoinListener(this), this) + pm.registerEvents(PlayerJoinListener(), this) /* Registering commands */ - getCommand("potatoipdisplay")!!.setExecutor(PotatoIpDisplayCommand(this)) - getCommand("pipd")!!.setExecutor(PotatoIpDisplayCommand(this)) + getCommand("potatoipdisplay")!!.setExecutor(PotatoIpDisplayCommand()) + getCommand("pipd")!!.setExecutor(PotatoIpDisplayCommand()) } fun log(message: String, level: Level = Level.INFO) = diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt index 11cdd03..2a541e3 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/command/PotatoIpDisplayCommand.kt @@ -13,10 +13,15 @@ import org.bukkit.command.TabExecutor /** * The /potatoipdisplay command. */ -class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { - private val plugin: PotatoIpDisplay +class PotatoIpDisplayCommand : TabExecutor { + private val plugin = PotatoIpDisplay.plugin - override fun onCommand(sender: CommandSender, cmd: Command, label: String, args: Array): Boolean { + override fun onCommand( + sender: CommandSender, + cmd: Command, + label: String, + args: Array + ): Boolean { if (!sender.hasPermission("potatoipdisplay.command")) { sendNoPerms(sender) @@ -47,6 +52,7 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { sendMsg(sender, "使用文档§f > §7\n https://upt.curiousers.org/docs/PotatoIpDisplay/intro", false) return true } + "reload" -> { if (!sender.hasPermission("potatoipdisplay.reload")) { sendNoPerms(sender) @@ -64,6 +70,7 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } return true } + "lookup" -> { if (!sender.hasPermission("potatoipdisplay.lookup")) { sendNoPerms(sender) @@ -91,10 +98,12 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } else sendMsg(sender, "§c查询的玩家离线,或 IPv4 无效", true) return true } + "clear" -> { if (args.size < 2) { val map = IpAttributeMap - val totalCacheSize = map.ip2regionRawDataMap.size + map.pconlineRawDataMap.size + map.ipApiRawDataMap.size + val totalCacheSize = + map.ip2regionRawDataMap.size + map.pconlineRawDataMap.size + map.ipApiRawDataMap.size val playerCacheSize = map.playerIpAttributeMap.size sendMsg(sender, "§e/$label clear player §f>> 清除玩家缓存 (当前 §b$playerCacheSize §f项)", false) sendMsg(sender, "§e/$label clear cache §f>> 清除查询缓存 (当前 §b$totalCacheSize §f项)", false) @@ -105,6 +114,7 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { sendMsg(sender, "§f清除完成,共清除了 §b$clearedItems §f项", true) return true } + else -> { sendMsg(sender, "§c未知命令", true) return true @@ -112,24 +122,35 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } } - override fun onTabComplete(sender: CommandSender, command: Command, alias: String, args: Array): List { + override fun onTabComplete( + sender: CommandSender, + command: Command, + alias: String, + args: Array + ): List { return when { !sender.hasPermission("potatoipdisplay.command") -> emptyList() - args.size == 1 -> listOf("lookup", "reload", "clear", "about").filter { it.startsWith(args[0]) } + args.size == 1 -> listOf("lookup", "reload", "clear", "about").filter { + it.startsWith(args[0]) + } + args.size == 2 && (args[0] == "lookup") -> { - val matchingPlayers = plugin.server.onlinePlayers.map { it.name }.filter { it.startsWith(args[1]) } + val matchingPlayers = + plugin.server.onlinePlayers.map { it.name }.filter { it.startsWith(args[1]) } matchingPlayers + listOf("127.0.0.1") } + args.size == 2 && (args[0] == "clear") -> { listOf("player", "cache") } + else -> emptyList() } } private fun lookup(ip: String): String { val ipParse = IpParseFactory.getIpParse(ip) - return "§f - IP: §e$ip \n" + + return "§f - IP: §e$ip \n" + "§f - 国家: §e${ipParse.getCountry()} \n" + "§f - 省市: §e${ipParse.getProvince()} ${ipParse.getCity()} \n" + "§f - ISP: §e${ipParse.getISP()} \n" + @@ -137,7 +158,8 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { } private fun validate(ip: String): Boolean { - val ipRegex = """(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}""".toRegex() + val ipRegex = + """(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}""".toRegex() return ip.matches(ipRegex) } @@ -150,6 +172,7 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { clearedItems += map.playerIpAttributeMap.size map.playerIpAttributeMap.clear() } + "cache" -> { clearedItems += map.ip2regionRawDataMap.size clearedItems += map.pconlineRawDataMap.size @@ -158,14 +181,13 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { map.pconlineRawDataMap.clear() map.ipApiRawDataMap.clear() } + else -> {} } return clearedItems } - - private fun sendMsg(sender: CommandSender, msg: String, showPrefix: Boolean) { val prefix = if (showPrefix) "§7[§6PotatoIPDisplay§7] " else "" sender.sendMessage("$prefix$msg") @@ -175,8 +197,4 @@ class PotatoIpDisplayCommand(plugin: PotatoIpDisplay) : TabExecutor { sender.sendMessage("§c您没有使用此命令的权限") } - init { - this.plugin = plugin - } - } \ No newline at end of file diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/integration/PlaceholderIntergration.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/integration/PlaceholderIntergration.kt index 12e0c1d..f7ddc46 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/integration/PlaceholderIntergration.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/integration/PlaceholderIntergration.kt @@ -6,9 +6,8 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion import org.bukkit.entity.Player -class PlaceholderIntergration(plugin: PotatoIpDisplay) : PlaceholderExpansion() { - - private val plugin: PotatoIpDisplay +class PlaceholderIntergration : PlaceholderExpansion() { + private val plugin = PotatoIpDisplay.plugin override fun getAuthor(): String { return "[NightFish, yukonisen]" @@ -40,8 +39,4 @@ class PlaceholderIntergration(plugin: PotatoIpDisplay) : PlaceholderExpansion() } } - init { - this.plugin = plugin - } - } \ No newline at end of file diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/MessageListener.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/MessageListener.kt index f5512fb..bb4bbf6 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/MessageListener.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/MessageListener.kt @@ -8,16 +8,16 @@ import org.bukkit.event.Listener import org.bukkit.event.player.AsyncPlayerChatEvent -class MessageListener(plugin: PotatoIpDisplay) : Listener { - private val plugin: PotatoIpDisplay - private val conf = plugin.conf +class MessageListener : Listener { + private val plugin = PotatoIpDisplay.plugin + @EventHandler(priority = EventPriority.LOWEST) fun onPlayerChat(event: AsyncPlayerChatEvent) { val playerName = event.player.name val ipAttr = IpAttributeMap.playerIpAttributeMap[playerName] ?: "未知" - val chatmsg = (conf.message.playerChat.string + val chatmsg = (plugin.conf.message.playerChat.string .replace("%ipAttr%", ipAttr) .replace("%playerName%", "%1\$s") .replace("%msg%", "%2\$s")) @@ -25,8 +25,4 @@ class MessageListener(plugin: PotatoIpDisplay) : Listener { event.format = chatmsg } - init { - this.plugin = plugin - } - } \ No newline at end of file diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/PlayerJoinListener.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/PlayerJoinListener.kt index 9c114c6..24868c3 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/PlayerJoinListener.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/listener/PlayerJoinListener.kt @@ -10,8 +10,8 @@ import org.bukkit.event.player.PlayerLoginEvent import org.bukkit.scheduler.BukkitRunnable -class PlayerJoinListener(plugin: PotatoIpDisplay) : Listener { - private val plugin: PotatoIpDisplay +class PlayerJoinListener: Listener { + val plugin = PotatoIpDisplay.plugin private val conf = plugin.conf @EventHandler @@ -37,10 +37,5 @@ class PlayerJoinListener(plugin: PotatoIpDisplay) : Listener { .replace("%ipAttr%", ipAttr)) } } - - init { - this.plugin = plugin - } - } diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/IpParseFactory.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/IpParseFactory.kt index 0093b41..07f2215 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/IpParseFactory.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/IpParseFactory.kt @@ -4,14 +4,12 @@ import indi.nightfish.potato_ip_display.PotatoIpDisplay import indi.nightfish.potato_ip_display.parser.provider.Ip2regionParser import indi.nightfish.potato_ip_display.parser.provider.IpApiParser import indi.nightfish.potato_ip_display.parser.provider.PconlineParser -import org.bukkit.Bukkit object IpParseFactory { fun getIpParse(ip: String): IpParse{ - val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay - val conf = plugin.conf - return when (val mode = conf.options.mode) { + val plugin = PotatoIpDisplay.plugin + return when (val mode = plugin.conf.options.mode) { "pconline" -> PconlineParser(ip) "ip2region" -> Ip2regionParser(ip) "ip-api" -> IpApiParser(ip) diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/Ip2regionParser.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/Ip2regionParser.kt index 2b2b7d3..3fc419d 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/Ip2regionParser.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/Ip2regionParser.kt @@ -3,14 +3,13 @@ package indi.nightfish.potato_ip_display.parser.provider import indi.nightfish.potato_ip_display.PotatoIpDisplay import indi.nightfish.potato_ip_display.parser.IpParse import indi.nightfish.potato_ip_display.util.IpAttributeMap -import org.bukkit.Bukkit import org.lionsoul.ip2region.xdb.Searcher import java.io.File import java.util.concurrent.CompletableFuture class Ip2regionParser(private val ip: String) : IpParse { - private val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay + private val plugin = PotatoIpDisplay.plugin private val dataFolder get() = plugin.dataFolder private val dbPath = File(dataFolder, "ip2region.xdb").toPath().toString() private val unknown: String = "未知" @@ -19,10 +18,8 @@ class Ip2regionParser(private val ip: String) : IpParse { private val searcher by lazy { when (xdbBuffer) { "none" -> Searcher.newWithFileOnly(dbPath) - "vindex" -> Searcher.newWithVectorIndex(dbPath, - Searcher.loadVectorIndexFromFile(dbPath)) - "cbuff" -> Searcher.newWithBuffer( - Searcher.loadContentFromFile(dbPath)) + "vindex" -> Searcher.newWithVectorIndex(dbPath, Searcher.loadVectorIndexFromFile(dbPath)) + "cbuff" -> Searcher.newWithBuffer(Searcher.loadContentFromFile(dbPath)) else -> throw IllegalArgumentException("Invalid xdbBuffer in config >> $xdbBuffer") } } @@ -76,9 +73,7 @@ class Ip2regionParser(private val ip: String) : IpParse { private fun getIp2regionDataAsync(): String { val map = IpAttributeMap.ip2regionRawDataMap[ip] - if (map != null) { - return map - } + if (map != null) return map val future = CompletableFuture() val thread = Thread { diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/IpApiParser.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/IpApiParser.kt index 2573abb..ae7e5e5 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/IpApiParser.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/IpApiParser.kt @@ -13,7 +13,9 @@ import java.util.concurrent.CompletableFuture class IpApiParser(private val ip: String) : IpParse { private val get = getIpApiDataAsync() private val unknown: String = "未知" - private val isReservedRange: Boolean = (get["status"]?.asString == "fail") && (get["message"]?.asString == "reserved range") + private val isReservedRange: Boolean = + (get["status"]?.asString == "fail") && (get["message"]?.asString == "reserved range") + override fun getRegion(): String = get["regionName"]?.asString ?: unknown @@ -64,7 +66,8 @@ class IpApiParser(private val ip: String) : IpParse { IpAttributeMap.ipApiRawDataMap[ip] = jsonObject } } catch (_: Exception) { - val jsonObject: JsonObject = Gson().fromJson("{\"err\":\"failed\"}", JsonObject::class.java) + val jsonObject: JsonObject = + Gson().fromJson("{\"err\":\"failed\"}", JsonObject::class.java) future.complete(jsonObject) throw RuntimeException("Error while querying $ip. Common network problem.") } diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/PconlineParser.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/PconlineParser.kt index 154f34c..9e97c32 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/PconlineParser.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/parser/provider/PconlineParser.kt @@ -38,9 +38,7 @@ class PconlineParser(private val ip: String) : IpParse { override fun getFallback(): String { val values = arrayOf(getProvince(), getCountry(), getCity()) for (value in values) { - if (value.isNotBlank() && value != "") { - return value - } + if (value.isNotBlank() && value != "") return value } return unknown } diff --git a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt index aeb7da9..6779bc7 100644 --- a/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt +++ b/bukkit/src/main/kotlin/indi/nightfish/potato_ip_display/util/UpdateUtil.kt @@ -13,8 +13,7 @@ import kotlin.math.min object UpdateUtil { private val httpClient = HttpClient.newHttpClient() - private val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay - + private val plugin = PotatoIpDisplay.plugin fun downloadDatabase(url: String, path: Path) { plugin.log("Start download database file") @@ -28,11 +27,13 @@ object UpdateUtil { if (response.statusCode() != 200) { throw IOException("Download database file FAILED: ${response.statusCode()}") } - plugin.log("Successful downloaded to $path") } catch (e: Exception) { - plugin.log("Download Failed! Please manually download from [$url],\n" + - "then move it to the plugin directory! (plugins\\PotatoIpDisplay\\{FILE})", Level.WARNING) + plugin.log( + "Download Failed! Please manually download from [$url],\n" + + "then move it to the plugin directory! (plugins\\PotatoIpDisplay\\{FILE})", + Level.WARNING + ) /*e.printStackTrace()*/ Bukkit.getPluginManager().disablePlugin(plugin) } @@ -41,9 +42,11 @@ object UpdateUtil { fun checkForUpdatesAsync(onComplete: (String) -> Unit) { val local: String = plugin.description.version + val githubUpdateURL = + "https://raw.githubusercontent.com/dmzz-yyhyy/PotatoIpDisplay/master/PLUGIN_VERSION" val thread = Thread { try { - val request = HttpRequest.newBuilder(URI.create("https://raw.githubusercontent.com/dmzz-yyhyy/PotatoIpDisplay/master/PLUGIN_VERSION")).GET().build() + val request = HttpRequest.newBuilder(URI.create(githubUpdateURL)).GET().build() val response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()) if (response.statusCode() == 200) { val remote = response.body().trim().split("=")[1] @@ -53,9 +56,8 @@ object UpdateUtil { 1 -> onComplete("§a已是最新。远程: §f$remote") /* local > remote, NEWER than remote??? */ else -> onComplete("unknown error while comparing versions: $local vs $remote") } - } else { - onComplete("§c无法获取当前远程版本") - } + } else onComplete("§c无法获取当前远程版本") + return@Thread } catch (e: Exception) { onComplete("§c无法从 GitHub 检查更新") @@ -66,7 +68,6 @@ object UpdateUtil { } - /* p=version[P]lugin, r=version[R]emote */ private fun compareVersions(p: String, r: String): Int { val px = p.split(".") @@ -82,5 +83,4 @@ object UpdateUtil { } - } \ No newline at end of file