Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: '9.x.x'
dotnet-version: '10.x.x'
- name: Restore dependencies
run: dotnet restore
- name: Download Dalamud
Expand Down
60 changes: 29 additions & 31 deletions PrefPro/DalamudApi.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Dalamud.Game;
using Dalamud.Game.ClientState.Objects;
using Dalamud.IoC;
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;

Expand All @@ -10,32 +8,32 @@ public class DalamudApi
{
public static void Initialize(IDalamudPluginInterface pluginInterface) => pluginInterface.Create<DalamudApi>();

// [PluginService] public static IAetheryteList AetheryteList { get; private set; } = null;
// [PluginService] public static IBuddyList BuddyList { get; private set; } = null;
// [PluginService] public static IChatGui ChatGui { get; private set; } = null;
[PluginService] public static IClientState ClientState { get; private set; } = null;
[PluginService] public static ICommandManager CommandManager { get; private set; } = null;
// [PluginService] public static ICondition Condition { get; private set; } = null;
[PluginService] public static IDalamudPluginInterface PluginInterface { get; private set; } = null;
// [PluginService] public static IDataManager DataManager { get; private set; } = null;
// [PluginService] public static IDtrBar DtrBar { get; private set; } = null;
// [PluginService] public static IFateTable FateTable { get; private set; } = null;
// [PluginService] public static IFlyTextGui FlyTextGui { get; private set; } = null;
[PluginService] public static IFramework Framework { get; private set; } = null;
// [PluginService] public static IGameGui GameGui { get; private set; } = null;
[PluginService] public static IGameConfig GameConfig { get; private set; } = null;
// [PluginService] public static IGameNetwork GameNetwork { get; private set; } = null;
// [PluginService] public static IGamepadState GamePadState { get; private set; } = null;
// [PluginService] public static IJobGauges JobGauges { get; private set; } = null;
// [PluginService] public static IKeyState KeyState { get; private set; } = null;
// [PluginService] public static ILibcFunction LibcFunction { get; private set; } = null;
[PluginService] public static IObjectTable ObjectTable { get; private set; } = null;
// [PluginService] public static IPartyFinderGui PartyFinderGui { get; private set; } = null;
// [PluginService] public static IPartyList PartyList { get; private set; } = null;
[PluginService] public static ISigScanner SigScanner { get; private set; } = null;
// [PluginService] public static ITargetManager TargetManager { get; private set; } = null;
// [PluginService] public static IToastGui ToastGui { get; private set; } = null;
[PluginService] public static IGameInteropProvider Hooks { get; private set; } = null;
[PluginService] public static IPluginLog PluginLog { get; private set; } = null;
// [PluginService] public static ITitleScreenMenu TitleScreenMenu { get; private set; } = null;
// [PluginService] public static IAetheryteList AetheryteList { get; private set; } = null!;
// [PluginService] public static IBuddyList BuddyList { get; private set; } = null; !
// [PluginService] public static IChatGui ChatGui { get; private set; } = null!;
[PluginService] public static IClientState ClientState { get; private set; } = null!;
[PluginService] public static ICommandManager CommandManager { get; private set; } = null!;
// [PluginService] public static ICondition Condition { get; private set; } = null!;
[PluginService] public static IDalamudPluginInterface PluginInterface { get; private set; } = null!;
// [PluginService] public static IDataManager DataManager { get; private set; } = null!;
// [PluginService] public static IDtrBar DtrBar { get; private set; } = null!;
// [PluginService] public static IFateTable FateTable { get; private set; } = null!;
// [PluginService] public static IFlyTextGui FlyTextGui { get; private set; } = null!;
[PluginService] public static IFramework Framework { get; private set; } = null!;
// [PluginService] public static IGameGui GameGui { get; private set; } = null!;
[PluginService] public static IGameConfig GameConfig { get; private set; } = null!;
// [PluginService] public static IGameNetwork GameNetwork { get; private set; } = null!;
// [PluginService] public static IGamepadState GamePadState { get; private set; } = null!;
// [PluginService] public static IJobGauges JobGauges { get; private set; } = null!;
// [PluginService] public static IKeyState KeyState { get; private set; } = null!;
// [PluginService] public static ILibcFunction LibcFunction { get; private set; } = null!;
[PluginService] public static IObjectTable ObjectTable { get; private set; } = null!;
// [PluginService] public static IPartyFinderGui PartyFinderGui { get; private set; } = null!;
// [PluginService] public static IPartyList PartyList { get; private set; } = null!;
[PluginService] public static ISigScanner SigScanner { get; private set; } = null!;
// [PluginService] public static ITargetManager TargetManager { get; private set; } = null!;
// [PluginService] public static IToastGui ToastGui { get; private set; } = null!;
[PluginService] public static IGameInteropProvider Hooks { get; private set; } = null!;
[PluginService] public static IPluginLog PluginLog { get; private set; } = null!;
// [PluginService] public static ITitleScreenMenu TitleScreenMenu { get; private set; } = null!;
}
2 changes: 1 addition & 1 deletion PrefPro/GenderHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private void SetLuaVarGender(nint poolBase, int gender)

