From b2d72c5f993e01d9a7f29cb4615d709907224209 Mon Sep 17 00:00:00 2001 From: sorokya Date: Sun, 27 Mar 2022 15:17:58 +0200 Subject: [PATCH] Store unknown Players/NPC in MapState repository --- EOLib/Domain/Map/CurrentMapStateRepository.cs | 14 +++++ EOLib/PacketHandlers/AdminHideHandler.cs | 18 ++++-- EOLib/PacketHandlers/AdminShowHandler.cs | 17 ++++-- .../Effects/PlayerSpikeDamageHandler.cs | 19 +++--- EOLib/PacketHandlers/ItemEquipHandler.cs | 5 ++ EOLib/PacketHandlers/MainPlayerWalkHandler.cs | 61 ++++--------------- EOLib/PacketHandlers/NPCActionHandler.cs | 10 ++- EOLib/PacketHandlers/NPCLeaveMapHandler.cs | 4 ++ EOLib/PacketHandlers/NPCTakeDamageHandler.cs | 10 ++- EOLib/PacketHandlers/PlayerAttackHandler.cs | 24 +++++--- .../PlayerAvatarChangeHandler.cs | 1 + EOLib/PacketHandlers/PlayerLeaveMapHandler.cs | 16 +++-- EOLib/PacketHandlers/PlayerSitHandler.cs | 1 + EOLib/PacketHandlers/PlayerStandHandler.cs | 1 + .../PlayerTargetOtherSpellHandler.cs | 1 + EOLib/PacketHandlers/PlayerWalkHandler.cs | 38 +++++++----- 16 files changed, 138 insertions(+), 102 deletions(-) diff --git a/EOLib/Domain/Map/CurrentMapStateRepository.cs b/EOLib/Domain/Map/CurrentMapStateRepository.cs index 8770e6917..44a8a7047 100644 --- a/EOLib/Domain/Map/CurrentMapStateRepository.cs +++ b/EOLib/Domain/Map/CurrentMapStateRepository.cs @@ -24,6 +24,10 @@ public interface ICurrentMapStateRepository HashSet VisibleSpikeTraps { get; set; } WarpState MapWarpState { get; set; } + + HashSet UnknownPlayerIDs { get; set; } + + HashSet UnknownNPCIndexes { get; set; } } public interface ICurrentMapStateProvider @@ -45,6 +49,10 @@ public interface ICurrentMapStateProvider IReadOnlyCollection VisibleSpikeTraps { get; } WarpState MapWarpState { get; set; } + + HashSet UnknownPlayerIDs { get; } + + HashSet UnknownNPCIndexes { get; } } [AutoMappedType(IsSingleton = true)] @@ -68,6 +76,10 @@ public class CurrentMapStateRepository : ICurrentMapStateRepository, ICurrentMap public WarpState MapWarpState { get; set; } + public HashSet UnknownPlayerIDs { get; set; } + + public HashSet UnknownNPCIndexes { get; set; } + IReadOnlyDictionary ICurrentMapStateProvider.Characters => Characters; IReadOnlyCollection ICurrentMapStateProvider.NPCs => NPCs; @@ -96,6 +108,8 @@ public void ResetState() OpenDoors = new HashSet(); PendingDoors = new HashSet(); VisibleSpikeTraps = new HashSet(); + UnknownPlayerIDs = new HashSet(); + UnknownNPCIndexes = new HashSet(); MapWarpState = WarpState.None; } diff --git a/EOLib/PacketHandlers/AdminHideHandler.cs b/EOLib/PacketHandlers/AdminHideHandler.cs index 4a6f3f386..979ab0edc 100644 --- a/EOLib/PacketHandlers/AdminHideHandler.cs +++ b/EOLib/PacketHandlers/AdminHideHandler.cs @@ -33,12 +33,18 @@ public override bool HandlePacket(IPacket packet) _characterRepository.MainCharacter = Hidden(_characterRepository.MainCharacter); else { - if (!_currentMapStateRepository.Characters.ContainsKey(id)) - return false; - var character = _currentMapStateRepository.Characters[id]; - - var updatedCharacter = Hidden(character); - _currentMapStateRepository.Characters[id] = updatedCharacter; + if (_currentMapStateRepository.Characters.ContainsKey(id)) + { + var character = _currentMapStateRepository.Characters[id]; + + var updatedCharacter = Hidden(character); + _currentMapStateRepository.Characters[id] = updatedCharacter; + } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(id); + } + } return true; diff --git a/EOLib/PacketHandlers/AdminShowHandler.cs b/EOLib/PacketHandlers/AdminShowHandler.cs index 79591fd22..368aa4b76 100644 --- a/EOLib/PacketHandlers/AdminShowHandler.cs +++ b/EOLib/PacketHandlers/AdminShowHandler.cs @@ -33,12 +33,17 @@ public override bool HandlePacket(IPacket packet) _characterRepository.MainCharacter = Shown(_characterRepository.MainCharacter); else { - if (!_currentMapStateRepository.Characters.ContainsKey(id)) - return false; - var character = _currentMapStateRepository.Characters[id]; - - var updatedCharacter = Shown(character); - _currentMapStateRepository.Characters[id] = updatedCharacter; + if (_currentMapStateRepository.Characters.ContainsKey(id)) + { + var character = _currentMapStateRepository.Characters[id]; + + var updatedCharacter = Shown(character); + _currentMapStateRepository.Characters[id] = updatedCharacter; + } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(id); + } } return true; diff --git a/EOLib/PacketHandlers/Effects/PlayerSpikeDamageHandler.cs b/EOLib/PacketHandlers/Effects/PlayerSpikeDamageHandler.cs index b88623cf1..136d2234f 100644 --- a/EOLib/PacketHandlers/Effects/PlayerSpikeDamageHandler.cs +++ b/EOLib/PacketHandlers/Effects/PlayerSpikeDamageHandler.cs @@ -35,16 +35,21 @@ public override bool HandlePacket(IPacket packet) var isDead = packet.ReadChar() != 0; var damageTaken = packet.ReadThree(); - if (!_currentMapStateRepository.Characters.ContainsKey(characterId)) - return false; - - var updatedCharacter = _currentMapStateRepository.Characters[characterId].WithDamage(damageTaken, isDead); - _currentMapStateRepository.Characters[characterId] = updatedCharacter; + if (_currentMapStateRepository.Characters.ContainsKey(characterId)) + { + var updatedCharacter = _currentMapStateRepository.Characters[characterId].WithDamage(damageTaken, isDead); + _currentMapStateRepository.Characters[characterId] = updatedCharacter; - foreach (var notifier in _otherCharacterEventNotifiers) + foreach (var notifier in _otherCharacterEventNotifiers) + { + notifier.OtherCharacterTakeDamage(characterId, playerPercentHealth, damageTaken); + } + } + else { - notifier.OtherCharacterTakeDamage(characterId, playerPercentHealth, damageTaken); + _currentMapStateRepository.UnknownPlayerIDs.Add(characterId); } + return true; } diff --git a/EOLib/PacketHandlers/ItemEquipHandler.cs b/EOLib/PacketHandlers/ItemEquipHandler.cs index abdd49227..9efa9882c 100644 --- a/EOLib/PacketHandlers/ItemEquipHandler.cs +++ b/EOLib/PacketHandlers/ItemEquipHandler.cs @@ -107,6 +107,11 @@ protected bool HandlePaperdollPacket(IPacket packet, bool itemUnequipped) } }); + update.MatchNone(() => + { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerId); + }); + return true; } } diff --git a/EOLib/PacketHandlers/MainPlayerWalkHandler.cs b/EOLib/PacketHandlers/MainPlayerWalkHandler.cs index 99dd1e6ae..8df46d5f4 100644 --- a/EOLib/PacketHandlers/MainPlayerWalkHandler.cs +++ b/EOLib/PacketHandlers/MainPlayerWalkHandler.cs @@ -2,9 +2,7 @@ using EOLib.Domain.Login; using EOLib.Domain.Map; using EOLib.Net; -using EOLib.Net.Communication; using EOLib.Net.Handlers; -using System.Collections.Generic; using System.Linq; namespace EOLib.PacketHandlers @@ -13,33 +11,36 @@ namespace EOLib.PacketHandlers public class MainPlayerWalkHandler : InGameOnlyPacketHandler { private readonly ICurrentMapStateRepository _currentMapStateRepository; - private readonly IPacketSendService _packetSendService; public override PacketFamily Family => PacketFamily.Walk; public override PacketAction Action => PacketAction.Reply; public MainPlayerWalkHandler(IPlayerInfoProvider playerInfoProvider, - ICurrentMapStateRepository currentMapStateRepository, - IPacketSendService packetSendService) + ICurrentMapStateRepository currentMapStateRepository) : base(playerInfoProvider) { _currentMapStateRepository = currentMapStateRepository; - _packetSendService = packetSendService; } public override bool HandlePacket(IPacket packet) { - var playerIDs = new List(); while (packet.PeekByte() != 0xFF) { - playerIDs.Add(packet.ReadShort()); + var playerID = packet.ReadShort(); + if (!_currentMapStateRepository.Characters.ContainsKey(playerID)) + { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerID); + } } packet.ReadByte(); - var npcIndexes = new List(); while (packet.PeekByte() != 0xFF) { - npcIndexes.Add(packet.ReadChar()); + var index = packet.ReadChar(); + if (!_currentMapStateRepository.NPCs.Any((npc) => npc.Index == index)) + { + _currentMapStateRepository.UnknownNPCIndexes.Add(index); + } } packet.ReadByte(); @@ -56,46 +57,6 @@ public override bool HandlePacket(IPacket packet) _currentMapStateRepository.MapItems.Add(newItem); } - var newPlayerIDs = playerIDs - .Where(id => !_currentMapStateRepository.Characters.ContainsKey(id)) - .ToList(); - - var newNPCIndxes = npcIndexes - .Where(index => !_currentMapStateRepository.NPCs.Any((npc) => npc.Index == index)) - .ToList(); - - if (newPlayerIDs.Count > 0 || newNPCIndxes.Count > 0) - { - IPacketBuilder builder = new PacketBuilder(PacketFamily.MapInfo, PacketAction.Request); - - if (newPlayerIDs.Count > 0) - { - foreach (var playerId in newPlayerIDs) - { - builder = builder.AddShort(playerId); - } - } - - if (newNPCIndxes.Count > 0) - { - builder.AddByte(0xFF); - foreach (var npcIndex in newNPCIndxes) - { - builder = builder.AddChar(npcIndex); - } - } - - try - { - var request = builder.Build(); - _packetSendService.SendPacket(request); - } - catch (NoDataSentException) - { - return false; - } - } - return true; } } diff --git a/EOLib/PacketHandlers/NPCActionHandler.cs b/EOLib/PacketHandlers/NPCActionHandler.cs index a5b9d99a0..5204682cc 100644 --- a/EOLib/PacketHandlers/NPCActionHandler.cs +++ b/EOLib/PacketHandlers/NPCActionHandler.cs @@ -69,7 +69,11 @@ public override bool HandlePacket(IPacket packet) { npc = _currentMapStateRepository.NPCs.Single(n => n.Index == index); } - catch (InvalidOperationException) { return false; } + catch (InvalidOperationException) + { + _currentMapStateRepository.UnknownNPCIndexes.Add(index); + return false; + } var updatedNpc = Option.None(); switch (num255s) @@ -142,6 +146,10 @@ private INPC HandleNPCAttack(IPacket packet, INPC npc) foreach (var notifier in _otherCharacterNotifiers) notifier.OtherCharacterTakeDamage(characterID, playerPercentHealth, damageTaken); } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(characterID); + } foreach (var notifier in _npcAnimationNotifiers) notifier.StartNPCAttackAnimation(npc.Index); diff --git a/EOLib/PacketHandlers/NPCLeaveMapHandler.cs b/EOLib/PacketHandlers/NPCLeaveMapHandler.cs index 3ccf6a1b2..d4aa52bd7 100644 --- a/EOLib/PacketHandlers/NPCLeaveMapHandler.cs +++ b/EOLib/PacketHandlers/NPCLeaveMapHandler.cs @@ -113,6 +113,10 @@ private void UpdatePlayerDirection(short playerID, EODirection playerDirection) var updatedCharacter = _currentMapStateRepository.Characters[playerID].WithRenderProperties(updatedRenderProps); _currentMapStateRepository.Characters[playerID] = updatedCharacter; } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerID); + } } private void UpdateCharacterStat(CharacterStat whichStat, int statValue) diff --git a/EOLib/PacketHandlers/NPCTakeDamageHandler.cs b/EOLib/PacketHandlers/NPCTakeDamageHandler.cs index 1bd3f2073..f3a93b7d4 100644 --- a/EOLib/PacketHandlers/NPCTakeDamageHandler.cs +++ b/EOLib/PacketHandlers/NPCTakeDamageHandler.cs @@ -68,6 +68,10 @@ public override bool HandlePacket(IPacket packet) var updatedCharacter = _currentMapStateRepository.Characters[fromPlayerId].WithRenderProperties(renderProps); _currentMapStateRepository.Characters[fromPlayerId] = updatedCharacter; } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(fromPlayerId); + } // todo: this has the potential to bug out if the opponent ID is never reset and the player dies/leaves try @@ -79,7 +83,11 @@ public override bool HandlePacket(IPacket packet) foreach (var notifier in _npcNotifiers) notifier.NPCTakeDamage(npcIndex, fromPlayerId, damageToNpc, npcPctHealth, spellId); } - catch (InvalidOperationException) { return false; } + catch (InvalidOperationException) + { + _currentMapStateRepository.UnknownNPCIndexes.Add((byte)npcIndex); + return false; + } return true; } diff --git a/EOLib/PacketHandlers/PlayerAttackHandler.cs b/EOLib/PacketHandlers/PlayerAttackHandler.cs index e292f584f..cd9249d66 100644 --- a/EOLib/PacketHandlers/PlayerAttackHandler.cs +++ b/EOLib/PacketHandlers/PlayerAttackHandler.cs @@ -32,18 +32,22 @@ public override bool HandlePacket(IPacket packet) var playerID = packet.ReadShort(); var direction = (EODirection)packet.ReadChar(); - if (!_currentMapStateRepository.Characters.ContainsKey(playerID)) - return false; - - var character = _currentMapStateRepository.Characters[playerID]; - if (character.RenderProperties.Direction != direction) + if (_currentMapStateRepository.Characters.ContainsKey(playerID)) { - var renderProperties = character.RenderProperties.WithDirection(direction); - _currentMapStateRepository.Characters[playerID] = character.WithRenderProperties(renderProperties); + var character = _currentMapStateRepository.Characters[playerID]; + if (character.RenderProperties.Direction != direction) + { + var renderProperties = character.RenderProperties.WithDirection(direction); + _currentMapStateRepository.Characters[playerID] = character.WithRenderProperties(renderProperties); + } + + foreach (var notifier in _otherCharacterAnimationNotifiers) + notifier.StartOtherCharacterAttackAnimation(playerID); + } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerID); } - - foreach (var notifier in _otherCharacterAnimationNotifiers) - notifier.StartOtherCharacterAttackAnimation(playerID); return true; } diff --git a/EOLib/PacketHandlers/PlayerAvatarChangeHandler.cs b/EOLib/PacketHandlers/PlayerAvatarChangeHandler.cs index 6c74a4ef1..c1badaa00 100644 --- a/EOLib/PacketHandlers/PlayerAvatarChangeHandler.cs +++ b/EOLib/PacketHandlers/PlayerAvatarChangeHandler.cs @@ -46,6 +46,7 @@ public override bool HandlePacket(IPacket packet) } else { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerID); return false; } diff --git a/EOLib/PacketHandlers/PlayerLeaveMapHandler.cs b/EOLib/PacketHandlers/PlayerLeaveMapHandler.cs index cee526c38..8c7180b93 100644 --- a/EOLib/PacketHandlers/PlayerLeaveMapHandler.cs +++ b/EOLib/PacketHandlers/PlayerLeaveMapHandler.cs @@ -39,12 +39,16 @@ public override bool HandlePacket(IPacket packet) notifier.NotifyWarpLeaveEffect(id, anim); } - if (!_currentMapStateRepository.Characters.ContainsKey(id)) - return false; - - var character = _currentMapStateRepository.Characters[id]; - _currentMapStateRepository.Characters.Remove(id); - _currentMapStateRepository.VisibleSpikeTraps.Remove(new MapCoordinate(character.RenderProperties.MapX, character.RenderProperties.MapY)); + if (_currentMapStateRepository.Characters.ContainsKey(id)) + { + var character = _currentMapStateRepository.Characters[id]; + _currentMapStateRepository.Characters.Remove(id); + _currentMapStateRepository.VisibleSpikeTraps.Remove(new MapCoordinate(character.RenderProperties.MapX, character.RenderProperties.MapY)); + } + else + { + _currentMapStateRepository.UnknownPlayerIDs.Add(id); + } return true; } diff --git a/EOLib/PacketHandlers/PlayerSitHandler.cs b/EOLib/PacketHandlers/PlayerSitHandler.cs index 9c1a39008..6a67eaa72 100644 --- a/EOLib/PacketHandlers/PlayerSitHandler.cs +++ b/EOLib/PacketHandlers/PlayerSitHandler.cs @@ -56,6 +56,7 @@ public override bool HandlePacket(IPacket packet) } else { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerId); return false; } diff --git a/EOLib/PacketHandlers/PlayerStandHandler.cs b/EOLib/PacketHandlers/PlayerStandHandler.cs index de06041d1..034eafb68 100644 --- a/EOLib/PacketHandlers/PlayerStandHandler.cs +++ b/EOLib/PacketHandlers/PlayerStandHandler.cs @@ -48,6 +48,7 @@ public override bool HandlePacket(IPacket packet) } else { + _currentMapStateRepository.UnknownPlayerIDs.Add(playerId); return false; } diff --git a/EOLib/PacketHandlers/PlayerTargetOtherSpellHandler.cs b/EOLib/PacketHandlers/PlayerTargetOtherSpellHandler.cs index f1a382eec..451961dea 100644 --- a/EOLib/PacketHandlers/PlayerTargetOtherSpellHandler.cs +++ b/EOLib/PacketHandlers/PlayerTargetOtherSpellHandler.cs @@ -52,6 +52,7 @@ public override bool HandlePacket(IPacket packet) } else { + _currentMapStateRepository.UnknownPlayerIDs.Add(sourcePlayerId); return false; } diff --git a/EOLib/PacketHandlers/PlayerWalkHandler.cs b/EOLib/PacketHandlers/PlayerWalkHandler.cs index d410ed3af..23410dd3c 100644 --- a/EOLib/PacketHandlers/PlayerWalkHandler.cs +++ b/EOLib/PacketHandlers/PlayerWalkHandler.cs @@ -8,6 +8,7 @@ using EOLib.Domain.Map; using EOLib.Domain.Notifiers; using EOLib.Net; +using EOLib.Net.Communication; using EOLib.Net.Handlers; namespace EOLib.PacketHandlers @@ -17,6 +18,7 @@ public class PlayerWalkHandler : InGameOnlyPacketHandler { private readonly ICurrentMapStateRepository _currentMapStateRepository; private readonly IEnumerable _otherCharacterAnimationNotifiers; + private readonly IPacketSendService _packetSendService; public override PacketFamily Family => PacketFamily.Walk; @@ -24,37 +26,43 @@ public class PlayerWalkHandler : InGameOnlyPacketHandler public PlayerWalkHandler(IPlayerInfoProvider playerInfoProvider, ICurrentMapStateRepository currentMapStateRepository, - IEnumerable otherCharacterAnimationNotifiers) + IEnumerable otherCharacterAnimationNotifiers, + IPacketSendService packetSendService) : base(playerInfoProvider) { _currentMapStateRepository = currentMapStateRepository; _otherCharacterAnimationNotifiers = otherCharacterAnimationNotifiers; + _packetSendService = packetSendService; } public override bool HandlePacket(IPacket packet) { var characterID = packet.ReadShort(); - if (!_currentMapStateRepository.Characters.ContainsKey(characterID)) - return false; + if (_currentMapStateRepository.Characters.ContainsKey(characterID)) + { + var dir = (EODirection)packet.ReadChar(); + var x = packet.ReadChar(); + var y = packet.ReadChar(); - var dir = (EODirection)packet.ReadChar(); - var x = packet.ReadChar(); - var y = packet.ReadChar(); + var character = _currentMapStateRepository.Characters[characterID]; - var character = _currentMapStateRepository.Characters[characterID]; + // if character is walking, that means animator is handling position of character + // if character is not walking (this is true in EOBot), update the domain model here + if (!character.RenderProperties.IsActing(CharacterActionState.Walking)) + { + var renderProperties = EnsureCorrectXAndY(character.RenderProperties.WithDirection(dir), x, y); + _currentMapStateRepository.Characters[characterID] = character.WithRenderProperties(renderProperties); + } - // if character is walking, that means animator is handling position of character - // if character is not walking (this is true in EOBot), update the domain model here - if (!character.RenderProperties.IsActing(CharacterActionState.Walking)) + foreach (var notifier in _otherCharacterAnimationNotifiers) + notifier.StartOtherCharacterWalkAnimation(characterID, x, y, dir); + } + else { - var renderProperties = EnsureCorrectXAndY(character.RenderProperties.WithDirection(dir), x, y); - _currentMapStateRepository.Characters[characterID] = character.WithRenderProperties(renderProperties); + _currentMapStateRepository.UnknownPlayerIDs.Add(characterID); } - foreach (var notifier in _otherCharacterAnimationNotifiers) - notifier.StartOtherCharacterWalkAnimation(characterID, x, y, dir); - return true; }