From 2d5fdd3c4c471570c9dfb93f6997cf496c05b4c7 Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Wed, 22 Apr 2020 08:51:24 -0700 Subject: [PATCH] payload constructors for user-created payloads --- Dalamud/Game/Chat/SeStringHandling/Payload.cs | 2 +- .../Payloads/AutoTranslatePayload.cs | 10 ++++ .../SeStringHandling/Payloads/ItemPayload.cs | 9 ++++ .../Payloads/MapLinkPayload.cs | 53 ++++++++++++++----- .../Payloads/PlayerPayload.cs | 15 +++--- .../SeStringHandling/Payloads/RawPayload.cs | 28 +++++++--- .../Payloads/StatusPayload.cs | 7 +++ .../SeStringHandling/Payloads/TextPayload.cs | 7 +++ .../Payloads/UIForegroundPayload.cs | 7 +++ .../Payloads/UIGlowPayload.cs | 7 +++ 10 files changed, 119 insertions(+), 26 deletions(-) diff --git a/Dalamud/Game/Chat/SeStringHandling/Payload.cs b/Dalamud/Game/Chat/SeStringHandling/Payload.cs index 0eaf4ee9e..519cd1e5c 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payload.cs @@ -35,7 +35,7 @@ namespace Dalamud.Game.Chat.SeStringHandling protected byte[] encodedData; - public Payload() + protected Payload() { // this is not a good way to do this, but I don't want to have to include a dalamud // reference on multiple methods in every payload class diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs index 7d81dc624..eadf0074f 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs @@ -27,6 +27,16 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private uint group; private uint key; + internal AutoTranslatePayload() { } + + public AutoTranslatePayload(uint group, uint key) + { + this.group = group; + this.key = key; + } + + // TODO: friendlier ctor? not sure how to handle that given how weird the tables are + public override string ToString() { return $"{Type} - Group: {group}, Key: {key}"; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs index ffc27af3e..cda7e33a8 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs @@ -41,6 +41,15 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private uint itemId; + internal ItemPayload() { } + + public ItemPayload(uint itemId, bool isHQ, string displayNameOverride = null) + { + this.itemId = itemId; + this.IsHQ = isHQ; + this.displayName = displayNameOverride; + } + public override string ToString() { return $"{Type} - ItemId: {itemId}, IsHQ: {IsHQ}"; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs index beaa80e3a..7b78b0423 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs @@ -46,6 +46,18 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + public string CoordinateString + { + get + { + // this truncates the values to one decimal without rounding, which is what the game does + var x = Math.Truncate(XCoord * 10.0f) / 10.0f; + var y = Math.Truncate(YCoord * 10.0f) / 10.0f; + + return $"( {x.ToString("0.0")}, {y.ToString("0.0")} )"; + } + } + private string placeNameRegion; public string PlaceNameRegion { @@ -66,14 +78,32 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } - public string DataString => $"m:{TerritoryType.RowId},{Map.RowId},{unchecked((int)rawX)},{unchecked((int)rawY)}"; + public string DataString => $"m:{TerritoryType.RowId},{Map.RowId},{rawX},{rawY}"; private uint territoryTypeId; private uint mapId; - private uint rawX; - private uint rawY; + private int rawX; + private int rawY; // there is no Z; it's purely in the text payload where applicable + internal MapLinkPayload() { } + + public MapLinkPayload(uint territoryTypeId, uint mapId, float niceXCoord, float niceYCoord) + { + this.territoryTypeId = territoryTypeId; + this.mapId = mapId; + this.rawX = this.ConvertMapCoordinateToRawPosition(niceXCoord, Map.SizeFactor); + this.rawY = this.ConvertMapCoordinateToRawPosition(niceYCoord, Map.SizeFactor); + } + + public MapLinkPayload(uint territoryTypeId, uint mapId, int rawX, int rawY) + { + this.territoryTypeId = territoryTypeId; + this.mapId = mapId; + this.rawX = rawX; + this.rawY = rawY; + } + public override string ToString() { return $"{Type} - TerritoryTypeId: {territoryTypeId}, MapId: {mapId}, RawX: {rawX}, RawY: {rawY}"; @@ -81,12 +111,9 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads protected override byte[] EncodeImpl() { - // TODO: for now we just encode the raw/internal values - // eventually we should allow creation using 'nice' values that then encode properly - var packedTerritoryAndMapBytes = MakePackedInteger(this.territoryTypeId, this.mapId); - var xBytes = MakeInteger(this.rawX); - var yBytes = MakeInteger(this.rawY); + var xBytes = MakeInteger(unchecked((uint)this.rawX)); + var yBytes = MakeInteger(unchecked((uint)this.rawY)); var chunkLen = 4 + packedTerritoryAndMapBytes.Length + xBytes.Length + yBytes.Length; @@ -116,8 +143,8 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads try { (this.territoryTypeId, this.mapId) = GetPackedIntegers(reader); - this.rawX = (uint)GetInteger(reader); - this.rawY = (uint)GetInteger(reader); + this.rawX = unchecked((int)GetInteger(reader)); + this.rawY = unchecked((int)GetInteger(reader)); // the Z coordinate is never in this chunk, just the text (if applicable) // seems to always be FF 01 @@ -134,16 +161,16 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads #region ugliness // from https://github.com/xivapi/ffxiv-datamining/blob/master/docs/MapCoordinates.md // extra 1/1000 because that is how the network ints are done - private float ConvertRawPositionToMapCoordinate(uint pos, float scale) + private float ConvertRawPositionToMapCoordinate(int pos, float scale) { var c = scale / 100.0f; - var scaledPos = (int)pos * c / 1000.0f; + var scaledPos = pos * c / 1000.0f; return ((41.0f / c) * ((scaledPos + 1024.0f) / 2048.0f)) + 1.0f; } // Created as the inverse of ConvertRawPositionToMapCoordinate(), since no one seemed to have a version of that - private float ConvertMapCoordinateToRawPosition(float pos, float scale) + private int ConvertMapCoordinateToRawPosition(float pos, float scale) { var c = scale / 100.0f; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs index 7c1be4876..6a05f1a74 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs @@ -33,6 +33,14 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private uint serverId; + internal PlayerPayload() { } + + public PlayerPayload(string playerName, uint serverId) + { + this.playerName = playerName; + this.serverId = serverId; + } + public override string ToString() { return $"{Type} - PlayerName: {PlayerName}, ServerId: {serverId}"; @@ -58,12 +66,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads // 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() - { - Text = playerName - }.Encode() - ); + bytes.AddRange(new TextPayload(playerName).Encode()); // unsure about this entire packet, but it seems to always follow a name bytes.AddRange(new byte[] diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs index 4d4788623..a71060cfb 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -8,23 +9,38 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads { public override PayloadType Type => PayloadType.Unknown; - public byte[] Data { get; private set; } + private byte[] data; + public byte[] Data + { + get + { + // for now don't allow modifying the contents + // because we don't really have a way to track Dirty + return (byte[])data.Clone(); + } + } private byte chunkType; - public RawPayload(byte chunkType) + internal RawPayload(byte chunkType) { this.chunkType = chunkType; } + public RawPayload(byte[] data) + { + this.chunkType = data[0]; + this.data = data.Skip(1).ToArray(); + } + public override string ToString() { - return $"{Type} - Chunk type: {chunkType:X}, Data: {BitConverter.ToString(Data).Replace("-", " ")}"; + return $"{Type} - Chunk type: {chunkType:X}, Data: {BitConverter.ToString(data).Replace("-", " ")}"; } protected override byte[] EncodeImpl() { - var chunkLen = Data.Length + 1; + var chunkLen = this.data.Length + 1; var bytes = new List() { @@ -32,7 +48,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads this.chunkType, (byte)chunkLen }; - bytes.AddRange(Data); + bytes.AddRange(this.data); bytes.Add(END_BYTE); @@ -41,7 +57,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads protected override void DecodeImpl(BinaryReader reader, long endOfStream) { - Data = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position + 1)); + this.data = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position + 1)); } } } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs index 0a08c5e5b..3b822c239 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs @@ -21,6 +21,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private uint statusId; + internal StatusPayload() { } + + public StatusPayload(uint statusId) + { + this.statusId = statusId; + } + public override string ToString() { return $"{Type} - StatusId: {statusId}"; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs index 1f8e3e584..8bb5eff1e 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs @@ -26,6 +26,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads return $"{Type} - Text: {Text}"; } + internal TextPayload() { } + + public TextPayload(string text) + { + this.text = text; + } + protected override byte[] EncodeImpl() { return Encoding.UTF8.GetBytes(Text); diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs index d88d0e1c7..78150f08d 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs @@ -40,6 +40,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private ushort colorKey; + internal UIForegroundPayload() { } + + public UIForegroundPayload(ushort colorKey) + { + this.colorKey = colorKey; + } + public override string ToString() { return $"{Type} - UIColor: {colorKey}"; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs index 33f5dde12..19fd8365a 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs @@ -40,6 +40,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads private ushort colorKey; + internal UIGlowPayload() { } + + public UIGlowPayload(ushort colorKey) + { + this.colorKey = colorKey; + } + public override string ToString() { return $"{Type} - UIColor: {colorKey}";