Skip to content

Commit c8f208b

Browse files
authored
Merge pull request #1 from darcymiranda/fix-byte-attribute-names
Refactor single byte attribute name serialization
2 parents d39bc8c + a457580 commit c8f208b

File tree

4 files changed

+20
-38
lines changed

4 files changed

+20
-38
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,7 @@ ASALocalRun/
337337
.localhistory/
338338

339339
# BeatPulse healthcheck temp database
340-
healthchecksdb
340+
healthchecksdb
341+
342+
src/PFire.Console/Logs/
343+
src/PFire.Console/*.sqlite*

src/PFire.Core/Protocol/MessageSerializer.cs

+12-34
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,23 @@ public static IMessage Deserialize(BinaryReader reader, IMessage messageBase)
3535

3636
for (var i = 0; i < attributeCount; i++)
3737
{
38-
var attributeName = GetAttributeName(reader, messageType);
38+
var attributeNameAsBytes = GetAttributeNameAsBytes(reader, messageType);
3939

4040
var attributeType = reader.ReadByte();
4141

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

4444
var field = fieldInfo
4545
.Where(a => a.GetCustomAttribute<XMessageField>() != null)
46-
.FirstOrDefault(a =>
47-
{
48-
var attribute = a.GetCustomAttribute<XMessageField>();
49-
if (attribute != null)
50-
{
51-
if (attributeName.Length == 1)
52-
{
53-
// If attributeName is a single byte, compare with the attribute's NameAsBytes
54-
return attribute.NameAsBytes.SequenceEqual(attributeName);
55-
}
56-
else
57-
{
58-
// If attributeName is a byte array with length > 1, compare with the attribute's Name converted to string
59-
return Encoding.UTF8.GetString(attributeName) == attribute.Name;
60-
}
61-
}
62-
return false;
63-
});
46+
.FirstOrDefault(a => a.GetCustomAttribute<XMessageField>().NameAsBytes.SequenceEqual(attributeNameAsBytes));
6447

6548
if (field != null)
6649
{
6750
field.SetValue(messageBase, value);
6851
}
6952
else
7053
{
71-
Debug.WriteLine($"WARN: No attribute defined for {attributeName} on class {messageType.Name}");
54+
Debug.WriteLine($"WARN: No attribute defined for {attributeNameAsBytes} on class {messageType.Name}");
7255
}
7356
}
7457

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

80-
private static byte[] GetAttributeName(BinaryReader reader, Type messageType)
63+
private static byte[] GetAttributeNameAsBytes(BinaryReader reader, Type messageType)
8164
{
82-
HashSet<Type> messageTypeSet = new HashSet<Type>
65+
// These messages contain a single field represented by a byte value instead of
66+
// the usual first byte representing the attribute name length.
67+
var messagesWithoutAttributeNames = new HashSet<Type>
8368
{
8469
typeof(StatusChange),
8570
typeof(GameServerFetchAll),
@@ -92,21 +77,14 @@ private static byte[] GetAttributeName(BinaryReader reader, Type messageType)
9277
typeof(UserRequestAdvancedInfo)
9378
};
9479

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

97-
// Check if count is 1, indicating a single byte
98-
if (count == 1)
99-
{
100-
// Read the single byte and treat it as a numeric value
101-
byte numericValue = reader.ReadByte();
102-
return [numericValue];
103-
}
104-
else
81+
if (messagesWithoutAttributeNames.Contains(messageType))
10582
{
106-
// Read the bytes for the attribute name
107-
var readBytes = reader.ReadBytes(count);
108-
return readBytes;
83+
return [reader.ReadByte()];
10984
}
85+
86+
var length = reader.ReadByte();
87+
return reader.ReadBytes(length);
11088
}
11189

11290
public static byte[] Serialize(IMessage message)

src/PFire.Core/Protocol/XFireAttributeFactory.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ public class XFireAttributeFactory
99
{
1010
private static readonly XFireAttributeFactory instance = null;
1111

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

14-
private static readonly byte[] IgnoreKnownUnimplementedTypes = {18};
14+
private static readonly byte[] IgnoreKnownUnimplementedTypes = [18];
1515

1616
private XFireAttributeFactory()
1717
{

src/PFire.Core/Protocol/XMessageField.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ internal sealed class XMessageField : Attribute
1313
public XMessageField(string name)
1414
{
1515
Name = name;
16+
NameAsBytes = Encoding.UTF8.GetBytes(name);
1617
}
1718

1819
public XMessageField(params byte[] name)
19-
//: this(Encoding.UTF8.GetString(name))
2020
{
21+
Name = Encoding.UTF8.GetString(name);
2122
NonTextualName = true;
2223
NameAsBytes = name;
2324
}

0 commit comments

Comments
 (0)