Skip to content

Commit

Permalink
Feat: improvements & add local ip2region support
Browse files Browse the repository at this point in the history
  • Loading branch information
yukonisen committed Mar 30, 2024
1 parent a0698b1 commit 6c288c9
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 123 deletions.
2 changes: 2 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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")
}
}
32 changes: 17 additions & 15 deletions src/main/kotlin/indi/nightfish/potato_ip_display/MessageListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
64 changes: 64 additions & 0 deletions src/main/kotlin/indi/nightfish/potato_ip_display/PIPDConfig.kt
Original file line number Diff line number Diff line change
@@ -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") ?: ""

)
)
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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))
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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) {
""
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
@@ -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")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
}
Loading

0 comments on commit 6c288c9

Please sign in to comment.