a651b3b9ad
Four pre-existing upstream defects fixed in v1.0.0: - Util/GlobalParametersCache.cs GetValue captures Cache into a local before the bounds check, so the check and the indexed read operate on the same array reference even when Refresh reassigns Cache from the main thread between the two operations - Util/IconUtil.cs binary search bounds: hi initialized to entries.Length-1 (was Length), and reset on redirect-restart; added entries.Length==0 short-circuit to prevent indexing into empty arrays - Sheets.cs WorldsOnDatacenter compared Region.RowId, which groups by region instead of datacenter — now compares DataCenter.RowId directly so the result actually reflects same-DC worlds - Message.cs back-reference loop iterates the processed Sender/Content properties rather than the raw constructor parameters, so chunks added or replaced by CheckMessageContent also get Message set
51 lines
1.5 KiB
C#
51 lines
1.5 KiB
C#
using Dalamud.Utility;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
|
using FFXIVClientStructs.FFXIV.Component.Text;
|
|
|
|
namespace HellionChat.Util;
|
|
|
|
public static class GlobalParametersCache
|
|
{
|
|
private static int[] Cache = [];
|
|
|
|
public static int GetValue(int index)
|
|
{
|
|
// Capture the array reference once so the bounds check and the
|
|
// indexed read operate on the same instance, even if Refresh
|
|
// reassigns Cache between the two operations.
|
|
var cache = Cache;
|
|
if (index < 0 || index >= cache.Length)
|
|
return 0;
|
|
|
|
return cache[index];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh the cache of global parameters from RaptureTextModule.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This should be called in the main thread when updates are necessary.
|
|
/// </remarks>
|
|
public static unsafe void Refresh()
|
|
{
|
|
if (!ThreadSafety.IsMainThread)
|
|
throw new InvalidOperationException("GlobalParametersCache.Refresh must be called on the main thread.");
|
|
|
|
var rtm = RaptureTextModule.Instance();
|
|
if (rtm is null)
|
|
return;
|
|
|
|
ref var gp = ref rtm->TextModule.MacroDecoder.GlobalParameters;
|
|
if (Cache.Length != (int)gp.MySize)
|
|
Cache = new int[gp.MySize];
|
|
|
|
for (ulong i = 0; i < gp.MySize; i++)
|
|
{
|
|
var p = gp[(long)i];
|
|
if (p.Type == TextParameterType.Integer)
|
|
Cache[(int)i] = p.IntValue;
|
|
else
|
|
Cache[(int)i] = 0;
|
|
}
|
|
}
|
|
} |