Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add handlers and requests for MapInfo packets #156

Merged
merged 12 commits into from
Mar 28, 2022
16 changes: 15 additions & 1 deletion EOLib/Domain/Map/CurrentMapStateRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public interface ICurrentMapStateRepository
HashSet<MapCoordinate> VisibleSpikeTraps { get; set; }

WarpState MapWarpState { get; set; }

HashSet<short> UnknownPlayerIDs { get; set; }

HashSet<byte> UnknownNPCIndexes { get; set; }
}

public interface ICurrentMapStateProvider
Expand All @@ -44,7 +48,11 @@ public interface ICurrentMapStateProvider

IReadOnlyCollection<MapCoordinate> VisibleSpikeTraps { get; }

WarpState MapWarpState { get; set; }
WarpState MapWarpState { get; }

HashSet<short> UnknownPlayerIDs { get; }

HashSet<byte> UnknownNPCIndexes { get; }
}

[AutoMappedType(IsSingleton = true)]
Expand All @@ -68,6 +76,10 @@ public class CurrentMapStateRepository : ICurrentMapStateRepository, ICurrentMap

public WarpState MapWarpState { get; set; }

public HashSet<short> UnknownPlayerIDs { get; set; }

public HashSet<byte> UnknownNPCIndexes { get; set; }

IReadOnlyDictionary<int, ICharacter> ICurrentMapStateProvider.Characters => Characters;

IReadOnlyCollection<INPC> ICurrentMapStateProvider.NPCs => NPCs;
Expand Down Expand Up @@ -96,6 +108,8 @@ public void ResetState()
OpenDoors = new HashSet<IWarp>();
PendingDoors = new HashSet<IWarp>();
VisibleSpikeTraps = new HashSet<MapCoordinate>();
UnknownPlayerIDs = new HashSet<short>();
UnknownNPCIndexes = new HashSet<byte>();

MapWarpState = WarpState.None;
}
Expand Down
6 changes: 3 additions & 3 deletions EOLib/Net/PacketFamily.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public enum PacketFamily : byte
Party = (byte)24,
Refresh = (byte)25,
NPC = (byte)26,
AutoRefresh = (byte)27,
AutoRefresh2 = (byte)28,
Appear = (byte)29,
CharacterMapInfo = (byte)27,
NPCMapInfo = (byte)28,
MapInfo = (byte)29,
PaperDoll = (byte)30,
Effect = (byte)31,
Trade = (byte)32,
Expand Down
3 changes: 2 additions & 1 deletion EOLib/Net/Translators/CharacterFromPacketFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public ICharacter CreateCharacter(IPacket packet)
var yLoc = packet.ReadShort();

var direction = (EODirection)packet.ReadChar();
packet.ReadChar(); //value is always 6? Unknown use
var classID = packet.ReadChar();
ethanmoffat marked this conversation as resolved.
Show resolved Hide resolved
var guildTag = packet.ReadString(3);

var level = packet.ReadChar();
Expand Down Expand Up @@ -78,6 +78,7 @@ public ICharacter CreateCharacter(IPacket packet)
return new Character()
.WithName(name)
.WithID(id)
.WithClassID(classID)
.WithMapID(mapID)
.WithGuildTag(guildTag)
.WithStats(stats)
Expand Down
27 changes: 27 additions & 0 deletions EOLib/Net/Translators/NPCFromPacketFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using AutomaticTypeMapper;
using EOLib.Domain.NPC;

namespace EOLib.Net.Translators
{
[AutoMappedType]
public class NPCFromPacketFactory : INPCFromPacketFactory
{
public INPC CreateNPC(IPacket packet)
{
var index = packet.ReadChar();
var id = packet.ReadShort();
var x = packet.ReadChar();
var y = packet.ReadChar();
var direction = (EODirection)packet.ReadChar();

INPC npc = new NPC(id, index);
npc = npc.WithX(x).WithY(y).WithDirection(direction).WithFrame(NPCFrame.Standing);
return npc;
}
}

public interface INPCFromPacketFactory
{
INPC CreateNPC(IPacket packet);
}
}
17 changes: 11 additions & 6 deletions EOLib/PacketHandlers/AdminHideHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ 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;
Expand Down
17 changes: 11 additions & 6 deletions EOLib/PacketHandlers/AdminShowHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 11 additions & 7 deletions EOLib/PacketHandlers/Effects/PlayerSpikeDamageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@ 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;
Expand Down
5 changes: 5 additions & 0 deletions EOLib/PacketHandlers/ItemEquipHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ protected bool HandlePaperdollPacket(IPacket packet, bool itemUnequipped)
}
});

