curios snbt clean

This commit is contained in:
mlus 2026-02-23 22:33:13 +08:00
parent bc71c59a45
commit b6da709393
8 changed files with 22 additions and 24 deletions

View File

@ -1,10 +1,11 @@
package vip.fubuki.playersync.config;
import net.neoforged.neoforge.common.ModConfigSpec;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.neoforged.neoforge.common.ModConfigSpec;
public class JdbcConfig {

View File

@ -1,6 +1,5 @@
package vip.fubuki.playersync.mixin.cobblemon;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.api.pokedex.PokedexManager;
import com.cobblemon.mod.common.api.storage.player.InstancedPlayerData;
import com.cobblemon.mod.common.api.storage.player.adapter.NbtBackedPlayerData;

View File

@ -4,7 +4,6 @@ import com.cobblemon.mod.common.api.storage.pc.PCStore;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.TagParser;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;

View File

@ -4,7 +4,6 @@ import com.cobblemon.mod.common.api.storage.party.PartyStore;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.TagParser;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;

View File

@ -36,7 +36,6 @@ import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.OnDatapackSyncEvent;
import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.neoforged.neoforge.event.entity.player.PlayerNegotiationEvent;
import net.neoforged.neoforge.event.server.ServerStoppedEvent;
import net.neoforged.neoforge.event.tick.LevelTickEvent;
@ -372,7 +371,7 @@ public class VanillaSync {
}
// deserialize item and potentially create placeholders
private static ItemStack deserializeAndCreatePlaceholderIfNeeded(String serializedNbt)
public static ItemStack deserializeAndCreatePlaceholderIfNeeded(String serializedNbt)
throws CommandSyntaxException {
if (serializedNbt == null || serializedNbt.isEmpty() || serializedNbt.equals("B64:e30=")) {
// Check for empty NBT (Base64 encoded '{}')
@ -380,7 +379,7 @@ public class VanillaSync {
}
String nbtString = deserializeString(serializedNbt);
CompoundTag compoundTag = TagParser.parseTag(LocalJsonUtil.cleanSnbt(nbtString));
CompoundTag compoundTag = TagParser.parseTag(nbtString);
if (compoundTag.isEmpty() || !compoundTag.contains("id", Tag.TAG_STRING)) {
return ItemStack.EMPTY; // Invalid or empty tag
@ -489,11 +488,13 @@ public class VanillaSync {
}
}
// Legacy fallback using custom replacement
return encoded.replace("|", ",")
// cleanSnbt is applied here because legacy serialization could produce stray {"":""} type markers
// B64-decoded data must NOT be cleaned as it contains verbatim NBT from modern mods
return LocalJsonUtil.cleanSnbt(encoded.replace("|", ",")
.replace("^", "\"")
.replace("<", "{")
.replace(">", "}")
.replace("~", "'");
.replace("~", "'"));
}
/**
@ -574,7 +575,7 @@ public class VanillaSync {
// Helper function to get the NBT string to be saved
// If item is a placeholder, get original NBT; otherwise, get current NBT
private static String getNbtForStorage(ItemStack itemStack) {
public static String getNbtForStorage(ItemStack itemStack) {
if (itemStack.is(Items.PAPER) && itemStack.getComponents().has(DataComponents.CUSTOM_DATA)
&& itemStack.getComponents().get(DataComponents.CUSTOM_DATA).contains("playersync:original_item_nbt")) {
// It's our placeholder, retrieve the original NBT string

View File

@ -4,7 +4,6 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameRules;
import net.neoforged.fml.ModList;
import top.theillusivec4.curios.api.CuriosApi;
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
@ -72,7 +71,7 @@ public class CuriosCache {
for (int i = 0; i < dynStacks.getSlots(); i++) {
ItemStack stack = dynStacks.getStackInSlot(i);
if (!stack.isEmpty()) {
String serialized = VanillaSync.serialize(VanillaSync.serializeNBT(stack).toString());
String serialized = VanillaSync.getNbtForStorage(stack);
flatMap.put(slotType + ":" + i, serialized);
}
}

View File

@ -2,12 +2,10 @@ package vip.fubuki.playersync.sync.addons;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.TagParser;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.neoforged.fml.ModList;
import net.neoforged.neoforge.server.ServerLifecycleHooks;
import top.theillusivec4.curios.api.CuriosApi;
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
@ -44,7 +42,7 @@ public class ModsSupport {
if (rsBackpack.next()) {
String serialized = rsBackpack.getString("backpack_nbt");
String nbtString = VanillaSync.deserializeString(serialized);
CompoundTag backpackNbt = TagParser.parseTag(LocalJsonUtil.cleanSnbt(nbtString));
CompoundTag backpackNbt = TagParser.parseTag(nbtString);
// Update BackpackStorage with the retrieved NBT
net.p3pp3rf1y.sophisticatedbackpacks.backpack.BackpackStorage.get().setBackpackContents(contentsUuid, backpackNbt);
PlayerSync.LOGGER.info("Restored backpack data for UUID " + contentsUuid);
@ -97,22 +95,21 @@ public class ModsSupport {
handlerOpt.ifPresent(handler -> {
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
String compositeKey = entry.getKey(); // Expected format: "slotType:index"
String[] parts = compositeKey.split(":");
if (parts.length != 2) {
// Use lastIndexOf to correctly handle slot type names that may contain ':'
int lastColon = compositeKey.lastIndexOf(':');
if (lastColon < 0) {
continue;
}
String slotType = parts[0];
String slotType = compositeKey.substring(0, lastColon);
int slotIndex;
try {
slotIndex = Integer.parseInt(parts[1]);
slotIndex = Integer.parseInt(compositeKey.substring(lastColon + 1));
} catch (NumberFormatException ex) {
continue;
}
String serialized = entry.getValue();
try {
String nbtString = VanillaSync.deserializeString(serialized);
CompoundTag tag = TagParser.parseTag(LocalJsonUtil.cleanSnbt(nbtString));
ItemStack stack = ItemStack.parse(ServerLifecycleHooks.getCurrentServer().registryAccess(),tag).get();
ItemStack stack = VanillaSync.deserializeAndCreatePlaceholderIfNeeded(serialized);
if (handler.getCurios().containsKey(slotType)) {
ICurioStacksHandler stacksHandler = handler.getCurios().get(slotType);
IDynamicStackHandler dynStacks = stacksHandler.getStacks();
@ -155,7 +152,7 @@ public class ModsSupport {
for (int i = 0; i < dynStacks.getSlots(); i++) {
ItemStack stack = dynStacks.getStackInSlot(i);
if (!stack.isEmpty()) {
String serialized = VanillaSync.serialize(VanillaSync.serializeNBT(stack).toString());
String serialized = VanillaSync.getNbtForStorage(stack);
flatMap.put(slotType + ":" + i, serialized);
}
}

View File

@ -3,7 +3,10 @@ package vip.fubuki.playersync.sync.chat;
import vip.fubuki.playersync.PlayerSync;
import vip.fubuki.playersync.config.JdbcConfig;
import java.io.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;