From 278c31f86729eea8e34ad152dca0d03168b1d8a8 Mon Sep 17 00:00:00 2001 From: sorokya Date: Sun, 27 Mar 2022 14:45:21 +0200 Subject: [PATCH] Request map info for new characters/npcs in the walk reply --- EOLib/PacketHandlers/MainPlayerWalkHandler.cs | 63 ++++++++++++++++++- EOLib/PacketHandlers/MapInfoHandler.cs | 7 ++- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/EOLib/PacketHandlers/MainPlayerWalkHandler.cs b/EOLib/PacketHandlers/MainPlayerWalkHandler.cs index 2783ae533..99dd1e6ae 100644 --- a/EOLib/PacketHandlers/MainPlayerWalkHandler.cs +++ b/EOLib/PacketHandlers/MainPlayerWalkHandler.cs @@ -2,7 +2,10 @@ 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 { @@ -10,21 +13,35 @@ 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) + ICurrentMapStateRepository currentMapStateRepository, + IPacketSendService packetSendService) : base(playerInfoProvider) { _currentMapStateRepository = currentMapStateRepository; + _packetSendService = packetSendService; } public override bool HandlePacket(IPacket packet) { - if (packet.ReadByte() != 255 || packet.ReadByte() != 255) - return false; + var playerIDs = new List(); + while (packet.PeekByte() != 0xFF) + { + playerIDs.Add(packet.ReadShort()); + } + packet.ReadByte(); + + var npcIndexes = new List(); + while (packet.PeekByte() != 0xFF) + { + npcIndexes.Add(packet.ReadChar()); + } + packet.ReadByte(); var numberOfMapItems = packet.PeekEndString().Length / 9; for (int i = 0; i < numberOfMapItems; ++i) @@ -39,6 +56,46 @@ 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/MapInfoHandler.cs b/EOLib/PacketHandlers/MapInfoHandler.cs index 0dcd5ff59..ebf0ab556 100644 --- a/EOLib/PacketHandlers/MapInfoHandler.cs +++ b/EOLib/PacketHandlers/MapInfoHandler.cs @@ -25,13 +25,15 @@ public class MapInfoHandler : InGameOnlyPacketHandler public MapInfoHandler(IPlayerInfoProvider playerInfoProvider, ICurrentMapStateRepository currentMapStateRepository, ICharacterFromPacketFactory characterFromPacketFactory, - INPCFromPacketFactory npcFromPacketFactory + INPCFromPacketFactory npcFromPacketFactory, + IEIFFileProvider eifFileProvider ) : base(playerInfoProvider) { _currentMapStateRepository = currentMapStateRepository; _characterFromPacketFactory = characterFromPacketFactory; _npcFromPacketFactory = npcFromPacketFactory; + _eifFileProvider = eifFileProvider; } public override bool HandlePacket(IPacket packet) @@ -40,6 +42,7 @@ public override bool HandlePacket(IPacket packet) if (packet.PeekByte() == 0xFF) { + packet.ReadByte(); for (var i = 0; i < num_entities; i++) { var character = _characterFromPacketFactory.CreateCharacter(packet); @@ -53,7 +56,7 @@ public override bool HandlePacket(IPacket packet) } } - while (packet.ReadPosition < packet.Length) + while (num_entities > 0 && packet.ReadPosition < packet.Length) { var npc = _npcFromPacketFactory.CreateNPC(packet); _currentMapStateRepository.NPCs.RemoveWhere(n => n.Index == npc.Index);