Fix anti-duplication: clear slots before restoring data
This commit is contained in:
parent
a8c0cb50af
commit
eec949f405
|
|
@ -155,17 +155,15 @@ public class ModCompatSync {
|
||||||
*/
|
*/
|
||||||
public static void applyAccessoriesFromData(Player player, String accessoriesData) {
|
public static void applyAccessoriesFromData(Player player, String accessoriesData) {
|
||||||
if (!ModList.get().isLoaded("accessories")) return;
|
if (!ModList.get().isLoaded("accessories")) return;
|
||||||
if (accessoriesData == null || accessoriesData.length() <= 2) return;
|
|
||||||
try {
|
try {
|
||||||
io.wispforest.accessories.api.AccessoriesCapability cap =
|
io.wispforest.accessories.api.AccessoriesCapability cap =
|
||||||
io.wispforest.accessories.api.AccessoriesCapability.get(player);
|
io.wispforest.accessories.api.AccessoriesCapability.get(player);
|
||||||
if (cap == null) return;
|
if (cap == null) return;
|
||||||
|
|
||||||
Map<String, String> storedMap = LocalJsonUtil.StringToMap(accessoriesData);
|
|
||||||
if (storedMap.isEmpty()) return;
|
|
||||||
|
|
||||||
Map<String, io.wispforest.accessories.api.AccessoriesContainer> containers = cap.getContainers();
|
Map<String, io.wispforest.accessories.api.AccessoriesContainer> containers = cap.getContainers();
|
||||||
|
|
||||||
|
// FIX ANTI-DUPLICATION: ALWAYS clear accessories slots first to wipe stale
|
||||||
|
// data from Minecraft's .dat file, then only restore if DB has valid data.
|
||||||
for (io.wispforest.accessories.api.AccessoriesContainer container : containers.values()) {
|
for (io.wispforest.accessories.api.AccessoriesContainer container : containers.values()) {
|
||||||
var accessories = container.getAccessories();
|
var accessories = container.getAccessories();
|
||||||
for (int i = 0; i < accessories.getContainerSize(); i++) {
|
for (int i = 0; i < accessories.getContainerSize(); i++) {
|
||||||
|
|
@ -173,6 +171,11 @@ public class ModCompatSync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accessoriesData == null || accessoriesData.length() <= 2) return;
|
||||||
|
|
||||||
|
Map<String, String> storedMap = LocalJsonUtil.StringToMap(accessoriesData);
|
||||||
|
if (storedMap.isEmpty()) return;
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
||||||
String compositeKey = entry.getKey();
|
String compositeKey = entry.getKey();
|
||||||
int lastColon = compositeKey.lastIndexOf(':');
|
int lastColon = compositeKey.lastIndexOf(':');
|
||||||
|
|
@ -308,19 +311,22 @@ public class ModCompatSync {
|
||||||
*/
|
*/
|
||||||
public static void applyCosmeticArmorFromData(Player player, String cosmeticArmorData) {
|
public static void applyCosmeticArmorFromData(Player player, String cosmeticArmorData) {
|
||||||
if (!ModList.get().isLoaded("cosmeticarmorreworked")) return;
|
if (!ModList.get().isLoaded("cosmeticarmorreworked")) return;
|
||||||
if (cosmeticArmorData == null || cosmeticArmorData.length() <= 2) return;
|
|
||||||
try {
|
try {
|
||||||
lain.mods.cos.impl.inventory.InventoryCosArmor cosInv =
|
lain.mods.cos.impl.inventory.InventoryCosArmor cosInv =
|
||||||
lain.mods.cos.impl.ModObjects.invMan.getCosArmorInventory(player.getUUID());
|
lain.mods.cos.impl.ModObjects.invMan.getCosArmorInventory(player.getUUID());
|
||||||
if (cosInv == null) return;
|
if (cosInv == null) return;
|
||||||
|
|
||||||
Map<Integer, String> storedMap = LocalJsonUtil.StringToEntryMap(cosmeticArmorData);
|
// FIX ANTI-DUPLICATION: ALWAYS clear cosmetic armor slots first to wipe stale
|
||||||
if (storedMap.isEmpty()) return;
|
// data from Minecraft's .dat file, then only restore if DB has valid data.
|
||||||
|
|
||||||
for (int i = 0; i < cosInv.getContainerSize(); i++) {
|
for (int i = 0; i < cosInv.getContainerSize(); i++) {
|
||||||
cosInv.setItem(i, ItemStack.EMPTY);
|
cosInv.setItem(i, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cosmeticArmorData == null || cosmeticArmorData.length() <= 2) return;
|
||||||
|
|
||||||
|
Map<Integer, String> storedMap = LocalJsonUtil.StringToEntryMap(cosmeticArmorData);
|
||||||
|
if (storedMap.isEmpty()) return;
|
||||||
|
|
||||||
for (Map.Entry<Integer, String> entry : storedMap.entrySet()) {
|
for (Map.Entry<Integer, String> entry : storedMap.entrySet()) {
|
||||||
int slot = entry.getKey();
|
int slot = entry.getKey();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -152,21 +152,10 @@ public class ModsSupport {
|
||||||
curiosData = rs.getString("curios_item");
|
curiosData = rs.getString("curios_item");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIX: Check if data is valid BEFORE clearing slots
|
|
||||||
if (curiosData == null || curiosData.length() <= 2) {
|
|
||||||
PlayerSync.LOGGER.debug("Empty curios data for player {}, skipping restore", player.getUUID());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> storedMap = LocalJsonUtil.StringToMap(curiosData);
|
|
||||||
if (storedMap.isEmpty()) {
|
|
||||||
PlayerSync.LOGGER.debug("No curios entries for player {}, skipping restore", player.getUUID());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICuriosItemHandler handler = handlerOpt.get();
|
ICuriosItemHandler handler = handlerOpt.get();
|
||||||
|
|
||||||
// Clear current Curios slots ONLY after confirming valid data exists
|
// FIX ANTI-DUPLICATION: ALWAYS clear curios slots first to wipe stale data
|
||||||
|
// loaded from Minecraft's .dat file, then only restore if DB has valid data.
|
||||||
handler.getCurios().forEach((slotType, stacksHandler) -> {
|
handler.getCurios().forEach((slotType, stacksHandler) -> {
|
||||||
IDynamicStackHandler dynStacks = stacksHandler.getStacks();
|
IDynamicStackHandler dynStacks = stacksHandler.getStacks();
|
||||||
for (int i = 0; i < dynStacks.getSlots(); i++) {
|
for (int i = 0; i < dynStacks.getSlots(); i++) {
|
||||||
|
|
@ -174,6 +163,17 @@ public class ModsSupport {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (curiosData == null || curiosData.length() <= 2) {
|
||||||
|
PlayerSync.LOGGER.debug("Empty curios data for player {}, slots cleared", player.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> storedMap = LocalJsonUtil.StringToMap(curiosData);
|
||||||
|
if (storedMap.isEmpty()) {
|
||||||
|
PlayerSync.LOGGER.debug("No curios entries for player {}, slots cleared", player.getUUID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore each saved item
|
// Restore each saved item
|
||||||
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
||||||
String compositeKey = entry.getKey();
|
String compositeKey = entry.getKey();
|
||||||
|
|
@ -267,7 +267,6 @@ public class ModsSupport {
|
||||||
*/
|
*/
|
||||||
public static void applyCuriosFromData(Player player, String curiosData) {
|
public static void applyCuriosFromData(Player player, String curiosData) {
|
||||||
if (!ModList.get().isLoaded("curios")) return;
|
if (!ModList.get().isLoaded("curios")) return;
|
||||||
if (curiosData == null || curiosData.length() <= 2) return;
|
|
||||||
|
|
||||||
Optional<ICuriosItemHandler> handlerOpt = CuriosApi.getCuriosInventory(player);
|
Optional<ICuriosItemHandler> handlerOpt = CuriosApi.getCuriosInventory(player);
|
||||||
if (handlerOpt.isEmpty()) {
|
if (handlerOpt.isEmpty()) {
|
||||||
|
|
@ -275,12 +274,11 @@ public class ModsSupport {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> storedMap = LocalJsonUtil.StringToMap(curiosData);
|
|
||||||
if (storedMap.isEmpty()) return;
|
|
||||||
|
|
||||||
ICuriosItemHandler handler = handlerOpt.get();
|
ICuriosItemHandler handler = handlerOpt.get();
|
||||||
|
|
||||||
// Clear all curios slots BEFORE restoring
|
// FIX ANTI-DUPLICATION: ALWAYS clear curios slots first, even when DB data is
|
||||||
|
// empty. Without this, stale curios loaded from Minecraft's .dat file (world save)
|
||||||
|
// persist when the DB has no curios data — causing item duplication across servers.
|
||||||
for (Map.Entry<String, ICurioStacksHandler> entry : handler.getCurios().entrySet()) {
|
for (Map.Entry<String, ICurioStacksHandler> entry : handler.getCurios().entrySet()) {
|
||||||
IDynamicStackHandler stacks = entry.getValue().getStacks();
|
IDynamicStackHandler stacks = entry.getValue().getStacks();
|
||||||
for (int i = 0; i < stacks.getSlots(); i++) {
|
for (int i = 0; i < stacks.getSlots(); i++) {
|
||||||
|
|
@ -288,6 +286,12 @@ public class ModsSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no data to restore, we're done (slots already cleared above)
|
||||||
|
if (curiosData == null || curiosData.length() <= 2) return;
|
||||||
|
|
||||||
|
Map<String, String> storedMap = LocalJsonUtil.StringToMap(curiosData);
|
||||||
|
if (storedMap.isEmpty()) return;
|
||||||
|
|
||||||
// Restore items from pre-read data
|
// Restore items from pre-read data
|
||||||
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
for (Map.Entry<String, String> entry : storedMap.entrySet()) {
|
||||||
String compositeKey = entry.getKey();
|
String compositeKey = entry.getKey();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user