update.MatchNone(() =>
{
_currentMapStateRepository.UnknownPlayerIDs.Add(playerId);
});

return true;
}
}
Expand Down
22 changes: 20 additions & 2 deletions EOLib/PacketHandlers/MainPlayerWalkHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using EOLib.Domain.Map;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Linq;

namespace EOLib.PacketHandlers
{
Expand All @@ -23,8 +24,25 @@ public MainPlayerWalkHandler(IPlayerInfoProvider playerInfoProvider,

public override bool HandlePacket(IPacket packet)
{
if (packet.ReadByte() != 255 || packet.ReadByte() != 255)
return false;
while (packet.PeekByte() != 0xFF)
ethanmoffat marked this conversation as resolved.
Show resolved Hide resolved
{
var playerID = packet.ReadShort();
if (!_currentMapStateRepository.Characters.ContainsKey(playerID))
{
_currentMapStateRepository.UnknownPlayerIDs.Add(playerID);
}
}
packet.ReadByte();

while (packet.PeekByte() != 0xFF)
{
var index = packet.ReadChar();
if (!_currentMapStateRepository.NPCs.Any((npc) => npc.Index == index))
{
_currentMapStateRepository.UnknownNPCIndexes.Add(index);
}
}
packet.ReadByte();

var numberOfMapItems = packet.PeekEndString().Length / 9;
for (int i = 0; i < numberOfMapItems; ++i)
Expand Down
71 changes: 71 additions & 0 deletions EOLib/PacketHandlers/MapInfoHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using AutomaticTypeMapper;
using EOLib.Domain.Extensions;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.IO.Extensions;
using EOLib.IO.Repositories;
using EOLib.Net;
using EOLib.Net.Handlers;
using EOLib.Net.Translators;

namespace EOLib.PacketHandlers
{
[AutoMappedType]
public class MapInfoHandler : InGameOnlyPacketHandler
{
private readonly ICurrentMapStateRepository _currentMapStateRepository;
private readonly ICharacterFromPacketFactory _characterFromPacketFactory;
private readonly INPCFromPacketFactory _npcFromPacketFactory;
private readonly IEIFFileProvider _eifFileProvider;

public override PacketFamily Family => PacketFamily.MapInfo;

public override PacketAction Action => PacketAction.Reply;

public MapInfoHandler(IPlayerInfoProvider playerInfoProvider,
ICurrentMapStateRepository currentMapStateRepository,
ICharacterFromPacketFactory characterFromPacketFactory,
INPCFromPacketFactory npcFromPacketFactory,
IEIFFileProvider eifFileProvider
)
: base(playerInfoProvider)
{
_currentMapStateRepository = currentMapStateRepository;
_characterFromPacketFactory = characterFromPacketFactory;
_npcFromPacketFactory = npcFromPacketFactory;
_eifFileProvider = eifFileProvider;
}

public override bool HandlePacket(IPacket packet)
{
var numOfEntities = packet.ReadChar();

if (packet.PeekByte() == 0xFF)
{
packet.ReadByte();
for (var i = 0; i < numOfEntities; i++)
{
var character = _characterFromPacketFactory.CreateCharacter(packet);
if (_currentMapStateRepository.Characters.ContainsKey(character.ID))
{
var existingCharacter = _currentMapStateRepository.Characters[character.ID];
var isRangedWeapon = _eifFileProvider.EIFFile.IsRangedWeapon(character.RenderProperties.WeaponGraphic);
character = existingCharacter.WithAppliedData(character, isRangedWeapon);
}
_currentMapStateRepository.Characters[character.ID] = character;
if (packet.ReadByte() != 255)
throw new MalformedPacketException("Missing 255 byte after character data", packet);
}
}

while (packet.ReadPosition < packet.Length)
{
var npc = _npcFromPacketFactory.CreateNPC(packet);
_currentMapStateRepository.NPCs.RemoveWhere(n => n.Index == npc.Index);
_currentMapStateRepository.NPCs.Add(npc);
}

return true;
}
}
}
10 changes: 9 additions & 1 deletion EOLib/PacketHandlers/NPCActionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 true;
}

var updatedNpc = Option.None<INPC>();
switch (num255s)
Expand Down Expand Up @@ -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);
Expand Down
49 changes: 0 additions & 49 deletions EOLib/PacketHandlers/NPCEnterMapHandler.cs

This file was deleted.

4 changes: 4 additions & 0 deletions EOLib/PacketHandlers/NPCLeaveMapHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading