From ba8780e047de015ab5e979e7736c2e2c1102eddf Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Wed, 16 Jun 2021 08:04:26 -0400 Subject: [PATCH 1/2] The ultimate fix --- .../Game/ClientState/Actors/Types/Actor.cs | 33 +++++++++++++++++-- Dalamud/Game/ClientState/Structs/Actor.cs | 4 +-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Dalamud/Game/ClientState/Actors/Types/Actor.cs b/Dalamud/Game/ClientState/Actors/Types/Actor.cs index d971a4e1e..b1476d9b7 100644 --- a/Dalamud/Game/ClientState/Actors/Types/Actor.cs +++ b/Dalamud/Game/ClientState/Actors/Types/Actor.cs @@ -1,6 +1,7 @@ using System; - +using System.Text; using Dalamud.Game.ClientState.Structs; +using Serilog; namespace Dalamud.Game.ClientState.Actors.Types { @@ -12,6 +13,8 @@ namespace Dalamud.Game.ClientState.Actors.Types private readonly Structs.Actor actorStruct; private readonly Dalamud dalamud; + private string name; + /// /// Initializes a new instance of the class. /// This represents a basic FFXIV actor. @@ -40,7 +43,33 @@ namespace Dalamud.Game.ClientState.Actors.Types /// /// Gets the displayname of this . /// - public string Name => this.ActorStruct.Name; + public string Name + { + get + { + if (this.name == null) + { + var i = 0; + for (; i < this.actorStruct.Name.Length; i++) + { + if (this.actorStruct.Name[i] == 0) + break; + } + + if (i == this.actorStruct.Name.Length) + { + this.name = Encoding.UTF8.GetString(this.actorStruct.Name); + Log.Warning($"Warning: Actor name exceeds underlying struct array length (name={this.name})"); + } + else + { + this.name = Encoding.UTF8.GetString(this.actorStruct.Name, 0, i); + } + } + + return this.name; + } + } /// /// Gets the actor ID of this . diff --git a/Dalamud/Game/ClientState/Structs/Actor.cs b/Dalamud/Game/ClientState/Structs/Actor.cs index 230601f8e..e765a8c4c 100644 --- a/Dalamud/Game/ClientState/Structs/Actor.cs +++ b/Dalamud/Game/ClientState/Structs/Actor.cs @@ -14,8 +14,8 @@ namespace Dalamud.Game.ClientState.Structs /// The actor name. /// [FieldOffset(ActorOffsets.Name)] - [MarshalAs(UnmanagedType.LPUTF8Str, SizeConst = 30)] - public string Name; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)] + public byte[] Name; /// /// The actor's internal id. From 98781f0bcd252f9835b87023ee276769851de51a Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Wed, 16 Jun 2021 08:42:42 -0400 Subject: [PATCH 2/2] Such utility, so many wows --- .../Game/ClientState/Actors/Types/Actor.cs | 28 +---------------- Dalamud/Util.cs | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/Dalamud/Game/ClientState/Actors/Types/Actor.cs b/Dalamud/Game/ClientState/Actors/Types/Actor.cs index b1476d9b7..9707f6674 100644 --- a/Dalamud/Game/ClientState/Actors/Types/Actor.cs +++ b/Dalamud/Game/ClientState/Actors/Types/Actor.cs @@ -43,33 +43,7 @@ namespace Dalamud.Game.ClientState.Actors.Types /// /// Gets the displayname of this . /// - public string Name - { - get - { - if (this.name == null) - { - var i = 0; - for (; i < this.actorStruct.Name.Length; i++) - { - if (this.actorStruct.Name[i] == 0) - break; - } - - if (i == this.actorStruct.Name.Length) - { - this.name = Encoding.UTF8.GetString(this.actorStruct.Name); - Log.Warning($"Warning: Actor name exceeds underlying struct array length (name={this.name})"); - } - else - { - this.name = Encoding.UTF8.GetString(this.actorStruct.Name, 0, i); - } - } - - return this.name; - } - } + public string Name => this.name ??= Util.GetUTF8String(this.actorStruct.Name); /// /// Gets the actor ID of this . diff --git a/Dalamud/Util.cs b/Dalamud/Util.cs index e851f87a0..456c93689 100644 --- a/Dalamud/Util.cs +++ b/Dalamud/Util.cs @@ -165,5 +165,36 @@ namespace Dalamud NativeFunctions.MessageBox(Process.GetCurrentProcess().MainWindowHandle, message, caption, flags); Environment.Exit(-1); } + + /// + /// Retrieve a UTF8 string from a null terminated byte array. + /// + /// A null terminated UTF8 byte array. + /// A UTF8 encoded string. + public static string GetUTF8String(byte[] array) + { + var count = 0; + for (; count < array.Length; count++) + { + if (array[count] == 0) + break; + } + + string text; + if (count == array.Length) + { + text = Encoding.UTF8.GetString(array); + Log.Warning($"Warning: text exceeds underlying array length ({text})"); + } + else + { + text = Encoding.UTF8.GetString(array, 0, count); + } + + return text; + } + + // TODO: Someone implement GetUTF8String with some IntPtr overloads. + // while(Marshal.ReadByte(0, sz) != 0) { sz++; } } }