Merge pull request #86 from ff-meli/master

Add partial support for FC integer marker in string payloads; some ca…
This commit is contained in:
goaaats 2020-04-21 19:57:30 +02:00 committed by GitHub
commit 43e4eac24b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 11 deletions

View file

@ -5,6 +5,13 @@ using System.Linq;
using Dalamud.Game.Chat.SeStringHandling.Payloads; using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Serilog; using Serilog;
// TODOs:
// - refactor integer handling now that we have multiple packed types
// - common construction/property design for subclasses
// - lumina DI
// - design for handling raw values vs resolved values, both for input and output
// - wrapper class(es) for handling of composite links in chat (item, map etc) and formatting operations
namespace Dalamud.Game.Chat.SeStringHandling namespace Dalamud.Game.Chat.SeStringHandling
{ {
/// <summary> /// <summary>
@ -148,6 +155,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
Int16 = 0xF2, Int16 = 0xF2,
Int16Packed = 0xF4, // seen in map links, seemingly 2 8-bit values packed into 2 bytes with only one marker Int16Packed = 0xF4, // seen in map links, seemingly 2 8-bit values packed into 2 bytes with only one marker
Int24Special = 0xF6, // unsure how different form Int24 - used for hq items that add 1 million, also used for normal 24-bit values in map links Int24Special = 0xF6, // unsure how different form Int24 - used for hq items that add 1 million, also used for normal 24-bit values in map links
Int24Packed = 0xFC, // used in map links- sometimes short+byte, sometimes... not??
Int24 = 0xFA, Int24 = 0xFA,
Int32 = 0xFE Int32 = 0xFE
} }
@ -189,6 +197,8 @@ namespace Dalamud.Game.Chat.SeStringHandling
case IntegerType.Int24Special: case IntegerType.Int24Special:
// Fallthrough - same logic // Fallthrough - same logic
case IntegerType.Int24Packed:
// fallthrough again
case IntegerType.Int24: case IntegerType.Int24:
{ {
var v = 0; var v = 0;
@ -267,6 +277,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
var type = bytes.Length switch var type = bytes.Length switch
{ {
4 => IntegerType.Int32, 4 => IntegerType.Int32,
3 => IntegerType.Int24Packed,
2 => IntegerType.Int16Packed, 2 => IntegerType.Int16Packed,
_ => throw new NotSupportedException() _ => throw new NotSupportedException()
}; };
@ -276,17 +287,32 @@ namespace Dalamud.Game.Chat.SeStringHandling
protected (uint, uint) GetPackedIntegers(BinaryReader input) protected (uint, uint) GetPackedIntegers(BinaryReader input)
{ {
// HACK - this was already a hack, but the addition of Int24Packed made it even worse
// All of this should be redone/removed at some point
var marker = (IntegerType)input.ReadByte();
input.BaseStream.Position--;
var value = GetInteger(input); var value = GetInteger(input);
if (value > 0xFFFF)
if (marker == IntegerType.Int24Packed)
{ {
return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF)); return ((uint)((value & 0xFFFF00) >> 8), (uint)(value & 0xFF));
} }
else if (value > 0xFF) // this used to be the catchall before Int24Packed; leave it for now to ensure we handle all encodings
else // if (marker == IntegerType.Int16Packed || marker == IntegerType.Int32)
{ {
return ((uint)((value & 0xFF00) >> 8), (uint)(value & 0xFF)); if (value > 0xFFFF)
{
return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF));
}
else if (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
throw new NotSupportedException(); throw new NotSupportedException();
} }

View file

@ -72,13 +72,27 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream) protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
{ {
(TerritoryTypeId, MapId) = GetPackedIntegers(reader); // for debugging for now
RawX = (uint)GetInteger(reader); var oldPos = reader.BaseStream.Position;
RawY = (uint)GetInteger(reader); var bytes = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position));
// the Z coordinate is never in this chunk, just the text (if applicable) reader.BaseStream.Position = oldPos;
// seems to always be FF 01 try
reader.ReadBytes(2); {
(TerritoryTypeId, MapId) = GetPackedIntegers(reader);
RawX = (uint)GetInteger(reader);
RawY = (uint)GetInteger(reader);
// the Z coordinate is never in this chunk, just the text (if applicable)
// seems to always be FF 01
reader.ReadBytes(2);
}
catch (NotSupportedException)
{
Serilog.Log.Information($"Unsupported map bytes {BitConverter.ToString(bytes).Replace("-", " ")}");
// we still want to break here for now, or we'd just throw again later
throw;
}
} }
#region ugliness #region ugliness