package com.example.playermanager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerManagerPlugin extends JavaPlugin implements Listener {
private Map<String, Integer> ipConnectionCount;
private int maxConnectionsPerIP;
@Override
public void onEnable() {
// 保存默认配置
saveDefaultConfig();
// 从配置中获取最大连接数
maxConnectionsPerIP = getConfig().getInt("max-connections-per-ip", 3);
// 初始化IP连接计数
ipConnectionCount = new HashMap<>();
// 注册事件监听器
getServer().getPluginManager().registerEvents(this, this);
// 记录启用日志
getLogger().info("玩家管理插件已启用! 每个IP最大连接数: " + maxConnectionsPerIP);
}
@Override
public void onDisable() {
// 清理资源
ipConnectionCount.clear();
getLogger().info("玩家管理插件已禁用!");
}
@EventHandler
public void onPlayerLogin(PlayerLoginEvent event) {
Player player = event.getPlayer();
String ipAddress = event.getAddress().getHostAddress();
// 跳过本地连接或本地主机
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("localhost")) {
return;
}
// 获取当前IP的连接数
int currentConnections = ipConnectionCount.getOrDefault(ipAddress, 0);
// 检查是否超过限制
if (currentConnections >= maxConnectionsPerIP) {
String kickMessage = getConfig().getString("kick-message",
"每个IP最多允许" + maxConnectionsPerIP + "个连接");
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, kickMessage);
return;
}
// 增加连接计数
ipConnectionCount.put(ipAddress, currentConnections + 1);
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("queryplayer")) {
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "用法: /queryplayer <玩家名>");
return true;
}
String playerName = args[0];
Player target = Bukkit.getPlayer(playerName);
if (target == null) {
sender.sendMessage(ChatColor.RED + "玩家 " + playerName + " 不在线或不存在!");
return true;
}
// 获取玩家信息
String ipAddress = target.getAddress().getAddress().getHostAddress();
UUID uuid = target.getUniqueId();
String world = target.getWorld().getName();
int ping = getPing(target);
// 发送玩家信息
sender.sendMessage(ChatColor.GREEN + "=== 玩家信息 ===");
sender.sendMessage(ChatColor.YELLOW + "名称: " + ChatColor.WHITE + target.getName());
sender.sendMessage(ChatColor.YELLOW + "UUID: " + ChatColor.WHITE + uuid);
sender.sendMessage(ChatColor.YELLOW + "IP地址: " + ChatColor.WHITE + ipAddress);
sender.sendMessage(ChatColor.YELLOW + "所在世界: " + ChatColor.WHITE + world);
sender.sendMessage(ChatColor.YELLOW + "游戏模式: " + ChatColor.WHITE + target.getGameMode());
sender.sendMessage(ChatColor.YELLOW + "生命值: " + ChatColor.WHITE + target.getHealth() + "/" + target.getMaxHealth());
sender.sendMessage(ChatColor.YELLOW + "等级: " + ChatColor.WHITE + target.getLevel());
sender.sendMessage(ChatColor.YELLOW + "Ping: " + ChatColor.WHITE + ping + "ms");
return true;
} else if (cmd.getName().equalsIgnoreCase("ipstats")) {
if (!sender.hasPermission("playermanager.ipstats")) {
sender.sendMessage(ChatColor.RED + "你没有权限使用此命令!");
return true;
}
sender.sendMessage(ChatColor.GREEN + "=== IP连接统计 ===");
for (Map.Entry<String, Integer> entry : ipConnectionCount.entrySet()) {
sender.sendMessage(ChatColor.YELLOW + entry.getKey() + ": " +
ChatColor.WHITE + entry.getValue() + " 个连接");
}
return true;
}
return false;
}
// 获取玩家ping值
private int getPing(Player player) {
try {
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
return (int) entityPlayer.getClass().getField("ping").get(entityPlayer);
} catch (Exception e) {
return -1;
}
}
}
每个IP允许的最大连接数量
max-connections-per-ip: 3
当玩家因IP限制被踢出时显示的消息
kick-message: “每个IP最多允许{max}个连接”
命令权限设置
commands:
queryplayer:
permission: “playermanager.query”
default: op
ipstats:
permission: “playermanager.ipstats”
default: op
name: PlayerManager
version: 1.0.0
main: com.example.playermanager.PlayerManagerPlugin
api-version: 1.20
author: YourName
description: 玩家查询和IP连接限制插件
commands:
queryplayer:
description: 查询在线玩家信息
usage: /queryplayer <玩家名>
permission: playermanager.query
permission-message: 你没有权限使用此命令!
ipstats:
description: 查看IP连接统计
usage: /ipstats
permission: playermanager.ipstats
permission-message: 你没有权限使用此命令!
permissions:
playermanager.query:
description: 允许使用查询玩家命令
default: op
playermanager.ipstats:
description: 允许查看IP统计
default: op
- 玩家查询功能:
- 使用
/queryplayer <玩家名>命令查询在线玩家的详细信息 - 显示信息包括: 名称、UUID、IP地址、所在世界、游戏模式、生命值、等级和Ping值
- 使用
- IP连接限制:
- 每个IP地址最多允许指定数量的连接(默认3个)
- 超过限制的新连接会被拒绝并显示提示消息
- 使用
/ipstats命令查看当前IP连接统计
- 权限管理:
playermanager.query– 使用查询玩家命令的权限playermanager.ipstats– 查看IP统计的权限





