Skip to content

Commit

Permalink
Merge pull request #1 from darcymiranda/fix-byte-attribute-names
Browse files Browse the repository at this point in the history
Refactor single byte attribute name serialization
  • Loading branch information
desukuran authored May 11, 2024
2 parents d39bc8c + a457580 commit c8f208b
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 38 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,7 @@ ASALocalRun/
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb

src/PFire.Console/Logs/
src/PFire.Console/*.sqlite*
46 changes: 12 additions & 34 deletions src/PFire.Core/Protocol/MessageSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,23 @@ public static IMessage Deserialize(BinaryReader reader, IMessage messageBase)

for (var i = 0; i < attributeCount; i++)
{
var attributeName = GetAttributeName(reader, messageType);
var attributeNameAsBytes = GetAttributeNameAsBytes(reader, messageType);

var attributeType = reader.ReadByte();

var value = XFireAttributeFactory.Instance.GetAttribute(attributeType).ReadValue(reader);

var field = fieldInfo
.Where(a => a.GetCustomAttribute<XMessageField>() != null)
.FirstOrDefault(a =>
{
var attribute = a.GetCustomAttribute<XMessageField>();
if (attribute != null)
{
if (attributeName.Length == 1)
{
// If attributeName is a single byte, compare with the attribute's NameAsBytes
return attribute.NameAsBytes.SequenceEqual(attributeName);
}
else
{
// If attributeName is a byte array with length > 1, compare with the attribute's Name converted to string
return Encoding.UTF8.GetString(attributeName) == attribute.Name;
}
}
return false;
});
.FirstOrDefault(a => a.GetCustomAttribute<XMessageField>().NameAsBytes.SequenceEqual(attributeNameAsBytes));

if (field != null)
{
field.SetValue(messageBase, value);
}
else
{
Debug.WriteLine($"WARN: No attribute defined for {attributeName} on class {messageType.Name}");
Debug.WriteLine($"WARN: No attribute defined for {attributeNameAsBytes} on class {messageType.Name}");
}
}

Expand All @@ -77,9 +60,11 @@ public static IMessage Deserialize(BinaryReader reader, IMessage messageBase)
return messageBase;
}

private static byte[] GetAttributeName(BinaryReader reader, Type messageType)
private static byte[] GetAttributeNameAsBytes(BinaryReader reader, Type messageType)
{
HashSet<Type> messageTypeSet = new HashSet<Type>
// These messages contain a single field represented by a byte value instead of
// the usual first byte representing the attribute name length.
var messagesWithoutAttributeNames = new HashSet<Type>
{
typeof(StatusChange),
typeof(GameServerFetchAll),
Expand All @@ -92,21 +77,14 @@ private static byte[] GetAttributeName(BinaryReader reader, Type messageType)
typeof(UserRequestAdvancedInfo)
};

byte count = messageTypeSet.Contains(messageType) ? (byte)1 : reader.ReadByte();

// Check if count is 1, indicating a single byte
if (count == 1)
{
// Read the single byte and treat it as a numeric value
byte numericValue = reader.ReadByte();
return [numericValue];
}
else
if (messagesWithoutAttributeNames.Contains(messageType))
{
// Read the bytes for the attribute name
var readBytes = reader.ReadBytes(count);
return readBytes;
return [reader.ReadByte()];
}

var length = reader.ReadByte();
return reader.ReadBytes(length);
}

public static byte[] Serialize(IMessage message)
Expand Down
4 changes: 2 additions & 2 deletions src/PFire.Core/Protocol/XFireAttributeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ public class XFireAttributeFactory
{
private static readonly XFireAttributeFactory instance = null;

private readonly Dictionary<byte, XFireAttribute> _attributeTypes = new Dictionary<byte, XFireAttribute>();
private readonly Dictionary<byte, XFireAttribute> _attributeTypes = [];

private static readonly byte[] IgnoreKnownUnimplementedTypes = {18};
private static readonly byte[] IgnoreKnownUnimplementedTypes = [18];

private XFireAttributeFactory()
{
Expand Down
3 changes: 2 additions & 1 deletion src/PFire.Core/Protocol/XMessageField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ internal sealed class XMessageField : Attribute
public XMessageField(string name)
{
Name = name;
NameAsBytes = Encoding.UTF8.GetBytes(name);
}

public XMessageField(params byte[] name)
//: this(Encoding.UTF8.GetString(name))
{
Name = Encoding.UTF8.GetString(name);
NonTextualName = true;
NameAsBytes = name;
}
Expand Down

0 comments on commit c8f208b

Please sign in to comment.