diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ce1c62c..7c75940 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -5,11 +5,13 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index f3bbe36..3b6a3bf 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 8f234a4..1eb3db2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,10 +2,11 @@ plugins { kotlin("jvm") version "1.9.22" id("idea") id ("com.github.johnrengelman.shadow") version "8.1.1" + id("xyz.jpenilla.run-paper") version "2.2.2" } group = "indi.nightfish.potato_ip_display" -version = "1.1-bukkit" +version = "1.2-bukkit" repositories { mavenCentral() @@ -23,9 +24,14 @@ dependencies { implementation("com.google.code.gson:gson:2.10.1") compileOnly("org.spigotmc:spigot-api:1.20.4-R0.1-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.4") + implementation("org.lionsoul:ip2region:2.7.0") } -tasks.test { - useJUnitPlatform() -} - +tasks { + runServer { + // Configure the Minecraft version for our task. + // This is the only required configuration besides applying the plugin. + // Your plugin's jar (or shadowJar if present) will be used automatically. + minecraftVersion("1.20.4") + } +} \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/MessageListener.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/MessageListener.kt index 4e371b5..8b7f95a 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/MessageListener.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/MessageListener.kt @@ -2,26 +2,28 @@ package indi.nightfish.potato_ip_display import me.clip.placeholderapi.PlaceholderAPI import org.bukkit.Bukkit -import org.bukkit.ChatColor import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.player.AsyncPlayerChatEvent -class MessageListener: Listener{ - @EventHandler(priority = EventPriority.LOWEST) - fun onPlayerChat(event: AsyncPlayerChatEvent) { - val parseOnly = PotatoPlugin.fileConfig.getBoolean("parseOnly", true) - if (!parseOnly) { - val player = event.player - val playerName = player.name - var msg = event.message - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { - msg = PlaceholderAPI.setPlaceholders(event.player, msg); - } - Bukkit.getServer().broadcastMessage("${ChatColor.GRAY}[${ChatColor.AQUA}${IpATTRMap.playerIpATTRMap[playerName]}${ChatColor.GRAY}] ${ChatColor.RESET}$playerName ${ChatColor.GRAY}>> ${ChatColor.RESET}$msg") - event.isCancelled = true - } +class MessageListener : Listener { + private val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay + private val conf = plugin.conf + @EventHandler(priority = EventPriority.LOWEST) + fun onPlayerChat(event: AsyncPlayerChatEvent) { + val playerName = event.player.name + var msg = event.message + val ipAttr = IpATTRMap.playerIpATTRMap[playerName] ?: "未知" + + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + msg = PlaceholderAPI.setPlaceholders(event.player, msg); } + Bukkit.getServer().broadcastMessage(conf.message.playerChat.string + .replace("%ipAttr%", ipAttr) + .replace("%playerName%", playerName) + .replace("%msg%", msg)) + event.isCancelled = true + } } \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/PIPDConfig.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/PIPDConfig.kt new file mode 100644 index 0000000..fd9bf41 --- /dev/null +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/PIPDConfig.kt @@ -0,0 +1,64 @@ +package indi.nightfish.potato_ip_display + +import org.bukkit.configuration.file.FileConfiguration + +data class PIPDConfig( + val configVersion: Int, + val options: Options, + val message: Message, + val papi: PAPISupport, +) { + data class Options( + val mode: String + ) + + data class Message( + val playerChat: PlayerChat, + val playerLogin: PlayerLogin + ) { + data class PlayerChat( + val enabled: Boolean, + val string: String + ) + + data class PlayerLogin( + val enabled: Boolean, + val string: String + ) + } + + data class PAPISupport( + val enabled: Boolean, + val format: String + ) +} + +fun loadPIPDConfig(fc: FileConfiguration): PIPDConfig { + return PIPDConfig( + fc.getInt("config-version"), + + PIPDConfig.Options( + fc.getString("options.mode") + ?: "ip2region" + ), + + PIPDConfig.Message( + PIPDConfig.Message.PlayerChat( + fc.getBoolean("messages.player-chat.enabled"), + fc.getString("messages.player-chat.string") + ?: "§7[§b\$ipAttr§7] §f\$playerName §7>> §f\$msg" // FALLBACK CHAT FORMAT + ), + PIPDConfig.Message.PlayerLogin( + fc.getBoolean("messages.player-login.enabled"), + fc.getString("messages.player-login.string") + ?: "§7[§6PotatoIpDisplay§7] §e您当前ip归属地 §7[§b\$ipAttr§7]" + ) + ), + + PIPDConfig.PAPISupport( + fc.getBoolean("papi.enabled"), + fc.getString("papi.format") ?: "" + + ) + ) +} diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/PlayerJoinListener.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/PlayerJoinListener.kt index 9f83eda..9e9b67c 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/PlayerJoinListener.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/PlayerJoinListener.kt @@ -1,7 +1,5 @@ package indi.nightfish.potato_ip_display -import com.google.gson.Gson -import indi.nightfish.potato_ip_display.ip.IpGson import indi.nightfish.potato_ip_display.ip.IpParseFactory import org.bukkit.Bukkit import org.bukkit.ChatColor @@ -12,21 +10,25 @@ import org.bukkit.event.player.PlayerLoginEvent class PlayerJoinListener : Listener { + private val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay + private val conf = plugin.conf @EventHandler - fun onPlayerLoin(event: PlayerLoginEvent) { + fun onPlayerLogin(event: PlayerLoginEvent) { val playerAddress = event.realAddress.hostAddress - val player = event.player - val playerName = player.name + val playerName = event.player.name val ipParse = IpParseFactory.getIpParse(playerAddress) - IpATTRMap.playerIpATTRMap[playerName] = ipParse.getProvincial() - Bukkit.getServer().logger.info("Player named $playerName connect to proxy from ${ipParse.getServiceProvider()}") - + IpATTRMap.playerIpATTRMap[playerName] = ipParse.getProvince() + Bukkit.getServer().logger.info("Player named $playerName connect to proxy from ${ipParse.getISP()}") } @EventHandler fun onPlayerJoin(event: PlayerJoinEvent) { - event.player.sendMessage("${ChatColor.DARK_GRAY}[${ChatColor.GOLD}PotatoIpDisplay${ChatColor.DARK_GRAY}] ${ChatColor.YELLOW}您当前ip归属地 ${ChatColor.GRAY}[${ChatColor.AQUA}${IpATTRMap.playerIpATTRMap[event.player.name]}${ChatColor.GRAY}]${ChatColor.RESET}") + val ipAttr = IpATTRMap.playerIpATTRMap[event.player.name] ?: "未知" + if (conf.message.playerLogin.enabled) { + event.player.sendMessage(conf.message.playerLogin.string + .replace("%ipAttr%", ipAttr)) + } } } diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt index ce995c6..8e85439 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoIpDisplay.kt @@ -2,29 +2,44 @@ package indi.nightfish.potato_ip_display import org.bukkit.Bukkit import org.bukkit.plugin.java.JavaPlugin +import java.io.File class PotatoIpDisplay : JavaPlugin() { + lateinit var conf: PIPDConfig override fun onLoad() { super.onLoad() - logger.info("PotatoIpDisplay loading") + logger.info("Loading") } override fun onEnable() { super.onEnable() - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") == null) { - logger.warning("Could not find PlaceholderAPI! The placeholders will not work!"); + val pm = Bukkit.getPluginManager() + conf = loadPIPDConfig(config) + + if (!File(dataFolder, "config.yml").exists()) { + saveDefaultConfig() } - saveDefaultConfig() - PotatoPlugin.fileConfig = getConfig() + + /*if (pm.getPlugin("PlaceholderAPI") == null) { + logger.warning("Could not find PlaceholderAPI! The placeholders will not work!"); + }*/ + logger.info("Registering event -> Listener") - server.pluginManager.registerEvents(PlayerJoinListener(), this) - server.pluginManager.registerEvents(MessageListener(), this) + if (conf.message.playerChat.enabled) { + // NOTE: formerly "parseOnly", but now we determine if PIPD listens for messages depending on it + pm.registerEvents(MessageListener(), this) + } + if (conf.options.mode == "ip2region" && !File(dataFolder, "ip2region.xdb").exists()) { + logger.warning("ip2region.xdb NOT FOUND! place into \"plugins/PotatoIpDisplay/ip2region.xdb\"") + } + pm.registerEvents(PlayerJoinListener(), this) + logger.info("Ready. Using ${conf.options.mode} mode.") } override fun onDisable() { super.onDisable() - logger.info("Disabling PotatoIpDisplay") + logger.info("Disabled") } } \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoPlugin.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoPlugin.kt deleted file mode 100644 index 319ffb6..0000000 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/PotatoPlugin.kt +++ /dev/null @@ -1,7 +0,0 @@ -package indi.nightfish.potato_ip_display - -import org.bukkit.configuration.file.FileConfiguration - -object PotatoPlugin { - lateinit var fileConfig: FileConfiguration -} \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/Ip2regionParse.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/Ip2regionParse.kt new file mode 100644 index 0000000..5b6da9c --- /dev/null +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/Ip2regionParse.kt @@ -0,0 +1,63 @@ +package indi.nightfish.potato_ip_display.ip + +import org.lionsoul.ip2region.xdb.Searcher + + +class Ip2regionParse(private val ip: String) : IpParse { + + private val dbFile: String = "plugins/PotatoIpDisplay/ip2region.xdb" + + private val searcher: Searcher by lazy { + Searcher.newWithFileOnly(dbFile) + } + + /* Structure of the information returned: + INDEX: | 0 | 1 | 2 | 3 | 4 | + | COUNTRY | ? | PROVINCE | CITY | ISP | + IP1 | 中国 | 0 | 上海 | 上海市 | 联通 | + IP2 | 美国 | 0 | 加利福尼亚 | 0 | 0 | + IP3 | 0 | 0 | 0 | 内网IP | 内网IP | + + */ + + override fun getRegion(): String { + return "null" + } + + override fun getCountry(): String { + val country = try { + searcher.search(ip).split("|")[0] + } catch (e: Exception) { + "" + } + // If null replace with getCity() + return if (country == "0") getCity() else country + } + + override fun getProvince(): String { + val province = try { + searcher.search(ip).split("|")[2].replace("省", "") + } catch (e: Exception) { + "" + } + // If null replace with getCountry() + return if (province == "0") getCountry() else province + } + + + override fun getCity(): String { + return try { + searcher.search(ip).split("|")[3].replace("市", "") + } catch (e: Exception) { + "" + } + } + + override fun getISP(): String { + return try { + searcher.search(ip).split("|")[4] + } catch (e: Exception) { + "" + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParse.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParse.kt index 9a59271..8cf6789 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParse.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParse.kt @@ -3,7 +3,7 @@ package indi.nightfish.potato_ip_display.ip interface IpParse { fun getRegion(): String fun getCountry(): String - fun getProvincial(): String + fun getProvince(): String fun getCity(): String - fun getServiceProvider(): String + fun getISP(): String } \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParseFactory.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParseFactory.kt index b088d8d..1c6cae4 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParseFactory.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/IpParseFactory.kt @@ -1,7 +1,17 @@ package indi.nightfish.potato_ip_display.ip +import indi.nightfish.potato_ip_display.PotatoIpDisplay +import org.bukkit.Bukkit + object IpParseFactory { + fun getIpParse(ip: String): IpParse{ - return WebIpParse(ip) + val plugin = Bukkit.getPluginManager().getPlugin("PotatoIpDisplay") as PotatoIpDisplay + val conf = plugin.conf + return when (val mode = conf.options.mode) { + "pconline" -> PconlineParse(ip) + "ip2region" -> Ip2regionParse(ip) + else -> throw IllegalArgumentException("Invalid mode in config >> $mode") + } } } \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/WebIpParse.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/PconlineParse.kt similarity index 76% rename from src/main/kotlin/indi/nightfish/potato_ip_display/ip/WebIpParse.kt rename to src/main/kotlin/indi/nightfish/potato_ip_display/ip/PconlineParse.kt index 58a4cab..db850bd 100644 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/WebIpParse.kt +++ b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/PconlineParse.kt @@ -2,7 +2,7 @@ package indi.nightfish.potato_ip_display.ip import com.google.gson.Gson -class WebIpParse(ip: String) : IpParse { +class PconlineParse(ip: String) : IpParse { private val parseData: IpGson = Gson().fromJson("https://whois.pconline.com.cn/ipJson.jsp?ip=$ip&json=true", IpGson::class.java) override fun getRegion(): String = parseData.region @@ -13,8 +13,8 @@ class WebIpParse(ip: String) : IpParse { "中国" } - override fun getProvincial(): String = parseData.pro + override fun getProvince(): String = parseData.pro override fun getCity(): String = parseData.city - override fun getServiceProvider(): String = parseData.addr + override fun getISP(): String = parseData.addr } \ No newline at end of file diff --git a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/httpConnectionUtil.kt b/src/main/kotlin/indi/nightfish/potato_ip_display/ip/httpConnectionUtil.kt deleted file mode 100644 index e508c39..0000000 --- a/src/main/kotlin/indi/nightfish/potato_ip_display/ip/httpConnectionUtil.kt +++ /dev/null @@ -1,69 +0,0 @@ -package indi.nightfish.potato_ip_display.ip - -import java.io.* -import java.net.HttpURLConnection -import java.net.URL - - -/** - * @author riemann - * @date 2019/05/24 23:42 - */ -object HttpURLConnectionUtil { - /** - * Http get请求 - * @param httpUrl 连接 - * @return 响应数据 - */ - fun get(httpUrl: String?): String { - //链接 - var connection: HttpURLConnection? = null - var `is`: InputStream? = null - var br: BufferedReader? = null - val result = StringBuffer() - try { - //创建连接 - val url = URL(httpUrl) - connection = url.openConnection() as HttpURLConnection - //设置请求方式 - connection.setRequestMethod("GET") - //设置连接超时时间 - connection.setReadTimeout(15000) - //开始连接 - connection.connect() - //获取响应数据 - if (connection.getResponseCode() == 200) { - //获取返回的数据 - `is` = connection.inputStream - if (null != `is`) { - br = BufferedReader(InputStreamReader(`is`, "UTF-8")) - var temp: String? - while (null != br.readLine().also { temp = it }) { - result.append(temp) - } - } - } - } catch (e: IOException) { - e.printStackTrace() - } finally { - if (null != br) { - try { - br.close() - } catch (e: IOException) { - e.printStackTrace() - } - } - if (null != `is`) { - try { - `is`.close() - } catch (e: IOException) { - e.printStackTrace() - } - } - //关闭远程连接 - connection!!.disconnect() - } - return result.toString() - } -} - diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 218faea..5ed953f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1 +1,33 @@ -parseOnly: false \ No newline at end of file +# Configurations for PotatoIpDisplay-bukkit, +# A Plugin for Checking Player Ip Attributions. +# Learn more at [https://github.com/dmzz-yyhyy/PotatoIpDisplay] + +# [Int] DO NOT TOUCH THIS! +config-version: 1 + +# General options +options: + # Working API: "pconline"(remote) or "ip2region"(local) + # "ip2region" depends on ip2region.xdb in the plugin directory to work. + # Get it from [https://github.com/lionsoul2014/ip2region/tree/master/data] + mode: "ip2region" + +messages: + # Messages sent by players. Use plugin to format + player-chat: + # [Boolean] Whether to listen for, and take over player chat messages + enabled: true + string: "§7[§b%ipAttr%§7] §f%playerName% §7>> §f%msg%" + + # Send a message to the player after logging in + player-login: + # [Boolean] Send a message after player login + enabled: true + string: "§7[§6PotatoIpDisplay§7] §e您当前IP归属地 §7[§b%ipAttr%§7]" + +# Placeholder API options +# TODO: WIP. +papi: + # [Boolean] Enable PAPI support. + enabled: false + format: "" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index bfd0daa..2534d3f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ -name: PotatoIdDisplay +name: PotatoIpDisplay main: indi.nightfish.potato_ip_display.PotatoIpDisplay -version: 1.1 +version: 1.2 author: "NightFish" softdepend: [PlaceholderAPI]