From 5c1cd2b5eae3a9267a73c057ed15631fcb8d3703 Mon Sep 17 00:00:00 2001 From: M4RC0Sx Date: Sun, 30 Aug 2026 01:15:20 +0200 Subject: [PATCH] fix: preserve Pokemon data through the pool, repair the /wt alias and make all command feedback configurable --- .../polymeta/wondertrade/WonderTrade.java | 4 +-- .../wondertrade/commands/RegeneratePool.java | 5 ++- .../polymeta/wondertrade/commands/Reload.java | 6 ++-- .../polymeta/wondertrade/commands/Trade.java | 16 +++++---- .../wondertrade/configuration/BaseConfig.java | 15 +++++++++ .../wondertrade/configuration/Pool.java | 4 ++- .../polymeta/wondertrade/gui/PoolGui.java | 6 ++-- .../wondertrade/util/PokemonCodec.java | 33 +++++++++++++++++++ .../polymeta/wondertrade/util/TradeUtil.java | 5 ++- 9 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 common/src/main/java/io/github/polymeta/wondertrade/util/PokemonCodec.java diff --git a/common/src/main/java/io/github/polymeta/wondertrade/WonderTrade.java b/common/src/main/java/io/github/polymeta/wondertrade/WonderTrade.java index 7bfe7bc..ce05ee8 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/WonderTrade.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/WonderTrade.java @@ -2,7 +2,6 @@ import com.cobblemon.mod.common.Cobblemon; import com.cobblemon.mod.common.api.pokemon.PokemonProperties; -import com.cobblemon.mod.common.api.pokemon.PokemonPropertyExtractor; import com.cobblemon.mod.common.pokemon.Pokemon; import dev.architectury.event.events.common.CommandRegistrationEvent; import dev.architectury.event.events.common.LifecycleEvent; @@ -11,6 +10,7 @@ import io.github.polymeta.wondertrade.commands.Trade; import io.github.polymeta.wondertrade.configuration.BaseConfig; import io.github.polymeta.wondertrade.configuration.Pool; +import io.github.polymeta.wondertrade.util.PokemonCodec; import net.kyori.adventure.text.minimessage.MiniMessage; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -101,7 +101,7 @@ public static void regeneratePool(int size) logger.error("Failed to regenerate pool! WonderTrade is now in a potentially broken state. Please review the config and try again."); return; } - pool.pokemon.add(pokemon.createPokemonProperties(PokemonPropertyExtractor.ALL).asString(" ")); + pool.pokemon.add(PokemonCodec.encode(pokemon)); } savePool(); regenerating.set(false); diff --git a/common/src/main/java/io/github/polymeta/wondertrade/commands/RegeneratePool.java b/common/src/main/java/io/github/polymeta/wondertrade/commands/RegeneratePool.java index 7e74fe8..620c5b0 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/commands/RegeneratePool.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/commands/RegeneratePool.java @@ -11,7 +11,6 @@ import io.github.polymeta.wondertrade.WonderTrade; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; -import net.minecraft.network.chat.Component; public class RegeneratePool { private static final Command Execute = (context) -> Regenerate(context, IntegerArgumentType.getInteger(context, "size")); @@ -20,11 +19,11 @@ public class RegeneratePool { private static int Regenerate(CommandContext context, int size) { if(WonderTrade.regenerating.get()) { - context.getSource().sendSystemMessage(Component.literal("The WonderTrade pool is being regenerated!")); + context.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerating(context.getSource().registryAccess())); return Command.SINGLE_SUCCESS; } WonderTrade.regeneratePool(size); - context.getSource().sendSystemMessage(Component.literal("WonderTrade pool regenerated!")); + context.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerated(context.getSource().registryAccess())); return size; } diff --git a/common/src/main/java/io/github/polymeta/wondertrade/commands/Reload.java b/common/src/main/java/io/github/polymeta/wondertrade/commands/Reload.java index 9bceb66..97d37b0 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/commands/Reload.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/commands/Reload.java @@ -8,20 +8,18 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.github.polymeta.wondertrade.WonderTrade; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.network.chat.Component; public class Reload { public static void register(CommandDispatcher dispatcher) { - var regenCommand = dispatcher.register( + dispatcher.register( LiteralArgumentBuilder.literal("reloadwondertrade") .requires(req -> Cobblemon.INSTANCE.getPermissionValidator().hasPermission(req, new CobblemonPermission("wondertrade.command.reload", PermissionLevel.ALL_COMMANDS))) .executes(ctx -> { WonderTrade.loadConfig(); - ctx.getSource().sendSystemMessage(Component.literal("Config reloaded, check console for errors")); + ctx.getSource().sendSystemMessage(WonderTrade.config.messages.configReloaded(ctx.getSource().registryAccess())); return Command.SINGLE_SUCCESS; }) ); - dispatcher.register(LiteralArgumentBuilder.literal("regeneratepool").redirect(regenCommand)); } } diff --git a/common/src/main/java/io/github/polymeta/wondertrade/commands/Trade.java b/common/src/main/java/io/github/polymeta/wondertrade/commands/Trade.java index 2e563cd..ad997e0 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/commands/Trade.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/commands/Trade.java @@ -15,7 +15,6 @@ import io.github.polymeta.wondertrade.util.TradeUtil; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; -import net.minecraft.network.chat.Component; public class Trade { @@ -30,7 +29,7 @@ public static void register(CommandDispatcher dispatcher) { .then(Commands.literal("pool") .executes(ctx -> { if(WonderTrade.regenerating.get()) { - ctx.getSource().sendSystemMessage(Component.literal("The WonderTrade pool is being regenerated!")); + ctx.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerating(ctx.getSource().registryAccess())); return Command.SINGLE_SUCCESS; } var player = ctx.getSource().getPlayerOrException(); @@ -41,7 +40,7 @@ public static void register(CommandDispatcher dispatcher) { .requires(req -> Cobblemon.INSTANCE.getPermissionValidator().hasPermission(req, new CobblemonPermission("wondertrade.command.trade.base", PermissionLevel.NONE))) .executes(ctx -> { if(WonderTrade.regenerating.get()) { - ctx.getSource().sendSystemMessage(Component.literal("The WonderTrade pool is being regenerated!")); + ctx.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerating(ctx.getSource().registryAccess())); return Command.SINGLE_SUCCESS; } var player = ctx.getSource().getPlayerOrException(); @@ -56,12 +55,17 @@ public static void register(CommandDispatcher dispatcher) { return 1; }) ); - dispatcher.register(LiteralArgumentBuilder.literal("wt").redirect(tradeCommand)); + // A redirect only forwards further arguments, so the alias needs the target's + // own command to answer a bare "/wt". + dispatcher.register(LiteralArgumentBuilder.literal("wt") + .requires(tradeCommand.getRequirement()) + .executes(tradeCommand.getCommand()) + .redirect(tradeCommand)); } private static final Command Execute = context -> { if(WonderTrade.regenerating.get()) { - context.getSource().sendSystemMessage(Component.literal("The WonderTrade pool is being regenerated!")); + context.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerating(context.getSource().registryAccess())); return Command.SINGLE_SUCCESS; } var slot = PartySlotArgumentType.Companion.getPokemon(context, "slot"); @@ -85,7 +89,7 @@ public static void register(CommandDispatcher dispatcher) { private static final Command ExecuteWithConfirm = context -> { if(WonderTrade.regenerating.get()) { - context.getSource().sendSystemMessage(Component.literal("The WonderTrade pool is being regenerated!")); + context.getSource().sendSystemMessage(WonderTrade.config.messages.poolRegenerating(context.getSource().registryAccess())); return Command.SINGLE_SUCCESS; } var slot = PartySlotArgumentType.Companion.getPokemon(context, "slot"); diff --git a/common/src/main/java/io/github/polymeta/wondertrade/configuration/BaseConfig.java b/common/src/main/java/io/github/polymeta/wondertrade/configuration/BaseConfig.java index 2769511..bb384a9 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/configuration/BaseConfig.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/configuration/BaseConfig.java @@ -79,6 +79,9 @@ public static class MessageConfig { public String successFeedback = "[WonderTrade] Successfully traded!"; public String broadcastPokemonAdded = "[WonderTrade] () got added to the wondertrade pool!"; public String broadcastShinyPokemonAdded = "[WonderTrade] Shiny () got added to the wondertrade pool!"; + public String poolRegenerating = "[WonderTrade] The pool is being regenerated!"; + public String poolRegenerated = "[WonderTrade] Pool regenerated!"; + public String configReloaded = "[WonderTrade] Config reloaded, check the console for errors."; public Component wonderTradeFeedback(Pokemon pokemon, int slot, RegistryAccess registryAccess) { @@ -116,5 +119,17 @@ public Component broadcastPokemon(Pokemon pokemon, RegistryAccess registryAccess public Component pokemonNotAllowed(RegistryAccess registryAccess) { return TextUtil.styledText(this.pokemonNotAllowed, registryAccess); } + + public Component poolRegenerating(RegistryAccess registryAccess) { + return TextUtil.styledText(this.poolRegenerating, registryAccess); + } + + public Component poolRegenerated(RegistryAccess registryAccess) { + return TextUtil.styledText(this.poolRegenerated, registryAccess); + } + + public Component configReloaded(RegistryAccess registryAccess) { + return TextUtil.styledText(this.configReloaded, registryAccess); + } } } diff --git a/common/src/main/java/io/github/polymeta/wondertrade/configuration/Pool.java b/common/src/main/java/io/github/polymeta/wondertrade/configuration/Pool.java index 3d446ed..207f07c 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/configuration/Pool.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/configuration/Pool.java @@ -1,8 +1,10 @@ package io.github.polymeta.wondertrade.configuration; +import com.google.gson.JsonElement; + import java.util.ArrayList; import java.util.List; public class Pool { - public List pokemon = new ArrayList<>(); + public List pokemon = new ArrayList<>(); } diff --git a/common/src/main/java/io/github/polymeta/wondertrade/gui/PoolGui.java b/common/src/main/java/io/github/polymeta/wondertrade/gui/PoolGui.java index dc47700..adf20a8 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/gui/PoolGui.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/gui/PoolGui.java @@ -1,9 +1,9 @@ package io.github.polymeta.wondertrade.gui; -import com.cobblemon.mod.common.api.pokemon.PokemonProperties; import com.cobblemon.mod.common.item.PokemonItem; import io.github.polymeta.wondertrade.WonderTrade; import io.github.polymeta.wondertrade.util.GuiUtil; +import io.github.polymeta.wondertrade.util.PokemonCodec; import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; @@ -48,8 +48,8 @@ private void setupContainer() var pageContent = WonderTrade.pool.pokemon.stream() .skip((long) this.pageNumber * this.pageSize) .limit(this.pageSize) - .map(PokemonProperties.Companion::parse) - .map(PokemonItem::from) + .map(PokemonCodec::decode) + .map(pokemon -> PokemonItem.from(pokemon, 1)) .toList(); for(int i = 0; i < pageContent.size(); i++) diff --git a/common/src/main/java/io/github/polymeta/wondertrade/util/PokemonCodec.java b/common/src/main/java/io/github/polymeta/wondertrade/util/PokemonCodec.java new file mode 100644 index 0000000..79963ab --- /dev/null +++ b/common/src/main/java/io/github/polymeta/wondertrade/util/PokemonCodec.java @@ -0,0 +1,33 @@ +package io.github.polymeta.wondertrade.util; + +import com.cobblemon.mod.common.api.pokemon.PokemonProperties; +import com.cobblemon.mod.common.pokemon.Pokemon; +import com.google.gson.JsonElement; +import com.mojang.serialization.JsonOps; + +import java.util.UUID; + +/** + * Pool entries use Cobblemon's own codec. A property string cannot round-trip a + * regional form: applying properties recomputes aspects from species features + * instead of restoring them, so the pool reset forms back to base (issue #8). + */ +public final class PokemonCodec { + + private PokemonCodec() {} + + public static JsonElement encode(Pokemon pokemon) { + return Pokemon.getCODEC().encodeStart(JsonOps.INSTANCE, pokemon).getOrThrow(); + } + + /** Strings are pool entries written before the codec; parsed the old way. */ + public static Pokemon decode(JsonElement entry) { + if (entry.isJsonPrimitive()) { + return PokemonProperties.Companion.parse(entry.getAsString()).create(); + } + var pokemon = Pokemon.getCODEC().parse(JsonOps.INSTANCE, entry).getOrThrow(); + // The codec restores the depositor's UUID, which must not reach a second party. + pokemon.setUuid(UUID.randomUUID()); + return pokemon; + } +} diff --git a/common/src/main/java/io/github/polymeta/wondertrade/util/TradeUtil.java b/common/src/main/java/io/github/polymeta/wondertrade/util/TradeUtil.java index bca46c4..3c034a6 100644 --- a/common/src/main/java/io/github/polymeta/wondertrade/util/TradeUtil.java +++ b/common/src/main/java/io/github/polymeta/wondertrade/util/TradeUtil.java @@ -4,7 +4,6 @@ import com.cobblemon.mod.common.api.permission.CobblemonPermission; import com.cobblemon.mod.common.api.permission.PermissionLevel; import com.cobblemon.mod.common.api.pokemon.PokemonProperties; -import com.cobblemon.mod.common.api.pokemon.PokemonPropertyExtractor; import com.cobblemon.mod.common.pokemon.Pokemon; import io.github.polymeta.wondertrade.WonderTrade; import net.minecraft.network.chat.Component; @@ -41,7 +40,7 @@ public static void doWonderTrade(ServerPlayer player, Pokemon slot) var playerParty = Cobblemon.INSTANCE.getStorage().getParty(player); var wonderPoke = WonderTrade.pool.pokemon.remove(rng.nextInt(WonderTrade.pool.pokemon.size())); var tookPoke = playerParty.remove(slot); - var pokeAdded = playerParty.add(PokemonProperties.Companion.parse(wonderPoke).create()); + var pokeAdded = playerParty.add(PokemonCodec.decode(wonderPoke)); if(WonderTrade.config.adjustNewPokemonToLevelRange) { var level = slot.getLevel(); if(level > WonderTrade.config.poolMaxLevel) { @@ -51,7 +50,7 @@ else if (level < WonderTrade.config.poolMinLevel) { slot.setLevel(WonderTrade.config.poolMinLevel); } } - WonderTrade.pool.pokemon.add(slot.createPokemonProperties(PokemonPropertyExtractor.ALL).asString(" ")); + WonderTrade.pool.pokemon.add(PokemonCodec.encode(slot)); WonderTrade.savePool(); if(WonderTrade.config.cooldownEnabled && !canBypass) { playersOnCooldown.add(player.getUUID());