diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/PlayerPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/PlayerPayload.cs
index 07a13e5a3..55697782e 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/PlayerPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/PlayerPayload.cs
@@ -6,6 +6,9 @@ using Dalamud.Data;
using Lumina.Excel;
using Lumina.Excel.Sheets;
+using Lumina.Text.Payloads;
+using Lumina.Text.ReadOnly;
+
using Newtonsoft.Json;
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
@@ -84,50 +87,32 @@ public class PlayerPayload : Payload
///
protected override byte[] EncodeImpl()
{
- var chunkLen = this.playerName.Length + 7;
- var bytes = new List()
- {
- START_BYTE,
- (byte)SeStringChunkType.Interactable, (byte)chunkLen, (byte)EmbeddedInfoType.PlayerName,
- /* unk */ 0x01,
- (byte)(this.serverId + 1), // I didn't want to deal with single-byte values in MakeInteger, so we have to do the +1 manually
- /* unk */ 0x01,
- /* unk */ 0xFF, // these sometimes vary but are frequently this
- (byte)(this.playerName.Length + 1),
- };
-
- bytes.AddRange(Encoding.UTF8.GetBytes(this.playerName));
- bytes.Add(END_BYTE);
-
- // TODO: should these really be here? additional payloads should come in separately already...
-
- // encoded names are followed by the name in plain text again
- // use the payload parsing for consistency, as this is technically a new chunk
- bytes.AddRange(new TextPayload(this.playerName).Encode());
-
- // unsure about this entire packet, but it seems to always follow a name
- bytes.AddRange(new byte[]
- {
- START_BYTE, (byte)SeStringChunkType.Interactable, 0x07, (byte)EmbeddedInfoType.LinkTerminator,
- 0x01, 0x01, 0x01, 0xFF, 0x01,
- END_BYTE,
- });
-
- return bytes.ToArray();
+ var ssb = Lumina.Text.SeStringBuilder.SharedPool.Get();
+ var res = ssb
+ .PushLinkCharacter(this.playerName, this.serverId)
+ .Append(this.playerName)
+ .PopLink()
+ .ToArray();
+ Lumina.Text.SeStringBuilder.SharedPool.Return(ssb);
+ return res;
}
///
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
{
- // unk
- reader.ReadByte();
+ var body = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position));
+ var rosps = new ReadOnlySePayloadSpan(ReadOnlySePayloadType.Macro, MacroCode.Link, body.AsSpan());
- this.serverId = GetInteger(reader);
+ if (!rosps.TryGetExpression(out _, out var worldIdExpression, out _, out var characterNameExpression))
+ return;
- // unk
- reader.ReadBytes(2);
+ if (!worldIdExpression.TryGetUInt(out var worldId))
+ return;
- var nameLen = (int)GetInteger(reader);
- this.playerName = Encoding.UTF8.GetString(reader.ReadBytes(nameLen));
+ if (!characterNameExpression.TryGetString(out var characterName))
+ return;
+
+ this.serverId = worldId;
+ this.playerName = characterName.ExtractText();
}
}