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); payload?.ProcessChunkImpl(reader, reader.BaseStream.Position + chunkLen - 1);
// read through the rest of the packet // read through the rest of the packet
var readBytes = (int)(reader.BaseStream.Position - packetStart); var readBytes = (uint)(reader.BaseStream.Position - packetStart);
reader.ReadBytes(chunkLen - readBytes + 1); // +1 for the END_BYTE marker reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker
return payload; return payload;
} }
@ -157,20 +157,20 @@ namespace Dalamud.Game.Chat.SeStringHandling
// made protected, unless we actually want to use it externally // made protected, unless we actually want to use it externally
// in which case it should probably go live somewhere else // 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 t = input.ReadByte();
var type = (IntegerType)t; var type = (IntegerType)t;
return GetInteger(input, type); return GetInteger(input, type);
} }
private static int GetInteger(BinaryReader input, IntegerType type) private static uint GetInteger(BinaryReader input, IntegerType type)
{ {
const byte ByteLengthCutoff = 0xF0; const byte ByteLengthCutoff = 0xF0;
var t = (byte)type; var t = (byte)type;
if (t < ByteLengthCutoff) if (t < ByteLengthCutoff)
return t - 1; return (uint)(t - 1);
switch (type) switch (type)
{ {
@ -178,7 +178,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
return input.ReadByte(); return input.ReadByte();
case IntegerType.ByteTimes256: case IntegerType.ByteTimes256:
return input.ReadByte() * 256; return input.ReadByte() * (uint)256;
case IntegerType.Int16: case IntegerType.Int16:
// fallthrough - same logic // fallthrough - same logic
@ -187,7 +187,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
var v = 0; var v = 0;
v |= input.ReadByte() << 8; v |= input.ReadByte() << 8;
v |= input.ReadByte(); v |= input.ReadByte();
return v; return (uint)v;
} }
case IntegerType.Int24Special: case IntegerType.Int24Special:
@ -198,7 +198,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
v |= input.ReadByte() << 16; v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8; v |= input.ReadByte() << 8;
v |= input.ReadByte(); v |= input.ReadByte();
return v; return (uint)v;
} }
case IntegerType.Int32: case IntegerType.Int32:
@ -208,7 +208,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
v |= input.ReadByte() << 16; v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8; v |= input.ReadByte() << 8;
v |= input.ReadByte(); v |= input.ReadByte();
return v; return (uint)v;
} }
default: 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 // 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++; value++;
return new byte[] { (byte)value }; return new byte[] { (byte)value };
@ -266,9 +266,10 @@ namespace Dalamud.Game.Chat.SeStringHandling
protected virtual byte GetMarkerForPackedIntegerBytes(byte[] bytes) 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 var type = bytes.Length switch
{ {
4 => IntegerType.Int32,
2 => IntegerType.Int16Packed, 2 => IntegerType.Int16Packed,
_ => throw new NotSupportedException() _ => throw new NotSupportedException()
}; };
@ -276,25 +277,25 @@ namespace Dalamud.Game.Chat.SeStringHandling
return (byte)type; 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) if (value > 0xFFFF)
{ {
return ((int)((value & 0xFFFF0000) >> 16), (int)(value & 0xFFFF)); return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF));
} }
else if (value > 0xFF) 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 // unsure if there are other cases, like "odd" pairings of 2+1 bytes etc
throw new NotSupportedException(); 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>(); var valueBytes = new List<byte>();
if (withMarker) if (withMarker)

View file

@ -11,13 +11,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{ {
public override PayloadType Type => PayloadType.Item; 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 string ItemName { get; private set; } = string.Empty;
public bool IsHQ { get; private set; } = false; public bool IsHQ { get; private set; } = false;
public ItemPayload() { } public ItemPayload() { }
public ItemPayload(int itemId, bool isHQ) public ItemPayload(uint itemId, bool isHQ)
{ {
ItemId = itemId; ItemId = itemId;
IsHQ = isHQ; IsHQ = isHQ;
@ -27,7 +27,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{ {
if (string.IsNullOrEmpty(ItemName)) if (string.IsNullOrEmpty(ItemName))
{ {
dynamic item = XivApi.GetItem(ItemId).GetAwaiter().GetResult(); dynamic item = XivApi.GetItem((int)ItemId).GetAwaiter().GetResult();
ItemName = item.Name; ItemName = item.Name;
} }
} }
@ -106,7 +106,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
// unk // unk
reader.ReadBytes(3); reader.ReadBytes(3);
var itemNameLen = GetInteger(reader); var itemNameLen = (int)GetInteger(reader);
var itemNameBytes = reader.ReadBytes(itemNameLen); var itemNameBytes = reader.ReadBytes(itemNameLen);
// HQ items have the HQ symbol as part of the name, but since we already recorded // 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; public override PayloadType Type => PayloadType.MapLink;
// pre-Resolve() values // pre-Resolve() values
public int TerritoryTypeId { get; set; } public uint TerritoryTypeId { get; set; }
public int MapId { get; set; } public uint MapId { get; set; }
public uint RawX { get; set; } public uint RawX { get; set; }
public uint RawY { 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 // eventually we should allow creation using 'nice' values that then encode properly
var packedTerritoryAndMapBytes = MakePackedInteger(TerritoryTypeId, MapId); var packedTerritoryAndMapBytes = MakePackedInteger(TerritoryTypeId, MapId);
var xBytes = MakeInteger((int)RawX); var xBytes = MakeInteger(RawX);
var yBytes = MakeInteger((int)RawY); var yBytes = MakeInteger(RawY);
var chunkLen = 4 + packedTerritoryAndMapBytes.Length + xBytes.Length + yBytes.Length; var chunkLen = 4 + packedTerritoryAndMapBytes.Length + xBytes.Length + yBytes.Length;
@ -54,11 +54,11 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
{ {
if (string.IsNullOrEmpty(Territory)) 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; Territory = dataResolver.GetExcelSheet<PlaceName>().GetRow(terrRow.PlaceName).Name;
Zone = dataResolver.GetExcelSheet<PlaceName>().GetRow(terrRow.PlaceNameZone).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); XCoord = ConvertRawPositionToMapCoordinate(RawX, mapSizeFactor);
YCoord = ConvertRawPositionToMapCoordinate(RawY, mapSizeFactor); YCoord = ConvertRawPositionToMapCoordinate(RawY, mapSizeFactor);
} }

View file

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

View file

@ -187,7 +187,7 @@ namespace Dalamud.Game {
if (!valueInfo.Success || !int.TryParse(valueInfo.Value.Replace(",", "").Replace(".", ""), out var itemValue)) if (!valueInfo.Success || !int.TryParse(valueInfo.Value.Replace(",", "").Replace(".", ""), out var itemValue))
continue; 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; break;
} }
} }