diff --git a/src/engine/gameManager/MultiboxManager.java b/src/engine/gameManager/MultiboxManager.java new file mode 100644 index 00000000..1e3b2d7d --- /dev/null +++ b/src/engine/gameManager/MultiboxManager.java @@ -0,0 +1,68 @@ +package engine.gameManager; + +import engine.objects.PlayerCharacter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class MultiboxManager { + public static HashMap> activeCharacters = new HashMap<>(); + public static ReentrantReadWriteLock updateLock = new ReentrantReadWriteLock(); + + public static void addPlayer(PlayerCharacter player){ + updateLock.writeLock().lock(); + try { + + //get the machine ID for the key of the map + String machineID = player.getClientConnection().machineID; + + //cleanup and remove inactive players from the list + ArrayList purgeList = new ArrayList<>(); + for(PlayerCharacter pc : activeCharacters.get(machineID)) + if(!pc.isEnteredWorld() || !pc.isActive()) + purgeList.add(pc); + + activeCharacters.get(machineID).removeAll(purgeList); + + //remove empty key + if(activeCharacters.get(machineID).size() < 1) + activeCharacters.remove(machineID); + + + if(activeCharacters.containsKey(machineID)){ + //already has an entry for this machine ID + player.isBoxed = true; + activeCharacters.get(machineID).add(player); + }else{ + //does not have an entry for this machine ID + player.isBoxed = false; + ArrayList newList = new ArrayList<>(); + newList.add(player); + activeCharacters.put(machineID,newList); + } + } finally { + updateLock.writeLock().unlock(); + } + } + + public static void removePlayer(PlayerCharacter player){ + + //get the machine ID for the key of the map + String machineID = player.getClientConnection().machineID; + + if(activeCharacters.containsKey(machineID)){ + //remove player from existing list + activeCharacters.get(machineID).remove(player); + + //check if there are still players in the machine ID key list + if(activeCharacters.get(machineID).size() > 1){ + //list still has characters, make one of them active + activeCharacters.get(machineID).get(0).isBoxed = false; + }else{ + //list is now empty, remove it from the map + activeCharacters.remove(machineID); + } + } + } +} diff --git a/src/engine/net/client/handlers/RequestEnterWorldHandler.java b/src/engine/net/client/handlers/RequestEnterWorldHandler.java index 18b48254..cd31a3a8 100644 --- a/src/engine/net/client/handlers/RequestEnterWorldHandler.java +++ b/src/engine/net/client/handlers/RequestEnterWorldHandler.java @@ -8,6 +8,7 @@ import engine.db.archive.CharacterRecord; import engine.db.archive.DataWarehouse; import engine.db.archive.PvpRecord; import engine.exception.MsgSendException; +import engine.gameManager.MultiboxManager; import engine.gameManager.SessionManager; import engine.math.Vector3fImmutable; import engine.net.Dispatch; @@ -157,6 +158,8 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { dispatch = Dispatch.borrow(player, sopm); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); + MultiboxManager.addPlayer(player); + return true; } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index c2bda26b..1236db3b 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -177,6 +177,8 @@ public class PlayerCharacter extends AbstractCharacter { public float ZergMultiplier = 1.0f; + public boolean isBoxed = false; + /** * No Id Constructor */ @@ -4814,6 +4816,10 @@ public class PlayerCharacter extends AbstractCharacter { this.safeZone = this.isInSafeZone(); + if(this.isBoxed && !this.containsEffect(1672601862)) { + PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); + } + } catch (Exception e) { Logger.error(e); } finally { diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index afc06004..8c77ace5 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -656,6 +656,7 @@ public class WorldServer { // TODO log this return; + MultiboxManager.removePlayer(playerCharacter); //cancel any trade if (playerCharacter.getCharItemManager() != null) playerCharacter.getCharItemManager().endTrade(true); @@ -705,6 +706,8 @@ public class WorldServer { Logger.error("Unable to find PlayerCharacter to logout"); return; } + + MultiboxManager.removePlayer(player); //remove player from loaded mobs agro maps for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(),MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_MOB)) { Mob loadedMob = (Mob) awo;