From 736d467a765ec31c4a89d747d8945687e2f5b51c Mon Sep 17 00:00:00 2001 From: Charles445 Date: Thu, 13 Jan 2022 18:15:52 -0600 Subject: [PATCH] BattleTowers, Charm Battle Towers Remove Unloaded Tower Destroyers, removes tower destroyers from unloaded worlds Enforce Tower Destruction Config, prevents clients from changing the tower destruction config Charm Disable Magnetic Enchantment, disables the effect of Magnetic without unregistering it to avoid packet issues, use this if the enchantment is broken --- .../rltweaker/config/ConfigBattleTowers.java | 12 ++ .../rltweaker/config/ConfigCharm.java | 9 ++ .../handler/BattleTowersHandler.java | 105 +++++++++++++----- .../rltweaker/handler/CharmHandler.java | 36 ++++-- .../rltweaker/handler/MinecraftHandler.java | 2 +- .../reflect/BattleTowersReflect.java | 31 +++++- 6 files changed, 156 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/charles445/rltweaker/config/ConfigBattleTowers.java b/src/main/java/com/charles445/rltweaker/config/ConfigBattleTowers.java index 8ca2a2f..20d160e 100644 --- a/src/main/java/com/charles445/rltweaker/config/ConfigBattleTowers.java +++ b/src/main/java/com/charles445/rltweaker/config/ConfigBattleTowers.java @@ -153,5 +153,17 @@ public class ConfigBattleTowers @RLConfig.RLCraftTwoNine("false") public boolean consistentTowerGeneration = false; + @Config.Comment("Removes tower destroyers from unloaded worlds. Prevents potential leaks and crashes.") + @Config.Name("Remove Unloaded Tower Destroyers") + @RLConfig.ImprovementsOnly("true") + @RLConfig.RLCraftTwoEightTwo("true") + @RLConfig.RLCraftTwoNine("true") + public boolean removeUnloadedTowerDestroyers = true; + @Config.Comment("Prevents clients from changing the tower destruction config") + @Config.Name("Enforce Tower Destruction Config") + @RLConfig.ImprovementsOnly("true") + @RLConfig.RLCraftTwoEightTwo("true") + @RLConfig.RLCraftTwoNine("true") + public boolean enforceTowerDestructionConfig = true; } diff --git a/src/main/java/com/charles445/rltweaker/config/ConfigCharm.java b/src/main/java/com/charles445/rltweaker/config/ConfigCharm.java index 5471155..992e9e1 100644 --- a/src/main/java/com/charles445/rltweaker/config/ConfigCharm.java +++ b/src/main/java/com/charles445/rltweaker/config/ConfigCharm.java @@ -35,4 +35,13 @@ public class ConfigCharm @RLConfig.RLCraftTwoEightTwo("true") @RLConfig.RLCraftTwoNine("true") public boolean fixChargedEmeraldCrash = true; + + @Config.Comment("Disables the effect of Magnetic without unregistering it to avoid packet issues. Do this if you experience dupes with the enchantment.") + @Config.Name("Disable Magnetic Enchantment") + @Config.RequiresMcRestart + @RLConfig.ImprovementsOnly("false") + @RLConfig.RLCraftTwoEightTwo("false") + @RLConfig.RLCraftTwoNine("false") + public boolean disableMagneticEnchantment = false; + } diff --git a/src/main/java/com/charles445/rltweaker/handler/BattleTowersHandler.java b/src/main/java/com/charles445/rltweaker/handler/BattleTowersHandler.java index 852781d..41dbe83 100644 --- a/src/main/java/com/charles445/rltweaker/handler/BattleTowersHandler.java +++ b/src/main/java/com/charles445/rltweaker/handler/BattleTowersHandler.java @@ -7,7 +7,6 @@ import com.charles445.rltweaker.RLTweaker; import com.charles445.rltweaker.config.ModConfig; -import com.charles445.rltweaker.debug.DebugUtil; import com.charles445.rltweaker.reflect.BattleTowersReflect; import com.charles445.rltweaker.util.AIUtil; import com.charles445.rltweaker.util.CompatUtil; @@ -44,6 +43,8 @@ public class BattleTowersHandler BattleTowersReflect reflector; + public int cachedTowerDestroyerConfig; + public BattleTowersHandler() { try @@ -67,6 +68,8 @@ public BattleTowersHandler() generator = CompatUtil.tryWrapWorldGenerator(generator, reflector.c_WorldGenHandler); } + cachedTowerDestroyerConfig = reflector.getTowerDestroyerEnabled(); + MinecraftForge.EVENT_BUS.register(this); } catch(Exception e) @@ -296,44 +299,59 @@ else if(golem.motionZ < -golemSpeedCap) @SubscribeEvent(priority = EventPriority.HIGH) public void onTick(TickEvent.WorldTickEvent tick) { - //Tower Explosion Credit + if(tick.phase == TickEvent.Phase.START && ModConfig.server.battletowers.enforceTowerDestructionConfig) + { + //Enforce config + try + { + if(reflector.getTowerDestroyerEnabled() != cachedTowerDestroyerConfig) + { + RLTweaker.logger.info("Fixing Tower Destroyer Config"); + reflector.setTowerDestroyerEnabled(cachedTowerDestroyerConfig); + } + } + catch (IllegalArgumentException | IllegalAccessException e) + { + ErrorUtil.logSilent("BT enforceTowerDestructionConfig Invocation"); + } + } - if(!ModConfig.server.battletowers.towerExplosionNoCredit) - return; + //Tower Explosion Credit - if(System.currentTimeMillis() > tickedTime) + if(ModConfig.server.battletowers.towerExplosionNoCredit) { - tickedTime = System.currentTimeMillis() + 14000L; // its a fourteen second timer ZZZ - - //It takes 15000L for the tower destroyer to run its first explosion, so this will intervene before then - //If the game gets paused while these timers are counting down, due to priority this will run before the tower starts exploding - //Really shouldn't be pausing the game during these anyway... - - try + if(System.currentTimeMillis() > tickedTime) { - Set towerDestroyers = reflector.getTowerDestroyers(); + tickedTime = System.currentTimeMillis() + 14000L; // its a fourteen second timer ZZZ + + //It takes 15000L for the tower destroyer to run its first explosion, so this will intervene before then + //If the game gets paused while these timers are counting down, due to priority this will run before the tower starts exploding + //Really shouldn't be pausing the game during these anyway... - if(towerDestroyers!=null && towerDestroyers.size() > 0) + try { - Iterator iterator = towerDestroyers.iterator(); - while(iterator.hasNext()) + Set towerDestroyers = reflector.getTowerDestroyers(); + + if(towerDestroyers!=null && towerDestroyers.size() > 0) { - Object destroyer = iterator.next(); - if(destroyer!=null) + Iterator iterator = towerDestroyers.iterator(); + while(iterator.hasNext()) { - //TODO is null safe? There have been some recoil issues with null targets, does this apply here? - reflector.setDestroyerPlayer(destroyer, null); + Object destroyer = iterator.next(); + if(destroyer!=null) + { + //TODO is null safe? There have been some recoil issues with null targets, does this apply here? + reflector.setDestroyerPlayer(destroyer, null); + } } } } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) + { + //Just quietly put it in the rlerrorreport and call it a day + ErrorUtil.logSilent("BT getTowerDestroyers Invocation"); + } } - catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) - { - //Just quietly put it in the rlerrorreport and call it a day - ErrorUtil.logSilent("BT getTowerDestroyers Invocation"); - return; - } - } } @@ -354,6 +372,39 @@ public void onApplyPotion(PotionApplicableEvent event) } } + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) + { + if(event.getWorld() != null) + { + if(ModConfig.server.battletowers.removeUnloadedTowerDestroyers) + { + try + { + Set towerDestroyers = reflector.getTowerDestroyers(); + if(towerDestroyers!=null && towerDestroyers.size() > 0) + { + Iterator iterator = towerDestroyers.iterator(); + while(iterator.hasNext()) + { + Object destroyer = iterator.next(); + if(destroyer!=null && !reflector.getDestroyerDeleteMe(destroyer)) + { + RLTweaker.logger.info("Removing tower destroyer for unloaded world"); + reflector.setDestroyerDeleteMe(destroyer, true); + } + } + } + } + catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) + { + // TODO Auto-generated catch block + ErrorUtil.logSilent("BT removeUnloadedTowerDestroyers Invocation"); + } + } + } + } + public boolean isDimensionWhitelisted(World world) { if(!ModConfig.server.battletowers.dimensionBlacklistEnabled) diff --git a/src/main/java/com/charles445/rltweaker/handler/CharmHandler.java b/src/main/java/com/charles445/rltweaker/handler/CharmHandler.java index 413c3fe..4abe423 100644 --- a/src/main/java/com/charles445/rltweaker/handler/CharmHandler.java +++ b/src/main/java/com/charles445/rltweaker/handler/CharmHandler.java @@ -12,6 +12,8 @@ import com.charles445.rltweaker.RLTweaker; import com.charles445.rltweaker.config.ModConfig; +import com.charles445.rltweaker.util.CompatUtil; +import com.charles445.rltweaker.util.CriticalException; import com.charles445.rltweaker.util.ErrorUtil; import com.charles445.rltweaker.util.ModNames; import com.charles445.rltweaker.util.ReflectUtil; @@ -45,14 +47,32 @@ public class CharmHandler public CharmHandler() { - if(ModConfig.server.charm.fixIncorrectItemEnchantments) - fixIncorrectItemEnchantments(); - - if(ModConfig.server.charm.fixSalvageTrade) - fixSalvageTrade(); - - if(ModConfig.server.charm.fixChargedEmeraldCrash) - fixChargedEmeraldCrash(); + try + { + if(ModConfig.server.charm.fixIncorrectItemEnchantments) + fixIncorrectItemEnchantments(); + + if(ModConfig.server.charm.fixSalvageTrade) + fixSalvageTrade(); + + if(ModConfig.server.charm.fixChargedEmeraldCrash) + fixChargedEmeraldCrash(); + + if(ModConfig.server.charm.disableMagneticEnchantment) + { + RLTweaker.logger.info("Disabling the Magnetic enchantment"); + CompatUtil.findAndRemoveHandlerFromEventBus("svenhjol.charm.enchanting.feature.Magnetic"); + } + } + catch (Exception e) + { + RLTweaker.logger.error("Failed to setup CharmHandler!", e); + ErrorUtil.logSilent("Charm Critical Setup Failure"); + + //Crash on Critical + if(e instanceof CriticalException) + throw new RuntimeException(e); + } //No event bus registration yet } diff --git a/src/main/java/com/charles445/rltweaker/handler/MinecraftHandler.java b/src/main/java/com/charles445/rltweaker/handler/MinecraftHandler.java index e1e16e7..d232817 100644 --- a/src/main/java/com/charles445/rltweaker/handler/MinecraftHandler.java +++ b/src/main/java/com/charles445/rltweaker/handler/MinecraftHandler.java @@ -257,7 +257,7 @@ private List containedChunks(int xIn1, int zIn1, int xIn2, int zIn2) //Capabilities - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.LOW) public void onAttachCapability(AttachCapabilitiesEvent event) { //Find player diff --git a/src/main/java/com/charles445/rltweaker/reflect/BattleTowersReflect.java b/src/main/java/com/charles445/rltweaker/reflect/BattleTowersReflect.java index 4b5b30d..1d6b95e 100644 --- a/src/main/java/com/charles445/rltweaker/reflect/BattleTowersReflect.java +++ b/src/main/java/com/charles445/rltweaker/reflect/BattleTowersReflect.java @@ -24,14 +24,17 @@ public class BattleTowersReflect public final Class c_AS_BattleTowersCore; public final Method m_AS_BattleTowersCore_getTowerDestroyers; public final Field f_AS_BattleTowersCore_instance; + public final Object o_AS_BattleTowersCore_instance; public final Field f_AS_BattleTowersCore_minDistanceFromSpawn; public final Field f_AS_BattleTowersCore_minDistanceBetweenTowers; + public final Field f_AS_BattleTowersCore_towerDestroyerEnabled; public final Class c_AS_EntityGolem; public final Method m_AS_EntityGolem_getIsDormant; public final Class c_AS_TowerDestroyer; public final Field f_AS_TowerDestroyer_player; + public final Field f_AS_TowerDestroyer_deleteMe; public final Class c_AS_EntityGolemFireball; public final Field f_AS_EntityGolemFireball_shooterEntity; @@ -53,7 +56,6 @@ public class BattleTowersReflect public final Class c_WorldGenHandler$WorldHandle; public final Field f_WorldGenHandler$WorldHandle_disableGenerationHook; - //Lycanites Mobs private boolean isLycanitesAvailable; @Nullable @@ -80,14 +82,17 @@ public BattleTowersReflect() throws Exception c_AS_BattleTowersCore = Class.forName("atomicstryker.battletowers.common.AS_BattleTowersCore"); m_AS_BattleTowersCore_getTowerDestroyers = ReflectUtil.findMethod(c_AS_BattleTowersCore, "getTowerDestroyers"); f_AS_BattleTowersCore_instance = ReflectUtil.findField(c_AS_BattleTowersCore, "instance"); + o_AS_BattleTowersCore_instance = f_AS_BattleTowersCore_instance.get(null); f_AS_BattleTowersCore_minDistanceFromSpawn = ReflectUtil.findField(c_AS_BattleTowersCore, "minDistanceFromSpawn"); f_AS_BattleTowersCore_minDistanceBetweenTowers = ReflectUtil.findField(c_AS_BattleTowersCore, "minDistanceBetweenTowers"); + f_AS_BattleTowersCore_towerDestroyerEnabled = ReflectUtil.findField(c_AS_BattleTowersCore, "towerDestroyerEnabled"); c_AS_EntityGolem = Class.forName("atomicstryker.battletowers.common.AS_EntityGolem"); m_AS_EntityGolem_getIsDormant = ReflectUtil.findMethod(c_AS_EntityGolem, "getIsDormant"); c_AS_TowerDestroyer = Class.forName("atomicstryker.battletowers.common.AS_TowerDestroyer"); f_AS_TowerDestroyer_player = ReflectUtil.findField(c_AS_TowerDestroyer, "player"); + f_AS_TowerDestroyer_deleteMe = ReflectUtil.findField(c_AS_TowerDestroyer, "deleteMe"); c_AS_EntityGolemFireball = Class.forName("atomicstryker.battletowers.common.AS_EntityGolemFireball"); f_AS_EntityGolemFireball_shooterEntity = ReflectUtil.findField(c_AS_EntityGolemFireball, "shooterEntity"); @@ -152,6 +157,16 @@ public void setDestroyerPlayer(Object towerDestroyer, @Nullable Entity entityToS f_AS_TowerDestroyer_player.set(towerDestroyer, entityToSet); } + public boolean getDestroyerDeleteMe(Object towerDestroyer) throws IllegalArgumentException, IllegalAccessException + { + return f_AS_TowerDestroyer_deleteMe.getBoolean(towerDestroyer); + } + + public void setDestroyerDeleteMe(Object towerDestroyer, boolean deleteMe) throws IllegalArgumentException, IllegalAccessException + { + f_AS_TowerDestroyer_deleteMe.setBoolean(towerDestroyer, deleteMe); + } + public boolean isEntityGolemFireball(Entity entity) { return c_AS_EntityGolemFireball.isInstance(entity); @@ -212,9 +227,9 @@ public int getSurfaceBlockHeight(Object worldGenHandler, World world, int x, int return (int) m_WorldGenHandler_getSurfaceBlockHeight.invoke(worldGenHandler, world, x, z); } - public Object getModInstance() throws IllegalArgumentException, IllegalAccessException + public Object getModInstance() { - return f_AS_BattleTowersCore_instance.get(null); + return o_AS_BattleTowersCore_instance; } public int getMinDistanceFromSpawn() throws IllegalArgumentException, IllegalAccessException @@ -227,6 +242,16 @@ public int getMinDistanceBetweenTowers() throws IllegalArgumentException, Illega return (int) f_AS_BattleTowersCore_minDistanceBetweenTowers.get(getModInstance()); } + public int getTowerDestroyerEnabled() throws IllegalArgumentException, IllegalAccessException + { + return (int) f_AS_BattleTowersCore_towerDestroyerEnabled.getInt(getModInstance()); + } + + public void setTowerDestroyerEnabled(int val) throws IllegalArgumentException, IllegalAccessException + { + f_AS_BattleTowersCore_towerDestroyerEnabled.setInt(getModInstance(), val); + } + public Object newTowerPosition(Object worldGenHandler, int x, int y, int z, int type, boolean underground) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { return con_WorldGenHandler$TowerPosition.newInstance(worldGenHandler, x, y, z, type, underground);