From fa39e91a288efcf72b2e57864f1e19288638e939 Mon Sep 17 00:00:00 2001 From: Xwaffle1 Date: Sun, 11 Feb 2024 20:38:19 -0500 Subject: [PATCH] Fixes for configs not merging properly between versions, allows servers to disable the use of a new thread when syncing players pokemon --- .../cobblemonextras/commands/PokeOdds.java | 2 +- .../config/CobblemonExtrasConfig.java | 1 + .../events/CobblemonExtrasEventHandler.java | 12 ++-- .../services/ShowcaseService.java | 24 +++++-- .../thread/SyncPlayersThread.java | 19 ++++++ .../chasem/cobblemonextras/CobblemonExtras.kt | 62 +++++++++++++++++-- .../cobblemonextras/fabric/CobblemonFabric.kt | 1 + forge/build.gradle.kts | 1 + .../forge/event/ForgeEventHandler.java | 13 +++- gradle.properties | 2 +- 10 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 common/src/main/java/dev/chasem/cobblemonextras/thread/SyncPlayersThread.java diff --git a/common/src/main/java/dev/chasem/cobblemonextras/commands/PokeOdds.java b/common/src/main/java/dev/chasem/cobblemonextras/commands/PokeOdds.java index f2bd778..688d2c6 100644 --- a/common/src/main/java/dev/chasem/cobblemonextras/commands/PokeOdds.java +++ b/common/src/main/java/dev/chasem/cobblemonextras/commands/PokeOdds.java @@ -27,7 +27,7 @@ public void register(CommandDispatcher dispatcher) { dispatcher.register(literal("pokeodds") .then(literal("setRate") .requires(source -> CobblemonExtrasPermissions.checkPermission(source, CobblemonExtras.permissions.POKEODDS_PERMISSION)) - .then(argument("rate", FloatArgumentType.floatArg(0.0F, 100.0F)) + .then(argument("rate", FloatArgumentType.floatArg(1.0F, 10000.0F)) .executes(ctx -> setRate(ctx, FloatArgumentType.getFloat(ctx, "rate"))))) .executes(this::execute)); } diff --git a/common/src/main/java/dev/chasem/cobblemonextras/config/CobblemonExtrasConfig.java b/common/src/main/java/dev/chasem/cobblemonextras/config/CobblemonExtrasConfig.java index 6f5926c..d40d041 100644 --- a/common/src/main/java/dev/chasem/cobblemonextras/config/CobblemonExtrasConfig.java +++ b/common/src/main/java/dev/chasem/cobblemonextras/config/CobblemonExtrasConfig.java @@ -38,5 +38,6 @@ public class ShowcaseConfig { public int syncIntervalMinutes = 5; public boolean debug = false; + public boolean async = true; } } diff --git a/common/src/main/java/dev/chasem/cobblemonextras/events/CobblemonExtrasEventHandler.java b/common/src/main/java/dev/chasem/cobblemonextras/events/CobblemonExtrasEventHandler.java index 2c50a64..c399bb9 100644 --- a/common/src/main/java/dev/chasem/cobblemonextras/events/CobblemonExtrasEventHandler.java +++ b/common/src/main/java/dev/chasem/cobblemonextras/events/CobblemonExtrasEventHandler.java @@ -6,13 +6,17 @@ public class CobblemonExtrasEventHandler { public void onPlayerLogin(ServerPlayerEntity player) { - System.out.println(player.getName().getString() + " has logged in!"); - CobblemonExtras.INSTANCE.getShowcaseService().syncPlayers(new ServerPlayerEntity[]{player}, true); +// System.out.println(player.getName().getString() + " has logged in!"); + if (CobblemonExtras.config.showcase.isShowcaseEnabled) { + CobblemonExtras.INSTANCE.getShowcaseService().syncPlayers(new ServerPlayerEntity[]{player}, true); + } } public void onPlayerLogout(ServerPlayerEntity player) { - System.out.println(player.getName().getString() + " has logged out!"); - CobblemonExtras.INSTANCE.getShowcaseService().syncPlayers(new ServerPlayerEntity[]{player}, true); +// System.out.println(player.getName().getString() + " has logged out!"); + if (CobblemonExtras.config.showcase.isShowcaseEnabled) { + CobblemonExtras.INSTANCE.getShowcaseService().syncPlayers(new ServerPlayerEntity[]{player}, true); + } } } diff --git a/common/src/main/java/dev/chasem/cobblemonextras/services/ShowcaseService.java b/common/src/main/java/dev/chasem/cobblemonextras/services/ShowcaseService.java index 4db0deb..c039451 100644 --- a/common/src/main/java/dev/chasem/cobblemonextras/services/ShowcaseService.java +++ b/common/src/main/java/dev/chasem/cobblemonextras/services/ShowcaseService.java @@ -11,6 +11,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonNull; import dev.chasem.cobblemonextras.CobblemonExtras; +import dev.chasem.cobblemonextras.thread.SyncPlayersThread; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import com.google.gson.JsonObject; @@ -26,6 +27,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.LaxRedirectStrategy; +import java.io.EOFException; import java.nio.charset.StandardCharsets; import java.util.*; @@ -42,6 +44,7 @@ public void stop() { Thread tempThread = showcaseThread; showcaseThread = null; tempThread.interrupt(); + CobblemonExtras.INSTANCE.getLogger().info("Showcase Thread Stopped"); } } @@ -58,7 +61,7 @@ public void init() { showcaseThread = new Thread(() -> { while (showcaseThread == Thread.currentThread()) { try { - Thread.sleep(1000L * 60 * CobblemonExtras.config.showcase.syncIntervalMinutes); + Thread.sleep(1000L * 60 * Math.max(CobblemonExtras.config.showcase.syncIntervalMinutes, 2)); // Get Minecraft Server instance MinecraftServer server = Cobblemon.INSTANCE.getImplementation().server(); // Sync all players @@ -96,6 +99,13 @@ public JsonObject getPokemonJson(Pokemon pokemon) { // Form pokemonJson.addProperty("FormName", pokemon.getForm().getName()); + pokemonJson.addProperty("Type1", pokemon.getPrimaryType().getDisplayName().getString()); + if (pokemon.getSecondaryType() != null) { + pokemonJson.addProperty("Type2", pokemon.getSecondaryType().getDisplayName().getString()); + } else { + pokemonJson.add("Type2", JsonNull.INSTANCE); + } + // Movesets JsonObject moveJson = pokemonJson.getAsJsonObject("MoveSet"); JsonElement moveSet0 = moveJson.get("MoveSet0"); @@ -132,12 +142,15 @@ public JsonObject getPokemonJson(Pokemon pokemon) { public JsonObject getPlayerJson(ServerPlayerEntity player) { // Obtain cobblemon pc data - PlayerPartyStore party = Cobblemon.INSTANCE.getStorage().getParty(player); + PlayerPartyStore party = null; PCStore pc = null; try { + party = Cobblemon.INSTANCE.getStorage().getParty(player); pc = Cobblemon.INSTANCE.getStorage().getPC(player.getUuid()); } catch (NoPokemonStoreException e) { // System.out.println("No PCStore found for player, skipping sync - " + player.getDisplayName().getString()); + } catch (Exception exc) { + return null; } JsonObject playerData = new JsonObject(); playerData.addProperty("uuid", player.getUuid().toString()); @@ -179,10 +192,9 @@ public JsonObject getPlayerJson(ServerPlayerEntity player) { } public void syncPlayers(ServerPlayerEntity[] player, boolean async) { - if (async) { - new Thread(() -> { - syncPlayers(player); - }).start(); + if (async && CobblemonExtras.config.showcase.async) { + SyncPlayersThread thread = new SyncPlayersThread(player); + thread.start(); } else { syncPlayers(player); } diff --git a/common/src/main/java/dev/chasem/cobblemonextras/thread/SyncPlayersThread.java b/common/src/main/java/dev/chasem/cobblemonextras/thread/SyncPlayersThread.java new file mode 100644 index 0000000..1921a21 --- /dev/null +++ b/common/src/main/java/dev/chasem/cobblemonextras/thread/SyncPlayersThread.java @@ -0,0 +1,19 @@ +package dev.chasem.cobblemonextras.thread; + +import dev.chasem.cobblemonextras.CobblemonExtras; +import net.minecraft.server.network.ServerPlayerEntity; + +public class SyncPlayersThread extends Thread { + ServerPlayerEntity[] players; + public SyncPlayersThread(ServerPlayerEntity[] players) { + super("CobblemonExtrasSyncPlayersThread"); + this.players = players; + } + + @Override + public void run() { + CobblemonExtras.INSTANCE.getShowcaseService().syncPlayers(players); + this.interrupt(); + + } +} diff --git a/common/src/main/kotlin/dev/chasem/cobblemonextras/CobblemonExtras.kt b/common/src/main/kotlin/dev/chasem/cobblemonextras/CobblemonExtras.kt index fc900c7..438fc31 100644 --- a/common/src/main/kotlin/dev/chasem/cobblemonextras/CobblemonExtras.kt +++ b/common/src/main/kotlin/dev/chasem/cobblemonextras/CobblemonExtras.kt @@ -1,5 +1,8 @@ package dev.chasem.cobblemonextras +import com.google.gson.JsonElement +import com.google.gson.JsonObject +import com.google.gson.JsonParser import com.mojang.brigadier.CommandDispatcher import dev.chasem.cobblemonextras.commands.* import dev.chasem.cobblemonextras.config.CobblemonExtrasConfig @@ -9,11 +12,11 @@ import dev.chasem.cobblemonextras.services.ShowcaseService import net.minecraft.command.CommandRegistryAccess import net.minecraft.server.command.CommandManager import net.minecraft.server.command.ServerCommandSource +import org.apache.logging.log4j.LogManager +import org.apache.logging.log4j.Logger import java.io.File import java.io.FileReader import java.io.FileWriter -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; object CobblemonExtras { @@ -25,10 +28,15 @@ object CobblemonExtras { val eventHandler = CobblemonExtrasEventHandler() fun initialize() { - System.out.println("CobblemonExtras - Initialized") + getLogger().info("CobblemonExtras - Initialized") loadConfig() // must load before permissions so perms use default permission level. this.permissions = CobblemonExtrasPermissions() showcaseService.init() + if (config.showcase.async) { + getLogger().info("CobblemonExtras - Showcase Async Enabled") + } else { + getLogger().info("CobblemonExtras - Showcase Async Disabled") + } } fun onShutdown() { @@ -50,7 +58,30 @@ object CobblemonExtras { if (configFile.exists()) { try { val fileReader = FileReader(configFile) - config = CobblemonExtrasConfig.GSON.fromJson(fileReader, CobblemonExtrasConfig::class.java) +// var loadedConfig = CobblemonExtrasConfig.GSON.fromJson(fileReader, CobblemonExtrasConfig::class.java) + + + // Create a default config instance + val defaultConfig = CobblemonExtrasConfig() + val defaultConfigJson: String = CobblemonExtrasConfig.GSON.toJson(defaultConfig) + + + val fileConfigElement: JsonElement = JsonParser.parseReader(fileReader) + + + // Convert default config JSON string to JsonElement + val defaultConfigElement: JsonElement = JsonParser.parseString(defaultConfigJson) + + + // Merge default config with the file config + val mergedConfigElement: JsonElement = mergeConfigs(defaultConfigElement.getAsJsonObject(), fileConfigElement.getAsJsonObject()) + + + // Deserialize the merged JsonElement back to CobblemonExtrasConfig + val finalConfig: CobblemonExtrasConfig = CobblemonExtrasConfig.GSON.fromJson(mergedConfigElement, CobblemonExtrasConfig::class.java) + + this.config = finalConfig; + fileReader.close() } catch (e: Exception) { System.err.println("[CobblemonExtras] Failed to load the config! Using default config as fallback") @@ -63,6 +94,29 @@ object CobblemonExtras { saveConfig() } + private fun mergeConfigs(defaultConfig: JsonObject, fileConfig: JsonObject): JsonElement { + // For every entry in the default config, check if it exists in the file config + getLogger().info("Checking for config merge."); + var merged = false; + for (key in defaultConfig.keySet()) { + if (!fileConfig.has(key)) { + // If the file config does not have the key, add it from the default config + fileConfig.add(key, defaultConfig.get(key)) + getLogger().info("[CobblemonExtras] $key not found in file config, adding from default."); + merged = true; + } else { + // If it's a nested object, recursively merge it + if (defaultConfig.get(key).isJsonObject() && fileConfig.get(key).isJsonObject()) { + mergeConfigs(defaultConfig.getAsJsonObject(key), fileConfig.getAsJsonObject(key)) + } + } + } + if (merged) { + getLogger().info("[CobblemonExtras] Successfully merged config."); + } + return fileConfig + } + private fun saveConfig() { try { val configFileLoc = System.getProperty("user.dir") + File.separator + "config" + File.separator + "cobblemonextras" + File.separator + "config.json"; diff --git a/fabric/src/main/kotlin/dev/chasem/cobblemonextras/fabric/CobblemonFabric.kt b/fabric/src/main/kotlin/dev/chasem/cobblemonextras/fabric/CobblemonFabric.kt index c1778ab..08df19c 100644 --- a/fabric/src/main/kotlin/dev/chasem/cobblemonextras/fabric/CobblemonFabric.kt +++ b/fabric/src/main/kotlin/dev/chasem/cobblemonextras/fabric/CobblemonFabric.kt @@ -12,6 +12,7 @@ class CobblemonFabric : ModInitializer { CobblemonExtras.initialize(); CommandRegistrationCallback.EVENT.register(CobblemonExtras::registerCommands) ServerLifecycleEvents.SERVER_STOPPING.register { CobblemonExtras.onShutdown() } + ServerLifecycleEvents.SERVER_STOPPED.register { CobblemonExtras.onShutdown() } ServerPlayConnectionEvents.JOIN.register { serverPlayNetworkHandler, _, _ -> CobblemonExtras.eventHandler.onPlayerLogin(serverPlayNetworkHandler.getPlayer()) } diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 7f7ed69..57999cc 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -63,6 +63,7 @@ tasks { exclude("architectury-common.accessWidener") relocate ("com.ibm.icu", "com.cobblemon.mod.relocations.ibm.icu") relocate("org.apache.http", "dev.chasem.apache.http") + relocate("org.apache.commons", "dev.chasem.apache.commons") } processResources { diff --git a/forge/src/main/java/dev/chasem/cobblemonextras/forge/event/ForgeEventHandler.java b/forge/src/main/java/dev/chasem/cobblemonextras/forge/event/ForgeEventHandler.java index c6e79a3..1acd09f 100644 --- a/forge/src/main/java/dev/chasem/cobblemonextras/forge/event/ForgeEventHandler.java +++ b/forge/src/main/java/dev/chasem/cobblemonextras/forge/event/ForgeEventHandler.java @@ -4,7 +4,9 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.event.server.ServerStoppedEvent; import net.minecraftforge.event.server.ServerStoppingEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; public class ForgeEventHandler { @@ -13,8 +15,15 @@ public void register() { CobblemonExtras.INSTANCE.getLogger().info("Registered CobblemonExtras Forge Event Handler"); } - @SubscribeEvent - public void onServerStop(ServerStoppingEvent event) { + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onServerStopped(ServerStoppedEvent event) { + CobblemonExtras.INSTANCE.getLogger().error("CobblemonExtras Server Stopped"); + CobblemonExtras.INSTANCE.onShutdown(); + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onServerStopping(ServerStoppingEvent event) { + CobblemonExtras.INSTANCE.getLogger().error("Server stopping, shutting down CobblemonExtras"); CobblemonExtras.INSTANCE.onShutdown(); } diff --git a/gradle.properties b/gradle.properties index 6843ee1..e5ff12d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ luckperms_version=5.4 mod_id=cobblemonextras -mod_version=1.2.0 +mod_version=1.2.3 snapshot=false fabric.loom.multiProjectOptimisation=true \ No newline at end of file