From 86ce6cc30254c83a096e4d439527d5c5182fea63 Mon Sep 17 00:00:00 2001
From: WpyQwq <3911625973@qq.com>
Date: Sat, 19 Sep 2026 12:06:47 +0800
Subject: [PATCH] =?UTF-8?q?Initial=20commit:=20HardwareFingerprint?=
=?UTF-8?q?=EF=BC=9APaper=20=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=8F=92=E4=BB=B6?=
=?UTF-8?q?=EF=BC=88Java=2021=EF=BC=89=EF=BC=8C=E5=9F=BA=E4=BA=8E=E7=A1=AC?=
=?UTF-8?q?=E4=BB=B6=E6=8C=87=E7=BA=B9=E7=9A=84=E6=9C=8D=E5=8A=A1=E7=AB=AF?=
=?UTF-8?q?=E6=A0=A1=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 58 ++++
.../security/HardwareFingerprintPlugin.java | 251 ++++++++++++++++++
.../fingerprint/FingerprintCollector.java | 69 +++++
.../security/fingerprint/FingerprintData.java | 128 +++++++++
.../fingerprint/FingerprintManager.java | 114 ++++++++
.../com/security/listener/PlayerListener.java | 130 +++++++++
.../security/storage/FingerprintLogger.java | 90 +++++++
.../com/security/storage/StorageManager.java | 224 ++++++++++++++++
.../verification/VerificationManager.java | 142 ++++++++++
src/main/resources/config.yml | 74 ++++++
src/main/resources/plugin.yml | 25 ++
11 files changed, 1305 insertions(+)
create mode 100644 pom.xml
create mode 100644 src/main/java/com/security/HardwareFingerprintPlugin.java
create mode 100644 src/main/java/com/security/fingerprint/FingerprintCollector.java
create mode 100644 src/main/java/com/security/fingerprint/FingerprintData.java
create mode 100644 src/main/java/com/security/fingerprint/FingerprintManager.java
create mode 100644 src/main/java/com/security/listener/PlayerListener.java
create mode 100644 src/main/java/com/security/storage/FingerprintLogger.java
create mode 100644 src/main/java/com/security/storage/StorageManager.java
create mode 100644 src/main/java/com/security/verification/VerificationManager.java
create mode 100644 src/main/resources/config.yml
create mode 100644 src/main/resources/plugin.yml
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