diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java index 7b552df..6b10f1c 100644 --- a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java @@ -6,13 +6,15 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.network.PacketDistributor; import org.apache.logging.log4j.Logger; import com.seodisparate.TurnBasedMinecraft.common.networking.PacketGeneralMessage; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; @@ -20,19 +22,17 @@ public class BattleManager { private int IDCounter = 0; protected Map battleMap; - private Thread updaterThread; - private BattleUpdater battleUpdater; private Logger logger; private Map recentlyLeftBattle; + private BattleUpdater battleUpdater; public BattleManager(Logger logger) { this.logger = logger; battleMap = new HashMap(); - battleUpdater = new BattleUpdater(this); - updaterThread = new Thread(battleUpdater); - updaterThread.start(); recentlyLeftBattle = new HashMap(); + battleUpdater = new BattleUpdater(this); + MinecraftForge.EVENT_BUS.register(battleUpdater); } /** @@ -47,14 +47,34 @@ public class BattleManager { Config config = TurnBasedMinecraftMod.proxy.getConfig(); // verify that both entities are EntityPlayer and not in creative or has a corresponding EntityInfo - if(!((event.getEntity() instanceof EntityPlayer && !((EntityPlayer)event.getEntity()).isCreative()) || (config.getEntityInfoReference(event.getEntity().getClass().getName()) != null || config.getCustomEntityInfoReference(event.getEntity().getCustomNameTag()) != null)) - || !((event.getSource().getTrueSource() instanceof EntityPlayer && !((EntityPlayer)event.getSource().getTrueSource()).isCreative()) || (config.getEntityInfoReference(event.getSource().getTrueSource().getClass().getName()) != null || config.getCustomEntityInfoReference(event.getSource().getTrueSource().getCustomNameTag()) != null))) + String receiverClassName = event.getEntity().getClass().getName(); + String receiverCustomName; + try { + receiverCustomName = event.getEntity().getCustomName().getUnformattedComponentText(); + } catch (NullPointerException e) { + receiverCustomName = null; + } + String attackerClassName; + try { + attackerClassName = event.getSource().getTrueSource().getClass().getName(); + } catch (NullPointerException e) { + attackerClassName = null; + } + String attackerCustomName; + try { + attackerCustomName = event.getSource().getTrueSource().getCustomName().getUnformattedComponentText(); + } catch (NullPointerException e) { + attackerCustomName = null; + } + + if(!((event.getEntity() instanceof PlayerEntity && !((PlayerEntity)event.getEntity()).isCreative()) || (config.getEntityInfoReference(receiverClassName) != null || config.getCustomEntityInfoReference(receiverCustomName) != null)) + || !((event.getSource().getTrueSource() instanceof PlayerEntity && !((PlayerEntity)event.getSource().getTrueSource()).isCreative()) || (config.getEntityInfoReference(attackerClassName) != null || config.getCustomEntityInfoReference(attackerCustomName) != null))) { return false; } // check if ignore battle in config - EntityInfo entityInfo = config.getCustomEntityInfoReference(event.getEntity().getCustomNameTag()); + EntityInfo entityInfo = config.getCustomEntityInfoReference(receiverCustomName); if(entityInfo == null) { entityInfo = config.getMatchingEntityInfo(event.getEntity()); @@ -78,7 +98,7 @@ public class BattleManager return false; } - entityInfo = config.getCustomEntityInfoReference(event.getSource().getTrueSource().getCustomNameTag()); + entityInfo = config.getCustomEntityInfoReference(attackerCustomName); if(entityInfo == null) { entityInfo = config.getMatchingEntityInfo(event.getSource().getTrueSource()); @@ -147,7 +167,7 @@ public class BattleManager if(inBattle == null) { // neither entity is in battle - if(event.getEntity() instanceof EntityPlayer || event.getSource().getTrueSource() instanceof EntityPlayer) + if(event.getEntity() instanceof PlayerEntity || event.getSource().getTrueSource() instanceof PlayerEntity) { // at least one of the entities is a player, create Battle Collection sideA = new ArrayList(1); @@ -185,26 +205,39 @@ public class BattleManager public void checkTargeted(LivingSetAttackTargetEvent event) { - EntityInfo attackerInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(event.getEntity().getCustomNameTag()); + String targetedCustomName; + try { + targetedCustomName = event.getTarget().getCustomName().getUnformattedComponentText(); + } catch (NullPointerException e) { + targetedCustomName = null; + } + String attackerCustomName; + try { + attackerCustomName = event.getEntity().getCustomName().getUnformattedComponentText(); + } catch (NullPointerException e) { + attackerCustomName = null; + } + + EntityInfo attackerInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(attackerCustomName); if(attackerInfo == null) { attackerInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(event.getEntity()); } EntityInfo targetedInfo; - if(event.getTarget() instanceof EntityPlayer) + if(event.getTarget() instanceof PlayerEntity) { targetedInfo = null; } else { - targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(event.getTarget().getCustomNameTag()); + targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getCustomEntityInfoReference(targetedCustomName); if(targetedInfo == null) { targetedInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(event.getTarget()); } } - if((event.getTarget() instanceof EntityPlayer && ((EntityPlayer)event.getTarget()).isCreative()) + if((event.getTarget() instanceof PlayerEntity && ((PlayerEntity)event.getTarget()).isCreative()) || attackerInfo == null || attackerInfo.ignoreBattle || TurnBasedMinecraftMod.proxy.getConfig().isIgnoreBattleType(attackerInfo.category) @@ -257,7 +290,7 @@ public class BattleManager if(battle == null) { // neither in battle - if(event.getEntity() instanceof EntityPlayer || event.getTarget() instanceof EntityPlayer) + if(event.getEntity() instanceof PlayerEntity || event.getTarget() instanceof PlayerEntity) { // at least one is a player, create battle Collection sideA = new ArrayList(1); @@ -312,25 +345,23 @@ public class BattleManager public void cleanup() { - battleUpdater.setIsRunning(false); - battleUpdater = null; - updaterThread = null; + battleUpdater.setRunning(false); + MinecraftForge.EVENT_BUS.unregister(battleUpdater); synchronized(battleMap) { battleMap.clear(); } + battleUpdater = null; } protected void addRecentlyLeftBattle(Combatant c) { c.time = System.nanoTime(); Config config = TurnBasedMinecraftMod.proxy.getConfig(); - if(c.entity instanceof EntityPlayerMP) - { - TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketGeneralMessage("You just left battle! " + config.getLeaveBattleCooldownSeconds() + " seconds until you can attack/be-attacked again!"), (EntityPlayerMP)c.entity); + if(c.entity instanceof ServerPlayerEntity) { + TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(()->(ServerPlayerEntity) c.entity), new PacketGeneralMessage("You just left battle! " + config.getLeaveBattleCooldownSeconds() + " seconds until you can attack/be-attacked again!")); } - synchronized(recentlyLeftBattle) - { + synchronized(recentlyLeftBattle) { recentlyLeftBattle.put(c.entity.getEntityId(), c); } } @@ -346,9 +377,9 @@ public class BattleManager if(current - entry.getValue().time > TurnBasedMinecraftMod.proxy.getConfig().getLeaveBattleCooldownNanos()) { iter.remove(); - if(entry.getValue().entity instanceof EntityPlayerMP) + if(entry.getValue().entity instanceof ServerPlayerEntity) { - TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketGeneralMessage("Timer ended, you can now attack/be-attacked again."), (EntityPlayerMP)entry.getValue().entity); + TurnBasedMinecraftMod.getHandler().send(PacketDistributor.PLAYER.with(()->(ServerPlayerEntity)entry.getValue().entity), new PacketGeneralMessage("Timer ended, you can now attack/be-attacked again.")); } } } diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java index 6b3bcdd..e2d2a8e 100644 --- a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java @@ -1,98 +1,35 @@ package com.seodisparate.TurnBasedMinecraft.common; -import java.util.Iterator; -import java.util.Map; + +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + import java.util.concurrent.atomic.AtomicBoolean; -public class BattleUpdater implements Runnable +public class BattleUpdater { private BattleManager manager; private AtomicBoolean isRunning; - - private class UpdateRunnable implements Runnable - { - private Battle battle; - private AtomicBoolean finished = new AtomicBoolean(false); - private AtomicBoolean battleFinished = new AtomicBoolean(false); - - public UpdateRunnable(Battle battle) - { - this.battle = battle; - } - - public boolean isFinished() - { - return finished.get(); - } - - public boolean isBattleFinished() - { - return battleFinished.get(); - } + private int tick; + private final int tickLimit = 10; - @Override - public void run() - { - battleFinished.set(battle.update()); - finished.set(true); - } - } - public BattleUpdater(BattleManager manager) { this.manager = manager; isRunning = new AtomicBoolean(true); + tick = 0; } - @Override - public void run() - { - while(isRunning.get()) - { - synchronized(manager.battleMap) - { - for(Iterator> iter = manager.battleMap.entrySet().iterator(); iter.hasNext();) - { - Map.Entry entry = iter.next(); - UpdateRunnable updateRunnable = new UpdateRunnable(entry.getValue()); - Thread updateThread = new Thread(updateRunnable); - updateThread.start(); - try { updateThread.join(2000); } catch(InterruptedException e){ /* exception ignored */ } - if(!updateRunnable.isFinished()) - { - TurnBasedMinecraftMod.logger.warn("Battle (" + entry.getValue().getId() + "; " + entry.getValue().debugLog + ") update hanged for 2 seconds!"); - try { updateThread.join(2000); } catch(InterruptedException e){ /* exception ignored */ } - if(!updateRunnable.isFinished()) - { - TurnBasedMinecraftMod.logger.warn("Battle (" + entry.getValue().getId() + "; " + entry.getValue().debugLog + ") update hanged for 4 seconds!"); - try { updateThread.join(2000); } catch(InterruptedException e){ /* exception ignored */ } - if(!updateRunnable.isFinished()) - { - TurnBasedMinecraftMod.logger.error("Battle (" + entry.getValue().getId() + "; " + entry.getValue().debugLog + ") update timed out (6 seconds)!"); - updateThread.interrupt(); - try { updateThread.join(2000); } catch(InterruptedException e){ /* exception ignored */ } - if(!updateRunnable.isFinished()) - { - // TODO this is an ugly fix to a still-not-found freeze bug in Battle.update() - TurnBasedMinecraftMod.logger.error("Battle update will not stop, forcing it to stop (8 seconds)!"); - updateThread.stop(); - } - } - } - } - if(updateRunnable.isFinished() && updateRunnable.isBattleFinished()) - { - iter.remove(); - } - } - } - manager.updateRecentlyLeftBattle(); - try { Thread.sleep(250); } catch (Throwable t) { /* ignored */ } - } - } - - public void setIsRunning(boolean isRunning) - { + public void setRunning(boolean isRunning) { this.isRunning.set(isRunning); } + + @SubscribeEvent + public void update(TickEvent.ServerTickEvent tickEvent) { + if(tickEvent.phase != TickEvent.Phase.START && isRunning.get() && ++tick > tickLimit) { + tick = 0; + manager.battleMap.entrySet().removeIf(entry -> entry.getValue().update()); + manager.updateRecentlyLeftBattle(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/CommonProxy.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/CommonProxy.java index ea2f77f..c9c936d 100644 --- a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/CommonProxy.java +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/CommonProxy.java @@ -4,6 +4,7 @@ import java.util.*; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.common.MinecraftForge; import org.apache.logging.log4j.Logger; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Config.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Config.java index e37d545..16847c5 100644 --- a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Config.java +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Config.java @@ -862,6 +862,9 @@ public class Config */ public EntityInfo getEntityInfo(String classFullName) { + if(classFullName == null) { + return null; + } EntityInfo eInfo = entityInfoMap.get(classFullName); if(eInfo != null) { @@ -872,18 +875,19 @@ public class Config protected EntityInfo getEntityInfoReference(String classFullName) { + if(classFullName == null) { + return null; + } return entityInfoMap.get(classFullName); } protected EntityInfo getMatchingEntityInfo(Object entity) { - if(entity == null) - { + if(entity == null) { return null; } EntityInfo matching = entityInfoMap.get(entity.getClass().getName()); - if(matching != null && matching.classType.isInstance(entity)) - { + if(matching != null && matching.classType.isInstance(entity)) { return matching; } return null; @@ -896,6 +900,9 @@ public class Config */ public EntityInfo getCustomEntityInfo(String customName) { + if(customName == null) { + return null; + } EntityInfo eInfo = customEntityInfoMap.get(customName); if(eInfo != null) { @@ -906,6 +913,9 @@ public class Config protected EntityInfo getCustomEntityInfoReference(String customName) { + if(customName == null) { + return null; + } return customEntityInfoMap.get(customName); }