修复:登陆后物品无法还原的bug

This commit is contained in:
ypsdf1
2026-05-07 00:24:15 +08:00
parent 68bcbe2e41
commit 48b31deaac
5 changed files with 455 additions and 568 deletions
@@ -51,10 +51,20 @@ public class DatabaseManager {
addColumnIfMissing("temp_password", "TEXT DEFAULT ''");
addColumnIfMissing("temp_pw_expire", "INTEGER DEFAULT 0");
addColumnIfMissing("temp_pw_used", "INTEGER DEFAULT 0");
st.executeUpdate("CREATE TABLE IF NOT EXISTS inventory_backups ("
+ "player_name TEXT PRIMARY KEY, "
+ "inventory_data TEXT DEFAULT '', "
+ "armor_data TEXT DEFAULT '', "
+ "extra_data TEXT DEFAULT '', "
+ "player_level INTEGER DEFAULT 0, "
+ "player_exp REAL DEFAULT 0.0)");
st.close();
} catch (Exception e) {
throw new RuntimeException(
"[Sdf1_login] DB初始化失败: " + e.getMessage(), e);
}
}
@@ -62,7 +72,77 @@ public class DatabaseManager {
try {
if (db != null && !db.isClosed()) db.close();
} catch (Exception ignored) {}
}
public void saveInventoryBackup(String name, String inv, String armor, String extra, int level, double exp) {
try {
PreparedStatement ps = db.prepareStatement(
"INSERT OR REPLACE INTO inventory_backups "
+ "(player_name, inventory_data, armor_data, extra_data, player_level, player_exp) "
+ "VALUES (?, ?, ?, ?, ?, ?)");
ps.setString(1, name);
ps.setString(2, inv);
ps.setString(3, armor);
ps.setString(4, extra);
ps.setInt(5, level);
ps.setDouble(6, exp);
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public String[] loadInventoryBackup(String name) {
try {
PreparedStatement ps = db.prepareStatement(
"SELECT inventory_data, armor_data, extra_data, player_level, player_exp "
+ "FROM inventory_backups WHERE player_name = ?");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String[] result = new String[5];
result[0] = rs.getString("inventory_data");
result[1] = rs.getString("armor_data");
result[2] = rs.getString("extra_data");
result[3] = String.valueOf(rs.getInt("player_level"));
result[4] = String.valueOf(rs.getDouble("player_exp"));
rs.close();
ps.close();
return result;
}
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public boolean hasInventoryBackup(String name) {
try {
PreparedStatement ps = db.prepareStatement(
"SELECT 1 FROM inventory_backups "
+ "WHERE player_name = ? AND inventory_data != ''");
ps.setString(1, name);
ResultSet rs = ps.executeQuery();
boolean has = rs.next();
rs.close();
ps.close();
return has;
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public void setFieldSafe(String name, String field, Object value) {
if (userExists(name)) {
setField(name, field, value);
}
}
public Connection getDb() { return db; }
private void addColumnIfMissing(String col, String def) {
@@ -0,0 +1,46 @@
package Sdf1_login;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
public class InventorySerializer {
public static String toBase64(ItemStack[] items) throws IOException {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
dataOutput.writeInt(items.length);
for (ItemStack item : items) {
dataOutput.writeObject(item);
}
dataOutput.close();
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
} catch (Exception e) {
throw new IOException("Unable to serialize item stacks.", e);
}
}
public static ItemStack[] fromBase64(String data) throws IOException {
if (data == null || data.isEmpty()) {
return new ItemStack[0];
}
try {
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(data));
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
ItemStack[] items = new ItemStack[dataInput.readInt()];
for (int i = 0; i < items.length; i++) {
items[i] = (ItemStack) dataInput.readObject();
}
dataInput.close();
return items;
} catch (ClassNotFoundException e) {
throw new IOException("Unable to deserialize item stacks.", e);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,75 @@
package Sdf1_login;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Level;
public class VerificationManager {
private final Main plugin;
public VerificationManager(Main plugin) {
this.plugin = plugin;
}
public boolean isBedrockPlayer(Player player) {
UUID uuid = player.getUniqueId();
if (uuid.toString().startsWith("00000000-0000-0000-0009-")) {
return true;
}
if (player.hasMetadata("isgeyserplayer")) {
return true;
}
if (player.hasPermission("geyser.player")) {
return true;
}
try {
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate");
if (floodgate == null) {
floodgate = Bukkit.getPluginManager().getPlugin("Floodgate");
}
if (floodgate != null && floodgate.isEnabled()) {
Class<?> apiClass = Class.forName("org.geysermc.floodgate.api.FloodgateApi");
Object api = apiClass.getMethod("getInstance").invoke(null);
boolean isBedrock = (boolean) apiClass.getMethod("isFloodgatePlayer", UUID.class).invoke(api, uuid);
if (isBedrock) return true;
}
} catch (Exception ignored) {
}
return false;
}
public boolean isOnlineMode() {
return Bukkit.getOnlineMode();
}
public void verifyPremiumAsync(Player player, Consumer<Boolean> callback) {
String name = player.getName();
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
boolean result = checkMojangApi(name);
Bukkit.getScheduler().runTask(plugin, () -> callback.accept(result));
});
}
private boolean checkMojangApi(String name) {
try {
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + name);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "Sdf1_login");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int code = conn.getResponseCode();
conn.disconnect();
return code == 200;
} catch (Exception e) {
plugin.getLogger().log(Level.WARNING, "Mojang API failed: " + name, e);
return false;
}
}
}
+2 -2
View File
@@ -39,9 +39,9 @@ commands:
找回密码:
description: 找回密码(中文)
usage: /找回密码
debug:
sdf1debug:
description: 调试指令
usage: /debug <玩家> take.<阶段>
usage: /sdf1debug <玩家> take.<阶段>
签到:
description: 每日签到(中文)
usage: /签到