private int GetCutVoGenderDetour(nint a1, nint a2)
{
var originalRet = _getCutVoGenderHook.Original(a1, a2);
var originalRet = _getCutVoGenderHook!.Original(a1, a2);

if (!_configuration.Enabled)
return originalRet;
Expand Down
6 changes: 1 addition & 5 deletions PrefPro/PrefPro.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Dalamud.NET.Sdk/15.0.0">
<Project Sdk="Dalamud.NET.Sdk/15.0.0">
<PropertyGroup>
<PluginVersion>1.3.0.3</PluginVersion>
</PropertyGroup>
Expand All @@ -25,10 +25,6 @@
<DebugType>pdbonly</DebugType>
</PropertyGroup>

<ItemGroup>
<Reference Include="Microsoft.Extensions.ObjectPool" Private="false" />
</ItemGroup>

<ItemGroup>
<Content Include="PrefPro.yaml" />
</ItemGroup>
Expand Down
146 changes: 104 additions & 42 deletions PrefPro/StringHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text;
using Dalamud.Hooking;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.System.String;
Expand Down Expand Up @@ -74,7 +73,7 @@ private bool FormatStringDetour(TextModule* thisPtr, CStringPointer input, StdDe
if (!_configuration.Enabled)
goto originalFormatString;

var seString = input.AsReadOnlySeStringSpan();
var seString = input.AsReadOnlySeString();
if (seString.IsEmpty || seString.IsTextOnly())
goto originalFormatString;

Expand Down Expand Up @@ -104,25 +103,11 @@ private bool FormatStringDetour(TextModule* thisPtr, CStringPointer input, StdDe
{
foreach (var payload in seString)
{
if (nameConfig.ApplyFull && ShouldHandleStringPayload(payload))
{
sb.Append(nameConfig.NameFull);
}
else if (nameConfig.ApplyFirst && ShouldHandleSplitPayload(payload, 1))
{
sb.Append(nameConfig.NameFirst);
}
else if (nameConfig.ApplyLast && ShouldHandleSplitPayload(payload, 2))
{
sb.Append(nameConfig.NameLast);
}
else
{
sb.Append(payload);
}
sb.Append(ProcessPayload(payload));
}

fixed (byte* newInput = sb.GetViewAsSpan())
return _formatStringHook.Original(thisPtr, newInput, localParameters, output);
return _formatStringHook!.Original(thisPtr, newInput, localParameters, output);
}
catch (Exception ex)
{
Expand All @@ -137,14 +122,14 @@ private bool FormatStringDetour(TextModule* thisPtr, CStringPointer input, StdDe
}
else
{
var result = _formatStringHook.Original(thisPtr, input, localParameters, output);
var result = _formatStringHook!.Original(thisPtr, input, localParameters, output);
raceParam.IntValue = oldRace;
genderParam.IntValue = oldGender;
return result;
}

originalFormatString:
return _formatStringHook.Original(thisPtr, input, localParameters, output);
return _formatStringHook!.Original(thisPtr, input, localParameters, output);
}

public void RefreshConfig()
Expand Down Expand Up @@ -188,25 +173,14 @@ private static NameHandlerConfig CreateConfig(Configuration config, string playe
else
{
data.Apply = true;

var nameFull = GetNameText(playerName, config.Name, config.FullName);
var nameFirst = GetNameText(playerName, config.Name, config.FirstName);
var nameLast = GetNameText(playerName, config.Name, config.LastName);

data.NameFull = MakePayload(nameFull);
data.NameFirst = MakePayload(nameFirst);
data.NameLast = MakePayload(nameLast);
data.NameFull = GetNameText(playerName, config.Name, config.FullName);
data.NameFirst = GetNameText(playerName, config.Name, config.FirstName);
data.NameLast = GetNameText(playerName, config.Name, config.LastName);
}

return data;
}

private static ReadOnlySePayload MakePayload(string text)
{
var bytes = Encoding.UTF8.GetBytes(text);
return new ReadOnlySePayload(ReadOnlySePayloadType.Text, macroCode: default, bytes);
}

private static string GetNameText(string playerName, string configName, NameSetting setting)
{
switch (setting)
Expand All @@ -225,8 +199,96 @@ private static string GetNameText(string playerName, string configName, NameSett
}
}

// <string(gstr1)>
private static bool ShouldHandleStringPayload(ReadOnlySePayloadSpan payload)
private ReadOnlySePayload ProcessPayload(ReadOnlySePayload input)
{
if (input.Type == ReadOnlySePayloadType.Macro)
{
using var rssb = new RentedSeStringBuilder();

if (_nameHandlerConfig.ApplyFull && ShouldHandleStringPayload(input))
{
rssb.Builder
.BeginMacro(MacroCode.String)
.AppendStringExpression(_nameHandlerConfig.NameFull)
.EndMacro();
}
else if (_nameHandlerConfig.ApplyFirst && ShouldHandleSplitPayload(input, 1))
{
rssb.Builder
.BeginMacro(MacroCode.String)
.AppendStringExpression(_nameHandlerConfig.NameFirst)
.EndMacro();
}
else if (_nameHandlerConfig.ApplyLast && ShouldHandleSplitPayload(input, 2))
{
rssb.Builder
.BeginMacro(MacroCode.String)
.AppendStringExpression(_nameHandlerConfig.NameLast)
.EndMacro();
}
else
{
rssb.Builder.BeginMacro(input.MacroCode);

foreach (var expr in input)
{
ProcessExpression(rssb.Builder, expr);
}

rssb.Builder.EndMacro();
}

foreach (var outPayload in rssb.Builder.ToReadOnlySeString())
{
return outPayload;
}
}

return input;
}

private void ProcessExpression(SeStringBuilder builder, ReadOnlySeExpression expr)
{
if (expr.TryGetInt(out var intExpr))
{
builder.AppendIntExpression(intExpr);
}
else if (expr.TryGetString(out var s))
{
using var rssb = new RentedSeStringBuilder();

foreach (var payload in s)
{
rssb.Builder.Append(ProcessPayload(payload));
}

builder.AppendStringExpression(rssb.Builder.ToReadOnlySeString().AsSpan());
}
else if (expr.TryGetPlaceholderExpression(out var expressionType))
{
builder.AppendNullaryExpression((ExpressionType)expressionType);
}
else if (expr.TryGetParameterExpression(out expressionType, out var e1))
{
builder.BeginUnaryExpression((ExpressionType)expressionType);
ProcessExpression(builder, e1);
builder.EndExpression();
}
else if (expr.TryGetBinaryExpression(out expressionType, out e1, out var e2))
{
builder.BeginBinaryExpression((ExpressionType)expressionType);
ProcessExpression(builder, e1);
ProcessExpression(builder, e2);
builder.EndExpression();
}
else
{
throw new Exception($"Could not process expression {expr}");
}
}

// <string(gstr1)>
private static bool ShouldHandleStringPayload(ReadOnlySePayload payload)
{
return payload.Type == ReadOnlySePayloadType.Macro
&& payload.MacroCode == MacroCode.String
Expand All @@ -237,8 +299,8 @@ private static bool ShouldHandleStringPayload(ReadOnlySePayloadSpan payload)
&& gstrIndex == 1;
}

// <split(<string(gstr1)>, ,index)>
private static bool ShouldHandleSplitPayload(ReadOnlySePayloadSpan payload, int splitIndex)
// <split(<string(gstr1)>, ,index)>
private static bool ShouldHandleSplitPayload(ReadOnlySePayload payload, int splitIndex)
{
if (payload.Type == ReadOnlySePayloadType.Macro
&& payload.MacroCode == MacroCode.Split
Expand All @@ -261,9 +323,9 @@ public class NameHandlerConfig
public bool ApplyFull;
public bool ApplyFirst;
public bool ApplyLast;
public ReadOnlySePayload? NameFull;
public ReadOnlySePayload? NameFirst;
public ReadOnlySePayload? NameLast;
public string? NameFull;
public string? NameFirst;
public string? NameLast;

public static readonly NameHandlerConfig None = new()
{
Expand Down