fixup string handling to use uints, since everything is realistically unsigned, and it can break encoding of actual 32-bit values otherwise

This commit is contained in:
meli 2020-04-02 22:17:24 -07:00
parent 6d50cdc398
commit 8fbac95b6b
6 changed files with 35 additions and 34 deletions

View file

@ -105,8 +105,8 @@ namespace Dalamud.Game.Chat.SeStringHandling
payload?.ProcessChunkImpl(reader, reader.BaseStream.Position + chunkLen - 1);
// read through the rest of the packet
var readBytes = (int)(reader.BaseStream.Position - packetStart);
reader.ReadBytes(chunkLen - readBytes + 1); // +1 for the END_BYTE marker
var readBytes = (uint)(reader.BaseStream.Position - packetStart);
reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker
return payload;
}
@ -157,20 +157,20 @@ namespace Dalamud.Game.Chat.SeStringHandling
// made protected, unless we actually want to use it externally
// in which case it should probably go live somewhere else
protected static int GetInteger(BinaryReader input)
protected static uint GetInteger(BinaryReader input)
{
var t = input.ReadByte();
var type = (IntegerType)t;
return GetInteger(input, type);
}
private static int GetInteger(BinaryReader input, IntegerType type)
private static uint GetInteger(BinaryReader input, IntegerType type)
{
const byte ByteLengthCutoff = 0xF0;
var t = (byte)type;
if (t < ByteLengthCutoff)
return t - 1;
return (uint)(t - 1);
switch (type)
{
@ -178,7 +178,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
return input.ReadByte();
case IntegerType.ByteTimes256:
return input.ReadByte() * 256;
return input.ReadByte() * (uint)256;
case IntegerType.Int16:
// fallthrough - same logic
@ -187,7 +187,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
var v = 0;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
return (uint)v;
}
case IntegerType.Int24Special:
@ -198,7 +198,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
return (uint)v;
}
case IntegerType.Int32:
@ -208,7 +208,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
return (uint)v;
}
default:
@ -216,10 +216,10 @@ namespace Dalamud.Game.Chat.SeStringHandling
}
}
protected virtual byte[] MakeInteger(int value, bool withMarker = true)
protected virtual byte[] MakeInteger(uint value, bool withMarker = true, bool incrementSmallInts = true) // TODO: better way to handle this
{
// single-byte values below the marker values have no marker and have 1 added
if (value + 1 < (int)IntegerType.Byte)
if (incrementSmallInts && (value + 1 < (int)IntegerType.Byte))
{
value++;
return new byte[] { (byte)value };
@ -266,9 +266,10 @@ namespace Dalamud.Game.Chat.SeStringHandling
protected virtual byte GetMarkerForPackedIntegerBytes(byte[] bytes)
{
// So far I've only ever seen this with 2 8-bit values packed into a short
// unsure if any 'strange' size groupings exist; only ever seen these
var type = bytes.Length switch
{
4 => IntegerType.Int32,
2 => IntegerType.Int16Packed,
_ => throw new NotSupportedException()
};
@ -276,25 +277,25 @@ namespace Dalamud.Game.Chat.SeStringHandling
return (byte)type;
}
protected (int, int) GetPackedIntegers(BinaryReader input)
protected (uint, uint) GetPackedIntegers(BinaryReader input)
{
var value = (uint)GetInteger(input);
var value = GetInteger(input);
if (value > 0xFFFF)
{
return ((int)((value & 0xFFFF0000) >> 16), (int)(value & 0xFFFF));
return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF));
}
else if (value > 0xFF)
{
return ((int)((value & 0xFF00) >> 8), (int)(value & 0xFF));
return ((uint)((value & 0xFF00) >> 8), (uint)(value & 0xFF));
}
// unsure if there are other cases, like "odd" pairings of 2+1 bytes etc
throw new NotSupportedException();
}
protected byte[] MakePackedInteger(int val1, int val2, bool withMarker = true)
protected byte[] MakePackedInteger(uint val1, uint val2, bool withMarker = true)
{
var value = MakeInteger(val1, false).Concat(MakeInteger(val2, false)).ToArray();
var value = MakeInteger(val1, false, false).Concat(MakeInteger(val2, false, false)).ToArray();
var valueBytes = new List<byte>();
if (withMarker)

View file

@ -11,13 +11,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{
public override PayloadType Type => PayloadType.Item;
public int ItemId { get; private set; }
public uint ItemId { get; private set; }
public string ItemName { get; private set; } = string.Empty;
public bool IsHQ { get; private set; } = false;
public ItemPayload() { }
public ItemPayload(int itemId, bool isHQ)
public ItemPayload(uint itemId, bool isHQ)
{
ItemId = itemId;
IsHQ = isHQ;
@ -27,7 +27,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{
if (string.IsNullOrEmpty(ItemName))
{
dynamic item = XivApi.GetItem(ItemId).GetAwaiter().GetResult();
dynamic item = XivApi.GetItem((int)ItemId).GetAwaiter().GetResult();
ItemName = item.Name;
}
}
@ -106,7 +106,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
// unk
reader.ReadBytes(3);
var itemNameLen = GetInteger(reader);
var itemNameLen = (int)GetInteger(reader);
var itemNameBytes = reader.ReadBytes(itemNameLen);
// HQ items have the HQ symbol as part of the name, but since we already recorded

View file

@ -10,8 +10,8 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
public override PayloadType Type => PayloadType.MapLink;
// pre-Resolve() values
public int TerritoryTypeId { get; set; }
public int MapId { get; set; }
public uint TerritoryTypeId { get; set; }
public uint MapId { get; set; }
public uint RawX { get; set; }
public uint RawY { get; set; }
@ -29,8 +29,8 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
// eventually we should allow creation using 'nice' values that then encode properly
var packedTerritoryAndMapBytes = MakePackedInteger(TerritoryTypeId, MapId);
var xBytes = MakeInteger((int)RawX);
var yBytes = MakeInteger((int)RawY);
var xBytes = MakeInteger(RawX);
var yBytes = MakeInteger(RawY);
var chunkLen = 4 + packedTerritoryAndMapBytes.Length + xBytes.Length + yBytes.Length;
@ -54,11 +54,11 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{
if (string.IsNullOrEmpty(Territory))
{
var terrRow = dataResolver.GetExcelSheet<TerritoryType>().GetRow(TerritoryTypeId);
var terrRow = dataResolver.GetExcelSheet<TerritoryType>().GetRow((int)TerritoryTypeId);
Territory = dataResolver.GetExcelSheet<PlaceName>().GetRow(terrRow.PlaceName).Name;
Zone = dataResolver.GetExcelSheet<PlaceName>().GetRow(terrRow.PlaceNameZone).Name;
var mapSizeFactor = dataResolver.GetExcelSheet<Map>().GetRow(MapId).SizeFactor;
var mapSizeFactor = dataResolver.GetExcelSheet<Map>().GetRow((int)MapId).SizeFactor;
XCoord = ConvertRawPositionToMapCoordinate(RawX, mapSizeFactor);
YCoord = ConvertRawPositionToMapCoordinate(RawY, mapSizeFactor);
}

View file

@ -12,12 +12,12 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
public override PayloadType Type => PayloadType.Player;
public string PlayerName { get; private set; }
public int ServerId { get; private set; }
public uint ServerId { get; private set; }
public string ServerName { get; private set; } = String.Empty;
public PlayerPayload() { }
public PlayerPayload(string playerName, int serverId)
public PlayerPayload(string playerName, uint serverId)
{
PlayerName = playerName;
ServerId = serverId;
@ -78,7 +78,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
// unk
reader.ReadBytes(2);
var nameLen = GetInteger(reader);
var nameLen = (int)GetInteger(reader);
PlayerName = Encoding.UTF8.GetString(reader.ReadBytes(nameLen));
}
}

View file

@ -11,13 +11,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{
public override PayloadType Type => PayloadType.Status;
public int StatusId { get; private set; }
public uint StatusId { get; private set; }
public string StatusName { get; private set; } = string.Empty;
public StatusPayload() { }
public StatusPayload(int statusId)
public StatusPayload(uint statusId)
{
StatusId = statusId;
}

View file

@ -187,7 +187,7 @@ namespace Dalamud.Game {
if (!valueInfo.Success || !int.TryParse(valueInfo.Value.Replace(",", "").Replace(".", ""), out var itemValue))
continue;
Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale(itemLink.ItemId, itemValue, itemLink.IsHQ));
Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale((int)itemLink.ItemId, itemValue, itemLink.IsHQ));
break;
}
}