mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
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:
commit
43e4eac24b
2 changed files with 51 additions and 11 deletions
|
|
@ -5,6 +5,13 @@ using System.Linq;
|
|||
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -148,6 +155,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
|||
Int16 = 0xF2,
|
||||
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
|
||||
Int24Packed = 0xFC, // used in map links- sometimes short+byte, sometimes... not??
|
||||
Int24 = 0xFA,
|
||||
Int32 = 0xFE
|
||||
}
|
||||
|
|
@ -189,6 +197,8 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
|||
|
||||
case IntegerType.Int24Special:
|
||||
// Fallthrough - same logic
|
||||
case IntegerType.Int24Packed:
|
||||
// fallthrough again
|
||||
case IntegerType.Int24:
|
||||
{
|
||||
var v = 0;
|
||||
|
|
@ -267,6 +277,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
|||
var type = bytes.Length switch
|
||||
{
|
||||
4 => IntegerType.Int32,
|
||||
3 => IntegerType.Int24Packed,
|
||||
2 => IntegerType.Int16Packed,
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
|
|
@ -276,17 +287,32 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
|||
|
||||
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);
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,13 +72,27 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
|||
|
||||
protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
|
||||
{
|
||||
(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)
|
||||
// for debugging for now
|
||||
var oldPos = reader.BaseStream.Position;
|
||||
var bytes = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position));
|
||||
reader.BaseStream.Position = oldPos;
|
||||
|
||||
// seems to always be FF 01
|
||||
reader.ReadBytes(2);
|
||||
try
|
||||
{
|
||||
(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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue