diff --git a/build.gradle b/build.gradle index 5320087..8df8b4a 100644 --- a/build.gradle +++ b/build.gradle @@ -104,10 +104,13 @@ configurations { dependencies { implementation "net.neoforged:neoforge:${neo_version}" - compileOnly "maven.modrinth:curios:7.4.3+1.20.4" - compileOnly "curse.maven:sophisticated-backpacks-422301:5297718" - compileOnly "curse.maven:sophisticated-core-618298:5296142" + compileOnly "curse.maven:curios-309927:6529130" + compileOnly "curse.maven:sophisticated-backpacks-422301:7169832" + compileOnly "curse.maven:sophisticated-core-618298:7168230" + runtimeOnly "curse.maven:curios-309927:6529130" + runtimeOnly "curse.maven:sophisticated-backpacks-422301:7169832" + runtimeOnly "curse.maven:sophisticated-core-618298:7168230" // embedd the JDBC driver in the mod using jarJar runtimeOnly "com.mysql:mysql-connector-j:${jdbc_version}" jarJar "com.mysql:mysql-connector-j:${jdbc_version}" diff --git a/src/main/java/vip/fubuki/playersync/CommandInit.java b/src/main/java/vip/fubuki/playersync/CommandInit.java index c20866b..ed778dd 100644 --- a/src/main/java/vip/fubuki/playersync/CommandInit.java +++ b/src/main/java/vip/fubuki/playersync/CommandInit.java @@ -2,7 +2,6 @@ package vip.fubuki.playersync; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -13,14 +12,14 @@ public class CommandInit { @SubscribeEvent public static void registerCommand(RegisterCommandsEvent event){ CommandDispatcher dispatcher=event.getDispatcher(); - dispatcher.register(Commands.literal("playersync") - .requires(cs->cs.hasPermission(2)) - .then(Commands.literal("reconnect") - .executes(context -> { -// context.getSource().sendSuccess(()->MutableComponent.create(new TranslatableContents("playersync.command.reconnect")),true); - return 0; - } - )) - ); +// dispatcher.register(Commands.literal("playersync") +// .requires(cs->cs.hasPermission(2)) +// .then(Commands.literal("reconnect") +// .executes(context -> { +//// context.getSource().sendSuccess(()->MutableComponent.create(new TranslatableContents("playersync.command.reconnect")),true); +// return 0; +// } +// )) +// ); } } diff --git a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java index 33f6b66..4e2dbe1 100644 --- a/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java +++ b/src/main/java/vip/fubuki/playersync/sync/VanillaSync.java @@ -558,9 +558,13 @@ public class VanillaSync { public static void onPlayerLogout(PlayerEvent.PlayerLoggedOutEvent event) throws SQLException { String player_uuid = event.getEntity().getUUID().toString(); if (deadPlayerWhileLogging.contains(player_uuid)) { - PlayerSync.LOGGER.warn("A dead or dying player was kicked,which uuid is:" + player_uuid); + PlayerSync.LOGGER.warn("A dead or dying player was kicked,which uuid is:{}", player_uuid); JDBCsetUp.executeUpdate("UPDATE player_data SET online= '0' WHERE uuid='" + player_uuid + "'"); deadPlayerWhileLogging.remove(player_uuid); + } else if (syncNotCompletedPlayer.contains(player_uuid)) { + PlayerSync.LOGGER.warn("A player logged out with uncompleted sync data,which uuid is:{}.For the safety,the new data won't be saved", player_uuid); + JDBCsetUp.executeUpdate("UPDATE player_data SET online= '0' WHERE uuid='" + player_uuid + "'"); + syncNotCompletedPlayer.remove(player_uuid); } else { // Mod support ModsSupport modsSupport = new ModsSupport(); @@ -604,7 +608,7 @@ public class VanillaSync { PlayerSync.LOGGER.info("Storing data for player " + player_uuid + " (init=" + init + ")"); // Basic Attributes - int XP = player.totalExperience; + int XP = getTotalExperience(player); int score = player.getScore(); int food_level = player.getFoodData().getFoodLevel(); int health = (int) player.getHealth(); @@ -650,7 +654,7 @@ public class VanillaSync { if (JdbcConfig.SYNC_ADVANCEMENTS.get()) { File gameDir = Objects.requireNonNull(player.getServer()).getServerDirectory().toFile(); final MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - if (server != null && server.isDedicatedServer() ) { + if (server != null && server.isDedicatedServer()) { PlayerSync.LOGGER.trace("Reading dedicated server advancements"); advancements = new File(gameDir, getSyncWorldForServer() + "/advancements" + "/" + player_uuid + ".json"); } else { diff --git a/src/main/java/vip/fubuki/playersync/sync/addons/ModsSupport.java b/src/main/java/vip/fubuki/playersync/sync/addons/ModsSupport.java index 25917ec..e91fbea 100644 --- a/src/main/java/vip/fubuki/playersync/sync/addons/ModsSupport.java +++ b/src/main/java/vip/fubuki/playersync/sync/addons/ModsSupport.java @@ -23,8 +23,6 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; -import static vip.fubuki.playersync.sync.VanillaSync.deserializeString; - public class ModsSupport { @@ -101,11 +99,10 @@ public class ModsSupport { PlayerSync.LOGGER.info("Restoring backpack data for player " + player.getUUID()); net.p3pp3rf1y.sophisticatedbackpacks.util.PlayerInventoryProvider.get().runOnBackpacks(player, (ItemStack backpackItem, String handler, String identifier, int slot) -> { net.p3pp3rf1y.sophisticatedbackpacks.backpack.wrapper.IBackpackWrapper backpackWrapper = net.p3pp3rf1y.sophisticatedbackpacks.backpack.wrapper.BackpackWrapper - .fromData(backpackItem); + .fromStack(backpackItem); // Retrieve the contents UUID from the backpack's NBT using NBTHelper - Optional uuidOpt = net.p3pp3rf1y.sophisticatedcore.util.NBTHelper - .getUniqueId(backpackWrapper.getBackpack(), "contentsUuid"); + Optional uuidOpt = backpackWrapper.getContentsUuid(); if (uuidOpt.isPresent()) { UUID contentsUuid = uuidOpt.get(); try { @@ -113,7 +110,7 @@ public class ModsSupport { ResultSet rsBackpack = qrBackpack.resultSet(); if (rsBackpack.next()) { String serialized = rsBackpack.getString("backpack_nbt"); - String nbtString = deserializeString(serialized); + String nbtString = VanillaSync.deserializeString(serialized); CompoundTag backpackNbt = NbtUtils.snbtToStructure(nbtString); // Update BackpackStorage with the retrieved NBT net.p3pp3rf1y.sophisticatedbackpacks.backpack.BackpackStorage.get().setBackpackContents(contentsUuid, backpackNbt); @@ -176,11 +173,10 @@ public class ModsSupport { PlayerSync.LOGGER.info("Storing backpack data for player " + player.getUUID()); net.p3pp3rf1y.sophisticatedbackpacks.util.PlayerInventoryProvider.get().runOnBackpacks(player, (ItemStack backpackItem, String handler, String identifier, int slot) -> { net.p3pp3rf1y.sophisticatedbackpacks.backpack.wrapper.IBackpackWrapper backpackWrapper = net.p3pp3rf1y.sophisticatedbackpacks.backpack.wrapper.BackpackWrapper - .fromData(backpackItem); + .fromStack(backpackItem); // Retrieve the contents UUID from the backpack's NBT using NBTHelper - Optional uuidOpt = net.p3pp3rf1y.sophisticatedcore.util.NBTHelper - .getUniqueId(backpackWrapper.getBackpack(), "contentsUuid"); + Optional uuidOpt = backpackWrapper.getContentsUuid(); if (uuidOpt.isPresent()) { UUID contentsUuid = uuidOpt.get(); // Get internal backpack data from BackpackStorage (creates it if missing) diff --git a/src/main/java/vip/fubuki/playersync/util/LocalJsonUtil.java b/src/main/java/vip/fubuki/playersync/util/LocalJsonUtil.java index f82748d..44c2249 100644 --- a/src/main/java/vip/fubuki/playersync/util/LocalJsonUtil.java +++ b/src/main/java/vip/fubuki/playersync/util/LocalJsonUtil.java @@ -2,31 +2,44 @@ package vip.fubuki.playersync.util; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; public class LocalJsonUtil { - public static Map StringToMap(String param) { - Map map = new HashMap<>(); - String s1 = param.substring(1,param.length()-1); - String s2 = s1.trim(); - String[] split = s2.split(","); - for (int i = split.length - 1; i >= 0; i--) { - String trim = split[i].trim(); - String[] split1 = trim.split("="); - map.put(split1[0],split1[1]); + private static Map stringToGenericMap(String param, Function keyParser) { + Map map = new HashMap<>(); + + // check if string is at least minimal json + if (param == null || param.length() < 2 || param.equals("{}")) { + return map; + } + + // extract string within outermost json brackets {} + String s1 = param.substring(param.indexOf('{')+1, param.lastIndexOf('}')).trim(); + if (s1.isEmpty()) { + return map; + } + + // split all json elements + for (String split : s1.split(",")) { + String trim = split.trim(); + + // only check for the first "=" as the values also contain additional "=" + int equalIndex = trim.indexOf('='); + if (equalIndex < 0) + continue; + + String key = trim.substring(0, equalIndex); + String value = trim.substring(equalIndex + 1); + map.put(keyParser.apply(key), value); } return map; } - public static Map StringToEntryMap(String param) { - Map map = new HashMap<>(); - String s1 = param.substring(1,param.length()-1); - String s2 = s1.trim(); - String[] split = s2.split(","); - for (int i = split.length - 1; i >= 0; i--) { - String trim = split[i].trim(); - String[] split1 = trim.split("="); - map.put(Integer.parseInt(split1[0]),split1[1]); - } - return map; + public static Map StringToMap(String param) { + return stringToGenericMap(param, Function.identity()); + } + + public static Map StringToEntryMap(String param) { + return stringToGenericMap(param, Integer::parseInt); } }