commit 86ce6cc30254c83a096e4d439527d5c5182fea63
Author: WpyQwq <3911625973@qq.com>
Date: Sat Sep 19 12:06:47 2026 +0800
Initial commit: HardwareFingerprint:Paper 服务端插件(Java 21),基于硬件指纹的服务端校验
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2c4d606
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.security
+ HardwareFingerprint
+ 1.0.0
+ jar
+
+
+ 21
+ UTF-8
+
+
+
+
+ papermc-repo
+ https://repo.papermc.io/repository/maven-public/
+
+
+
+
+
+ io.papermc.paper
+ paper-api
+ 1.21-R0.1-SNAPSHOT
+ provided
+
+
+
+
+ HardwareFingerprint-${project.version}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ ${java.version}
+ ${java.version}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.5.0
+
+
+ package
+ shade
+
+
+
+
+
+
diff --git a/src/main/java/com/security/HardwareFingerprintPlugin.java b/src/main/java/com/security/HardwareFingerprintPlugin.java
new file mode 100644
index 0000000..ea558eb
--- /dev/null
+++ b/src/main/java/com/security/HardwareFingerprintPlugin.java
@@ -0,0 +1,251 @@
+package com.security;
+
+import com.security.fingerprint.FingerprintCollector;
+import com.security.fingerprint.FingerprintManager;
+import com.security.fingerprint.FingerprintData;
+import com.security.listener.PlayerListener;
+import com.security.storage.FingerprintLogger;
+import com.security.storage.StorageManager;
+import com.security.verification.VerificationManager;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class HardwareFingerprintPlugin extends JavaPlugin {
+
+ private FingerprintCollector collector;
+ private FingerprintManager fingerprintManager;
+ private StorageManager storageManager;
+ private VerificationManager verificationManager;
+ private FingerprintLogger fingerprintLogger;
+
+ @Override
+ public void onEnable() {
+ saveDefaultConfig();
+ reloadConfig();
+
+ ConfigurationSection config = getConfig();
+
+ fingerprintLogger = new FingerprintLogger(this);
+
+ collector = new FingerprintCollector(this);
+ fingerprintManager = new FingerprintManager(config);
+
+ ConfigurationSection dbConfig = config.getConfigurationSection("database");
+ if (dbConfig == null) {
+ getLogger().severe("数据库配置缺失!");
+ Bukkit.getPluginManager().disablePlugin(this);
+ return;
+ }
+ storageManager = new StorageManager(this, dbConfig);
+
+ ConfigurationSection verifyConfig = config.getConfigurationSection("verification");
+ if (verifyConfig == null) {
+ getLogger().severe("验证配置缺失!");
+ Bukkit.getPluginManager().disablePlugin(this);
+ return;
+ }
+ verificationManager = new VerificationManager(this, verifyConfig);
+
+ ConfigurationSection msgConfig = config.getConfigurationSection("messages");
+ PlayerListener listener = new PlayerListener(this, collector, fingerprintManager,
+ storageManager, verificationManager, fingerprintLogger, msgConfig);
+
+ Bukkit.getPluginManager().registerEvents(listener, this);
+
+ fingerprintLogger.logRaw("========================================");
+ fingerprintLogger.logRaw("HardwareFingerprint 插件已加载");
+ fingerprintLogger.logRaw("ProtocolLib: " + (collector.isProtocolLibAvailable() ? "已连接" : "未安装"));
+ fingerprintLogger.logRaw("========================================");
+
+ getLogger().info("§a✓ HardwareFingerprint 插件已加载");
+ getLogger().info("§a✓ ProtocolLib " + (collector.isProtocolLibAvailable() ? "已连接" : "未安装(功能受限)"));
+
+ if (!collector.isProtocolLibAvailable()) {
+ getLogger().warning("§e建议安装 ProtocolLib 以获得完整的指纹收集功能");
+ getLogger().warning("§e下载地址: https://www.spigotmc.org/resources/protocollib.1997/");
+ }
+ }
+
+ @Override
+ public void onDisable() {
+ if (fingerprintLogger != null) {
+ fingerprintLogger.logRaw("HardwareFingerprint 插件已卸载");
+ fingerprintLogger.close();
+ }
+ if (storageManager != null) {
+ storageManager.close();
+ }
+ getLogger().info("HardwareFingerprint 插件已卸载");
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!command.getName().equalsIgnoreCase("hfp")) return false;
+
+ if (args.length == 0) {
+ sendHelp(sender);
+ return true;
+ }
+
+ switch (args[0].toLowerCase()) {
+ case "verify" -> handleVerify(sender, args);
+ case "info" -> handleInfo(sender, args);
+ case "history" -> handleHistory(sender, args);
+ case "status" -> handleStatus(sender);
+ case "reload" -> handleReload(sender);
+ default -> sendHelp(sender);
+ }
+ return true;
+ }
+
+ private void handleVerify(CommandSender sender, String[] args) {
+ if (!(sender instanceof Player player)) {
+ sender.sendMessage("§c此命令仅限玩家使用");
+ return;
+ }
+ if (args.length < 2) {
+ player.sendMessage("§c用法: /hfp verify <验证码>");
+ return;
+ }
+ if (verificationManager.verify(player, args[1])) {
+ player.sendMessage("§a✓ 设备验证通过!");
+ }
+ }
+
+ private void handleInfo(CommandSender sender, String[] args) {
+ if (!sender.hasPermission("hardwarefingerprint.admin")) {
+ sender.sendMessage("§c你没有权限执行此命令");
+ return;
+ }
+ Player target;
+ if (args.length >= 2) {
+ target = Bukkit.getPlayer(args[1]);
+ } else if (sender instanceof Player) {
+ target = (Player) sender;
+ } else {
+ sender.sendMessage("§c请指定玩家名称");
+ return;
+ }
+ if (target == null) {
+ sender.sendMessage("§c玩家不在线");
+ return;
+ }
+ FingerprintData current = collector.collect(target);
+ FingerprintData stored = storageManager.loadFingerprint(target.getUniqueId());
+
+ sender.sendMessage("§8=== §b指纹信息 - " + target.getName() + " §8===");
+ sender.sendMessage("§7UUID: §f" + target.getUniqueId());
+ sender.sendMessage("§7IP: §f" + current.getIpAddress());
+ sender.sendMessage("§7客户端: §f" + (current.getClientBrand() != null ? current.getClientBrand() : "未知"));
+ sender.sendMessage("§7区域语言: §f" + current.getLocale());
+ sender.sendMessage("§7视野距离: §f" + current.getViewDistance());
+ sender.sendMessage("§7惯用手: §f" + current.getMainHand());
+ sender.sendMessage("§7操作系统: §f" + (current.getOsName() != null ? current.getOsName() : "未知"));
+ sender.sendMessage("§7系统架构: §f" + (current.getOsArch() != null ? current.getOsArch() : "未知"));
+ sender.sendMessage("§7Java版本: §f" + (current.getJavaVersion() != null ? current.getJavaVersion() : "未知"));
+ sender.sendMessage("§7CPU核心: §f" + (current.getCpuCores() > 0 ? current.getCpuCores() : "未知"));
+ sender.sendMessage("§7屏幕分辨率: §f" + (current.getScreenWidth() > 0 ?
+ current.getScreenWidth() + "x" + current.getScreenHeight() : "未知"));
+
+ if (stored != null) {
+ int risk = fingerprintManager.calculateRiskScore(current, stored);
+ sender.sendMessage("§7本次风险评分: §" + (risk > 60 ? "c" : risk > 30 ? "e" : "a") + risk);
+ sender.sendMessage("§7指纹哈希: §f" + current.computeHash().substring(0, 16) + "...");
+ sender.sendMessage("§7首次登录: §f" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ .format(new java.util.Date(stored.getFirstSeen())));
+ sender.sendMessage("§7上次登录: §f" + new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+ .format(new java.util.Date(stored.getLastSeen())));
+ } else {
+ sender.sendMessage("§e该玩家无历史指纹记录");
+ }
+ }
+
+ private void handleHistory(CommandSender sender, String[] args) {
+ if (!sender.hasPermission("hardwarefingerprint.admin")) {
+ sender.sendMessage("§c你没有权限执行此命令");
+ return;
+ }
+ if (args.length < 2) {
+ sender.sendMessage("§c用法: /hfp history <玩家名>");
+ return;
+ }
+ Player target = Bukkit.getPlayer(args[1]);
+ if (target == null) {
+ sender.sendMessage("§c玩家不在线,但将尝试查找记录...");
+ }
+ UUID uuid = target != null ? target.getUniqueId() : parseOffline(args[1]);
+ if (uuid == null) {
+ sender.sendMessage("§c无法识别该玩家");
+ return;
+ }
+ List