improve payload parsing of item links

This commit is contained in:
meli 2019-11-21 15:11:27 -08:00
parent 28e348d5f0
commit 766b777f74

View file

@ -14,29 +14,42 @@ namespace Dalamud.Game.Chat {
PlayerLink = 0x27
}
// in all likelihood these are flags of some kind, but these are the only 2 values I've noticed
public enum ItemQuality {
NormalQuality = 0xF2,
HighQuality = 0xF6
}
private const int START_BYTE = 0x02;
private const int END_BYTE = 0x03;
public static (string Output, List<SeStringPayloadContainer> Payloads) Parse(string input) {
public static (string Output, List<SeStringPayloadContainer> Payloads) Parse(byte[] bytes)
{
var output = new List<byte>();
var payloads = new List<SeStringPayloadContainer>();
var bytes = Encoding.UTF8.GetBytes(input);
using (var stream = new MemoryStream(bytes))
using (var reader = new BinaryReader(stream)) {
while (stream.Position < bytes.Length) {
using (var reader = new BinaryReader(stream))
{
while (stream.Position < bytes.Length)
{
var b = stream.ReadByte();
if (b == START_BYTE)
ProcessPacket(reader, output, payloads);
else
output.Add((byte) b);
output.Add((byte)b);
}
}
return (Encoding.UTF8.GetString(output.ToArray()), payloads);
}
public static (string Output, List<SeStringPayloadContainer> Payloads) Parse(string input) {
var bytes = Encoding.UTF8.GetBytes(input);
return Parse(bytes);
}
private static void ProcessPacket(BinaryReader reader, List<byte> output,
List<SeStringPayloadContainer> payloads) {
var type = reader.ReadByte();
@ -54,11 +67,27 @@ namespace Dalamud.Game.Chat {
switch ((SeStringPayloadType) type) {
case SeStringPayloadType.PlayerLink:
if (payload[0] == (byte) PlayerLinkType.ItemLink)
payloads.Add(new SeStringPayloadContainer {
if (payload[0] == (byte)PlayerLinkType.ItemLink)
{
int itemId;
if ((ItemQuality)payload[1] == ItemQuality.HighQuality)
{
// hq items have an extra 0x0F byte before the ID, and the ID is 0x4240 above the actual item ID
// This _seems_ consistent but I really don't know
itemId = (payload[3] << 8 | payload[4]) - 0x4240;
}
else
{
itemId = (payload[2] << 8 | payload[3]);
}
payloads.Add(new SeStringPayloadContainer
{
Type = SeStringPayloadType.PlayerLink,
Param1 = BitConverter.ToInt16(payload, 4)
Param1 = itemId
});
}
break;
}
}