From 4b0758bbba35b4ca4b37bc3455f40e38575d6d4e Mon Sep 17 00:00:00 2001 From: sorokya Date: Sun, 27 Mar 2022 16:06:37 +0200 Subject: [PATCH] Add UnknownEntitiesRequester to game --- EOLib/PacketHandlers/MapInfoHandler.cs | 2 + EOLib/PacketHandlers/PlayerWalkHandler.cs | 10 +- .../HUD/Controls/HudControlIdentifier.cs | 1 + .../HUD/Controls/HudControlsFactory.cs | 13 ++- .../Network/UnknownEntitiesRequester.cs | 104 ++++++++++++++++++ 5 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 EndlessClient/Network/UnknownEntitiesRequester.cs diff --git a/EOLib/PacketHandlers/MapInfoHandler.cs b/EOLib/PacketHandlers/MapInfoHandler.cs index ebf0ab556..053154310 100644 --- a/EOLib/PacketHandlers/MapInfoHandler.cs +++ b/EOLib/PacketHandlers/MapInfoHandler.cs @@ -53,6 +53,8 @@ public override bool HandlePacket(IPacket packet) character = existingCharacter.WithAppliedData(character, isRangedWeapon); } _currentMapStateRepository.Characters[character.ID] = character; + if (packet.ReadByte() != 255) + throw new MalformedPacketException("Missing 255 byte after character data", packet); } } diff --git a/EOLib/PacketHandlers/PlayerWalkHandler.cs b/EOLib/PacketHandlers/PlayerWalkHandler.cs index 23410dd3c..257e82a39 100644 --- a/EOLib/PacketHandlers/PlayerWalkHandler.cs +++ b/EOLib/PacketHandlers/PlayerWalkHandler.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using AutomaticTypeMapper; using EOLib.Domain.Character; using EOLib.Domain.Extensions; @@ -8,7 +6,6 @@ using EOLib.Domain.Map; using EOLib.Domain.Notifiers; using EOLib.Net; -using EOLib.Net.Communication; using EOLib.Net.Handlers; namespace EOLib.PacketHandlers @@ -18,7 +15,6 @@ public class PlayerWalkHandler : InGameOnlyPacketHandler { private readonly ICurrentMapStateRepository _currentMapStateRepository; private readonly IEnumerable _otherCharacterAnimationNotifiers; - private readonly IPacketSendService _packetSendService; public override PacketFamily Family => PacketFamily.Walk; @@ -26,13 +22,11 @@ public class PlayerWalkHandler : InGameOnlyPacketHandler public PlayerWalkHandler(IPlayerInfoProvider playerInfoProvider, ICurrentMapStateRepository currentMapStateRepository, - IEnumerable otherCharacterAnimationNotifiers, - IPacketSendService packetSendService) + IEnumerable otherCharacterAnimationNotifiers) : base(playerInfoProvider) { _currentMapStateRepository = currentMapStateRepository; _otherCharacterAnimationNotifiers = otherCharacterAnimationNotifiers; - _packetSendService = packetSendService; } public override bool HandlePacket(IPacket packet) diff --git a/EndlessClient/HUD/Controls/HudControlIdentifier.cs b/EndlessClient/HUD/Controls/HudControlIdentifier.cs index 4d98ce989..f1181ea08 100644 --- a/EndlessClient/HUD/Controls/HudControlIdentifier.cs +++ b/EndlessClient/HUD/Controls/HudControlIdentifier.cs @@ -69,6 +69,7 @@ public enum HudControlIdentifier UserInputHandler, CharacterAnimator, NPCAnimator, + UnknownEntitiesRequester, PreviousUserInputTracker = Int32.MaxValue, //this should always be last! } diff --git a/EndlessClient/HUD/Controls/HudControlsFactory.cs b/EndlessClient/HUD/Controls/HudControlsFactory.cs index b22523fcd..ca01f980a 100644 --- a/EndlessClient/HUD/Controls/HudControlsFactory.cs +++ b/EndlessClient/HUD/Controls/HudControlsFactory.cs @@ -10,6 +10,7 @@ using EndlessClient.HUD.Panels; using EndlessClient.HUD.StatusBars; using EndlessClient.Input; +using EndlessClient.Network; using EndlessClient.Rendering; using EndlessClient.Rendering.Character; using EndlessClient.Rendering.Factories; @@ -19,6 +20,7 @@ using EOLib.Domain.Map; using EOLib.Graphics; using EOLib.Localization; +using EOLib.Net.Communication; using Microsoft.Xna.Framework; using XNAControls; @@ -53,6 +55,7 @@ public class HudControlsFactory : IHudControlsFactory private readonly IPathFinder _pathFinder; private readonly ICharacterActions _characterActions; private readonly IWalkValidationActions _walkValidationActions; + private readonly IPacketSendService _packetSendService; private IChatController _chatController; public HudControlsFactory(IHudButtonController hudButtonController, @@ -76,7 +79,8 @@ public class HudControlsFactory : IHudControlsFactory IArrowKeyController arrowKeyController, IPathFinder pathFinder, ICharacterActions characterActions, - IWalkValidationActions walkValidationActions) + IWalkValidationActions walkValidationActions, + IPacketSendService packetSendService) { _hudButtonController = hudButtonController; _hudPanelFactory = hudPanelFactory; @@ -100,6 +104,7 @@ public class HudControlsFactory : IHudControlsFactory _pathFinder = pathFinder; _characterActions = characterActions; _walkValidationActions = walkValidationActions; + _packetSendService = packetSendService; } public void InjectChatController(IChatController chatController) @@ -158,6 +163,7 @@ public void InjectChatController(IChatController chatController) {HudControlIdentifier.UserInputHandler, CreateUserInputHandler()}, {HudControlIdentifier.CharacterAnimator, CreateCharacterAnimator()}, {HudControlIdentifier.NPCAnimator, CreateNPCAnimator()}, + {HudControlIdentifier.UnknownEntitiesRequester, CreateUnknownEntitiesRequester()}, {HudControlIdentifier.PreviousUserInputTracker, CreatePreviousUserInputTracker()} }; @@ -359,6 +365,11 @@ private UsageTrackerComponent CreateUsageTracker() return new UsageTrackerComponent(_endlessGameProvider, _characterRepository); } + private UnknownEntitiesRequester CreateUnknownEntitiesRequester() + { + return new UnknownEntitiesRequester(_endlessGameProvider, _currentMapStateRepository, _packetSendService); + } + private StatusBarLabel CreateStatusLabel() { return new StatusBarLabel(_clientWindowSizeProvider, _statusLabelTextProvider) { DrawOrder = HUD_CONTROL_LAYER }; diff --git a/EndlessClient/Network/UnknownEntitiesRequester.cs b/EndlessClient/Network/UnknownEntitiesRequester.cs new file mode 100644 index 000000000..1fe841b1b --- /dev/null +++ b/EndlessClient/Network/UnknownEntitiesRequester.cs @@ -0,0 +1,104 @@ +using EndlessClient.GameExecution; +using EOLib.Domain.Map; +using EOLib.Net; +using EOLib.Net.Communication; +using Microsoft.Xna.Framework; +using System; + +namespace EndlessClient.Network +{ + public class UnknownEntitiesRequester : GameComponent + { + private readonly ICurrentMapStateRepository _currentMapStateRepository; + private readonly IPacketSendService _packetSendService; + private DateTime _lastRequestTime; + private const double REQUEST_INTERVAL_SECONDS = 1; + + public UnknownEntitiesRequester(IEndlessGameProvider gameProvider, + ICurrentMapStateRepository currentMapStateRepository, + IPacketSendService packetSendService) + : base((Game) gameProvider.Game) + { + _currentMapStateRepository = currentMapStateRepository; + _packetSendService = packetSendService; + _lastRequestTime = DateTime.Now; + } + + public override void Update(GameTime gameTime) + { + if ((DateTime.Now - _lastRequestTime).TotalSeconds >= REQUEST_INTERVAL_SECONDS) + { + IPacket request = null; + if (_currentMapStateRepository.UnknownNPCIndexes.Count > 0 && _currentMapStateRepository.UnknownPlayerIDs.Count > 0) + { + request = CreateRequestForBoth(); + } + else if (_currentMapStateRepository.UnknownNPCIndexes.Count > 0) + { + request = CreateRequestForNPCs(); + } + else if (_currentMapStateRepository.UnknownPlayerIDs.Count > 0) + { + request = CreateRequestForPlayers(); + } + + try + { + if (request != null) + _packetSendService.SendPacket(request); + } + catch (NoDataSentException) + { + // do nothing.. should we log these? + } + finally + { + _currentMapStateRepository.UnknownNPCIndexes.Clear(); + _currentMapStateRepository.UnknownPlayerIDs.Clear(); + _lastRequestTime = DateTime.Now; + } + } + + base.Update(gameTime); + } + + private IPacket CreateRequestForBoth() + { + IPacketBuilder builder = new PacketBuilder(PacketFamily.MapInfo, PacketAction.Request); + foreach (var id in _currentMapStateRepository.UnknownPlayerIDs) + { + builder = builder.AddShort(id); + } + builder = builder.AddByte(0xFF); + foreach (var index in _currentMapStateRepository.UnknownNPCIndexes) + { + builder = builder.AddChar(index); + } + + return builder.Build(); + } + + private IPacket CreateRequestForNPCs() + { + IPacketBuilder builder = new PacketBuilder(PacketFamily.NPCMapInfo, PacketAction.Request) + .AddChar((byte)_currentMapStateRepository.UnknownNPCIndexes.Count) + .AddByte(0xFF); + + foreach (var index in _currentMapStateRepository.UnknownNPCIndexes) + { + builder = builder.AddChar(index); + } + return builder.Build(); + } + + private IPacket CreateRequestForPlayers() + { + IPacketBuilder builder = new PacketBuilder(PacketFamily.CharacterMapInfo, PacketAction.Request); + foreach (var id in _currentMapStateRepository.UnknownPlayerIDs) + { + builder = builder.AddShort(id); + } + return builder.Build(); + } + } +}