Skip to content

Commit

Permalink
Add ItemSlot and InventorySize encoding for character data
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaioru committed Aug 30, 2024
1 parent 2a4d1ff commit 2eb7cc0
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 25 deletions.
124 changes: 107 additions & 17 deletions src/protocol/Edelstein.Protocol.Gameplay/Entities/CharacterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,28 @@ public static StructuredCharacterLook ToStructuredCharacterLook(this Character c
var unseen = new Dictionary<byte, int>();
var equip = new Dictionary<byte, int>();
var weaponStickerID = 0;

// TODO: evan gloves 1082262

foreach (var kv in inventory.Where(kv => kv.Key < -100))
{
var slot = (byte)(Math.Abs(kv.Key) - 100);
if (slot == (int)BodyPart.Weapon)

if (slot == (int)BodyPart.Weapon)
weaponStickerID = kv.Value.TemplateID;
equip[slot] = kv.Value.TemplateID;
}

foreach (var kv in inventory.Where(kv => kv.Key is < 0 and > -100))
{
var slot = (byte)Math.Abs(kv.Key);
if (!equip.ContainsKey(slot))

if (!equip.ContainsKey(slot))
equip[slot] = kv.Value.TemplateID;
else
else
unseen[slot] = kv.Value.TemplateID;
}

return new StructuredCharacterLook
{
Gender = character.Gender,
Expand All @@ -95,15 +95,105 @@ public static StructuredCharacterLook ToStructuredCharacterLook(this Character c
};
}

public static StructuredCharacterData ToStructuredCharacterData(this Character character, StructuredCharacterDataFlag flags = StructuredCharacterDataFlag.All)
public static StructuredCharacterData ToStructuredCharacterData(this Character character)
=> new()
{
Character = flags.HasFlag(StructuredCharacterDataFlag.Character)
? new StructuredCharacterDataInfoCharacter
{
Stats = character.ToStructuredCharacterStat(),
FriendMax = 100
}
: null
Character = new StructuredCharacterDataInfoCharacter
{
Stats = character.ToStructuredCharacterStat(),
FriendMax = 100
},
Money = character.Money,
InventorySize = new StructuredCharacterDataInfoInventorySize
{
Equip = (byte)character.Inventories.Equip.SlotMax,
Consume = (byte)character.Inventories.Consume.SlotMax,
Install = (byte)character.Inventories.Install.SlotMax,
Etc = (byte)character.Inventories.Etc.SlotMax,
Cash = (byte)character.Inventories.Cash.SlotMax
},
ItemSlotEquip = new StructuredCharacterDataInfoItemSlotEquips
{
Equipped = character.Inventories.Equip.Items
.Where(kv => kv.Key is >= -100 and < 0)
.Select(kv => new StructuredCharacterDataInfoItemSlotEquip
{
Slot = (short)Math.Abs(kv.Key % 100),
Item = kv.Value.ToStructured()
})
.ToList(),
Equipped2 = character.Inventories.Equip.Items
.Where(kv => kv.Key is >= -1000 and < -100)
.Select(kv => new StructuredCharacterDataInfoItemSlotEquip
{
Slot = (short)Math.Abs(kv.Key % 100),
Item = kv.Value.ToStructured()
})
.ToList(),
Equip = character.Inventories.Equip.Items
.Where(kv => kv.Key >= 0)
.Select(kv => new StructuredCharacterDataInfoItemSlotEquip
{
Slot = (short)Math.Abs(kv.Key % 100),
Item = kv.Value.ToStructured()
})
.ToList(),
Dragon = character.Inventories.Equip.Items
.Where(kv => kv.Key is >= -1100 and < -1000)
.Select(kv => new StructuredCharacterDataInfoItemSlotEquip
{
Slot = (short)Math.Abs(kv.Key % 100),
Item = kv.Value.ToStructured()
})
.ToList(),
Mechanic = character.Inventories.Equip.Items
.Where(kv => kv.Key is >= -1200 and < -1100)
.Select(kv => new StructuredCharacterDataInfoItemSlotEquip
{
Slot = (short)Math.Abs(kv.Key % 100),
Item = kv.Value.ToStructured()
})
.ToList(),
},
ItemSlotConsume = new StructuredCharacterDataInfoItemSlotBundles
{
Items = character.Inventories.Consume.Items
.Select(kv => new StructuredCharacterDataInfoItemSlotBundle
{
Slot = (byte)kv.Key,
Item = kv.Value.ToStructured()
})
.ToList(),
},
ItemSlotInstall = new StructuredCharacterDataInfoItemSlotBundles
{
Items = character.Inventories.Install.Items
.Select(kv => new StructuredCharacterDataInfoItemSlotBundle
{
Slot = (byte)kv.Key,
Item = kv.Value.ToStructured()
})
.ToList(),
},
ItemSlotEtc = new StructuredCharacterDataInfoItemSlotBundles
{
Items = character.Inventories.Etc.Items
.Select(kv => new StructuredCharacterDataInfoItemSlotBundle
{
Slot = (byte)kv.Key,
Item = kv.Value.ToStructured()
})
.ToList(),
},
ItemSlotCash = new StructuredCharacterDataInfoItemSlotBundles
{
Items = character.Inventories.Cash.Items
.Select(kv => new StructuredCharacterDataInfoItemSlotBundle
{
Slot = (byte)kv.Key,
Item = kv.Value.ToStructured()
})
.ToList(),
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,50 @@ namespace Edelstein.Protocol.Gameplay.Entities;

public record StructuredCharacterData : StructuredBasePacket, IBinarySerializable
{
[Ignore]
public byte CombatOrders { get; set; }
[Ignore] public byte CombatOrders { get; set; }
[Ignore] public byte Unk1 { get; set; }

[Ignore]
public byte Unk1 { get; set; }
[Ignore] public StructuredCharacterDataInfoCharacter? Character { get; set; }

[Ignore]
public StructuredCharacterDataInfoCharacter? Character { get; set; }
[Ignore] public int? Money { get; set; }

[Ignore] public StructuredCharacterDataInfoInventorySize? InventorySize { get; set; }

[Ignore] public StructuredCharacterDataInfoItemSlotEquips? ItemSlotEquip { get; set; }
[Ignore] public StructuredCharacterDataInfoItemSlotBundles? ItemSlotConsume { get; set; }
[Ignore] public StructuredCharacterDataInfoItemSlotBundles? ItemSlotInstall { get; set; }
[Ignore] public StructuredCharacterDataInfoItemSlotBundles? ItemSlotEtc { get; set; }
[Ignore] public StructuredCharacterDataInfoItemSlotBundles? ItemSlotCash { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
using var writer = new BinaryWriter(stream);
var flags = 0 |
(Character != null ? StructuredCharacterDataFlag.Character : 0);
var flags =
(Character != null ? StructuredCharacterDataFlag.Character : 0) |
(Money.HasValue ? StructuredCharacterDataFlag.Money : 0) |
(InventorySize != null ? StructuredCharacterDataFlag.InventorySize : 0) |
(ItemSlotEquip != null ? StructuredCharacterDataFlag.ItemSlotEquip : 0) |
(ItemSlotConsume != null ? StructuredCharacterDataFlag.ItemSlotConsume : 0) |
(ItemSlotInstall != null ? StructuredCharacterDataFlag.ItemSlotInstall : 0) |
(ItemSlotEtc != null ? StructuredCharacterDataFlag.ItemSlotEtc : 0) |
(ItemSlotCash != null ? StructuredCharacterDataFlag.ItemSlotCash : 0);

writer.Write((long)flags);
writer.Write(CombatOrders);
writer.Write(Unk1);

Character?.DispatchTo(stream);

if (Money.HasValue)
writer.Write(Money.Value);

InventorySize?.DispatchTo(stream);

ItemSlotEquip?.DispatchTo(stream);
ItemSlotConsume?.DispatchTo(stream);
ItemSlotInstall?.DispatchTo(stream);
ItemSlotEtc?.DispatchTo(stream);
ItemSlotCash?.DispatchTo(stream);
}
public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
Expand All @@ -38,5 +62,22 @@ public void Deserialize(Stream stream, Endianness endianness, BinarySerializatio

if (flags.HasFlag(StructuredCharacterDataFlag.Character))
Character = serializer.Deserialize<StructuredCharacterDataInfoCharacter>(stream);

if (flags.HasFlag(StructuredCharacterDataFlag.Money))
Money = reader.ReadInt32();

if (flags.HasFlag(StructuredCharacterDataFlag.InventorySize))
InventorySize = serializer.Deserialize<StructuredCharacterDataInfoInventorySize>(stream);

if (flags.HasFlag(StructuredCharacterDataFlag.ItemSlotEquip))
ItemSlotEquip = serializer.Deserialize<StructuredCharacterDataInfoItemSlotEquips>(stream);
if (flags.HasFlag(StructuredCharacterDataFlag.ItemSlotConsume))
ItemSlotConsume = serializer.Deserialize<StructuredCharacterDataInfoItemSlotBundles>(stream);
if (flags.HasFlag(StructuredCharacterDataFlag.ItemSlotInstall))
ItemSlotInstall = serializer.Deserialize<StructuredCharacterDataInfoItemSlotBundles>(stream);
if (flags.HasFlag(StructuredCharacterDataFlag.ItemSlotEtc))
ItemSlotEtc = serializer.Deserialize<StructuredCharacterDataInfoItemSlotBundles>(stream);
if (flags.HasFlag(StructuredCharacterDataFlag.ItemSlotCash))
ItemSlotCash = serializer.Deserialize<StructuredCharacterDataInfoItemSlotBundles>(stream);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using BinarySerialization;
using Edelstein.Protocol.Network.Packets;

namespace Edelstein.Protocol.Gameplay.Entities;

public record StructuredCharacterDataInfoInventorySize : StructuredBasePacket
{
[FieldOrder(0)]
public required byte Equip { get; set; }

[FieldOrder(1)]
public required byte Consume { get; set; }

[FieldOrder(2)]
public required byte Install { get; set; }

[FieldOrder(3)]
public required byte Etc { get; set; }

[FieldOrder(4)]
public required byte Cash { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using BinarySerialization;
using Edelstein.Protocol.Gameplay.Entities.Inventories;
using Edelstein.Protocol.Network.Packets;

namespace Edelstein.Protocol.Gameplay.Entities;

public record StructuredCharacterDataInfoItemSlotBundles : StructuredBasePacket
{
[FieldOrder(0)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotBundle> Items { get; init; }
}

public record StructuredCharacterDataInfoItemSlotBundle : StructuredBasePacket
{
[FieldOrder(0)]
public required byte Slot { get; init; }

[FieldOrder(1)]
public required StructuredItemSlot Item { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using BinarySerialization;
using Edelstein.Protocol.Gameplay.Entities.Inventories;
using Edelstein.Protocol.Network.Packets;

namespace Edelstein.Protocol.Gameplay.Entities;

public record StructuredCharacterDataInfoItemSlotEquips : StructuredBasePacket
{
[FieldOrder(0)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotEquip> Equipped { get; init; }

[FieldOrder(1)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotEquip> Equipped2 { get; init; }

[FieldOrder(2)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotEquip> Equip { get; init; }

[FieldOrder(3)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotEquip> Dragon { get; init; }

[FieldOrder(4)]
[SerializeUntil((short)0)]
public required List<StructuredCharacterDataInfoItemSlotEquip> Mechanic { get; init; }
}

public record StructuredCharacterDataInfoItemSlotEquip : StructuredBasePacket
{
[FieldOrder(0)]
public required short Slot { get; init; }

[FieldOrder(1)]
public required StructuredItemSlot Item { get; init; }
}

0 comments on commit 2eb7cc0

Please sign in to comment.