4 Commits

Author SHA1 Message Date
5ca4b318c6 1.7.1.6
All checks were successful
Build and Update Repo / build-and-update-repo (push) Successful in 1m7s
Update NuGet Packages
Update DalamudPackager
2025-12-19 15:10:01 +00:00
cedd0ceb26 1.7.1.5
Some checks failed
Build and Update Repo / build-and-update-repo (push) Failing after 1m44s
2025-12-18 17:14:39 +00:00
374fc03ce9 Update workflow
API14
2025-12-18 17:01:42 +00:00
75f88d5104 Potential fix for Honorific throwing away data. Still testing efficacy.
All checks were successful
Build and Update Repo / build-and-update-repo (push) Successful in 1m13s
2025-09-24 20:37:12 +01:00
9 changed files with 59 additions and 34 deletions

View File

@@ -7,7 +7,7 @@ on:
env:
PLUGIN_NAME: ClubPenguinSync
DOTNET_VERSION: 9.x
DOTNET_VERSION: 10.x
jobs:
build-and-update-repo:
@@ -22,10 +22,10 @@ jobs:
fetch-depth: 0
submodules: true
- name: Setup .NET 9 SDK
- name: Setup .NET 10 SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x
dotnet-version: 10.x
- name: Download Dalamud
run: |

Submodule MareAPI updated: b2f4453b79...d27ef802b9

View File

@@ -14,6 +14,7 @@ public sealed class IpcCallerHonorific : IIpcCaller
private readonly ICallGateSubscriber<int, object> _honorificClearCharacterTitle;
private readonly ICallGateSubscriber<object> _honorificDisposing;
private readonly ICallGateSubscriber<string> _honorificGetLocalCharacterTitle;
private readonly ICallGateSubscriber<int, string> _honorificGetCharacterTitle;
private readonly ICallGateSubscriber<string, object> _honorificLocalCharacterTitleChanged;
private readonly ICallGateSubscriber<object> _honorificReady;
private readonly ICallGateSubscriber<int, string, object> _honorificSetCharacterTitle;
@@ -29,6 +30,7 @@ public sealed class IpcCallerHonorific : IIpcCaller
_dalamudUtil = dalamudUtil;
_honorificApiVersion = pi.GetIpcSubscriber<(uint, uint)>("Honorific.ApiVersion");
_honorificGetLocalCharacterTitle = pi.GetIpcSubscriber<string>("Honorific.GetLocalCharacterTitle");
_honorificGetCharacterTitle = pi.GetIpcSubscriber<int, string>("Honorific.GetCharacterTitle");
_honorificClearCharacterTitle = pi.GetIpcSubscriber<int, object>("Honorific.ClearCharacterTitle");
_honorificSetCharacterTitle = pi.GetIpcSubscriber<int, string, object>("Honorific.SetCharacterTitle");
_honorificLocalCharacterTitleChanged = pi.GetIpcSubscriber<string, object>("Honorific.LocalCharacterTitleChanged");
@@ -84,6 +86,23 @@ public sealed class IpcCallerHonorific : IIpcCaller
return string.IsNullOrEmpty(title) ? string.Empty : Convert.ToBase64String(Encoding.UTF8.GetBytes(title));
}
public async Task<string> GetTitleForPlayer(IntPtr character)
{
if (!APIAvailable) return string.Empty;
string title = await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is IPlayerCharacter pc)
{
return _honorificGetCharacterTitle.InvokeFunc(pc.ObjectIndex);
}
return string.Empty;
}).ConfigureAwait(false);
return string.IsNullOrEmpty(title) ? string.Empty : Convert.ToBase64String(Encoding.UTF8.GetBytes(title));
}
public async Task SetTitleAsync(IntPtr character, string honorificDataB64)
{
if (!APIAvailable) return;

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Dalamud.NET.Sdk/13.1.0">
<Project Sdk="Dalamud.NET.Sdk/14.0.0">
<PropertyGroup>
<AssemblyName>ClubPenguinSync</AssemblyName>
<Version>1.7.1.3</Version>
<Version>1.7.1.6</Version>
<PackageProjectUrl>https://github.com/Rawrington/ClubPenguinSync/</PackageProjectUrl>
</PropertyGroup>
@@ -13,18 +13,18 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Downloader" Version="3.3.4" />
<PackageReference Include="Downloader" Version="4.0.3" />
<PackageReference Include="K4os.Compression.LZ4.Legacy" Version="1.3.8" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.3.8" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.189">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.263">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<PackageReference Include="NReco.Logging.File" Version="1.2.2" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.1" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.1" />
<PackageReference Include="NReco.Logging.File" Version="1.3.1" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.17.0.131074">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@@ -47,4 +47,8 @@
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="DalamudPackager" Version="14.0.1" />
</ItemGroup>
</Project>

View File

@@ -149,7 +149,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
public string? PlayerName { get; private set; }
public string PlayerNameHash => Pair.Ident;
public void ApplyCharacterData(Guid applicationBase, CharacterData characterData, bool forceApplyCustomization = false)
public async void ApplyCharacterData(Guid applicationBase, CharacterData characterData, bool forceApplyCustomization = false)
{
if (_configService.Current.HoldCombatApplication && _dalamudUtil.IsInCombatOrPerforming)
{
@@ -175,7 +175,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
Logger.LogDebug("[BASE-{appBase}] Received data but player was in invalid state, charaHandlerIsNull: {charaIsNull}, playerPointerIsNull: {ptrIsNull}",
applicationBase, _charaHandler == null, PlayerCharacter == IntPtr.Zero);
var hasDiffMods = characterData.CheckUpdatedData(applicationBase, _cachedData, Logger,
this, forceApplyCustomization, forceApplyMods: false)
this, forceApplyCustomization, forceApplyMods: false, string.Empty)
.Any(p => p.Value.Contains(PlayerChanges.ModManip) || p.Value.Contains(PlayerChanges.ModFiles));
_forceApplyMods = hasDiffMods || _forceApplyMods || (PlayerCharacter == IntPtr.Zero && _cachedData == null);
_cachedData = characterData;
@@ -201,7 +201,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
$"Not applying character data: {reasons}")));
Logger.LogDebug("[BASE-{appBase}] Not applying due to hold: {reasons}", applicationBase, reasons);
var hasDiffMods = characterData.CheckUpdatedData(applicationBase, _cachedData, Logger,
this, forceApplyCustomization, forceApplyMods: false)
this, forceApplyCustomization, forceApplyMods: false, _ipcManager.Honorific.GetTitleForPlayer(PlayerCharacter).GetAwaiter().GetResult())
.Any(p => p.Value.Contains(PlayerChanges.ModManip) || p.Value.Contains(PlayerChanges.ModFiles));
_forceApplyMods = hasDiffMods || _forceApplyMods || (PlayerCharacter == IntPtr.Zero && _cachedData == null);
_cachedData = characterData;
@@ -228,7 +228,8 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
_forceApplyMods |= forceApplyCustomization;
var charaDataToUpdate = characterData.CheckUpdatedData(applicationBase, _cachedData?.DeepClone() ?? new(), Logger, this, forceApplyCustomization, _forceApplyMods);
string oldHonorificTitle = _ipcManager.Honorific.GetTitleForPlayer(PlayerCharacter).GetAwaiter().GetResult();
var charaDataToUpdate = characterData.CheckUpdatedData(applicationBase, _cachedData?.DeepClone() ?? new(), Logger, this, forceApplyCustomization, _forceApplyMods, oldHonorificTitle);
if (_charaHandler != null && _forceApplyMods)
{

View File

@@ -7,6 +7,7 @@ using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Control;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using Lumina.Excel.Sheets;
@@ -139,7 +140,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_ = RunOnFrameworkThread(() =>
{
var addr = GetPlayerCharacterFromCachedTableByIdent(ident);
var pc = _clientState.LocalPlayer!;
var pc = _objectTable.LocalPlayer!;
var gobj = CreateGameObject(addr);
// Any further than roughly 55y is out of range for targetting
if (gobj != null && Vector3.Distance(pc.Position, gobj.Position) < 55.0f)
@@ -243,7 +244,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public bool GetIsPlayerPresent()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid();
return _objectTable.LocalPlayer != null && _objectTable.LocalPlayer.IsValid();
}
public async Task<bool> GetIsPlayerPresentAsync()
@@ -287,7 +288,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IPlayerCharacter GetPlayerCharacter()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer!;
return _objectTable.LocalPlayer!;
}
public IntPtr GetPlayerCharacterFromCachedTableByName(string characterName)
@@ -309,7 +310,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public string GetPlayerName()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer?.Name.ToString() ?? "--";
return _objectTable.LocalPlayer?.Name.ToString() ?? "--";
}
public async Task<string> GetPlayerNameAsync()
@@ -325,7 +326,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public IntPtr GetPlayerPointer()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer?.Address ?? IntPtr.Zero;
return _objectTable.LocalPlayer?.Address ?? IntPtr.Zero;
}
public async Task<IntPtr> GetPlayerPointerAsync()
@@ -336,13 +337,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public uint GetHomeWorldId()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer?.HomeWorld.RowId ?? 0;
return _objectTable.LocalPlayer?.HomeWorld.RowId ?? 0;
}
public uint GetWorldId()
{
EnsureIsOnFramework();
return _clientState.LocalPlayer!.CurrentWorld.RowId;
return _objectTable.LocalPlayer!.CurrentWorld.RowId;
}
public unsafe LocationInfo GetMapData()
@@ -351,8 +352,8 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
var agentMap = AgentMap.Instance();
var houseMan = HousingManager.Instance();
uint serverId = 0;
if (_clientState.LocalPlayer == null) serverId = 0;
else serverId = _clientState.LocalPlayer.CurrentWorld.RowId;
if (_objectTable.LocalPlayer == null) serverId = 0;
else serverId = _objectTable.LocalPlayer.CurrentWorld.RowId;
uint mapId = agentMap == null ? 0 : agentMap->CurrentMapId;
uint territoryId = agentMap == null ? 0 : agentMap->CurrentTerritoryId;
uint divisionId = houseMan == null ? 0 : (uint)(houseMan->GetCurrentDivision());
@@ -473,7 +474,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_framework.Update += ClubPenguinSync.Plugin.Self.OnFrameworkUpdate;
if (IsLoggedIn)
{
_classJobId = _clientState.LocalPlayer!.ClassJob.RowId;
_classJobId = _objectTable.LocalPlayer!.ClassJob.RowId;
}
_logger.LogInformation("Started DalamudUtilService");
@@ -582,7 +583,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
bool isDrawingChanged = false;
if ((nint)drawObj != IntPtr.Zero)
{
isDrawing = gameObj->RenderFlags == 0b100000000000;
isDrawing = gameObj->RenderFlags == VisibilityFlags.Model;
if (!isDrawing)
{
isDrawing = ((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0;
@@ -635,7 +636,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
private unsafe void FrameworkOnUpdateInternal()
{
if (_clientState.LocalPlayer?.IsDead ?? false)
if (_objectTable.LocalPlayer?.IsDead ?? false)
{
return;
}
@@ -764,7 +765,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
Mediator.Publish(new ResumeScanMessage(nameof(ConditionFlag.BetweenAreas)));
}
var localPlayer = _clientState.LocalPlayer;
var localPlayer = _objectTable.LocalPlayer;
if (localPlayer != null)
{
_classJobId = localPlayer.ClassJob.RowId;

View File

@@ -56,7 +56,7 @@ public static class VariousExtensions
}
public static Dictionary<ObjectKind, HashSet<PlayerChanges>> CheckUpdatedData(this CharacterData newData, Guid applicationBase,
CharacterData? oldData, ILogger logger, PairHandler cachedPlayer, bool forceApplyCustomization, bool forceApplyMods)
CharacterData? oldData, ILogger logger, PairHandler cachedPlayer, bool forceApplyCustomization, bool forceApplyMods, string oldHonorificData)
{
oldData ??= new();
var charaDataToUpdate = new Dictionary<ObjectKind, HashSet<PlayerChanges>>();
@@ -182,7 +182,7 @@ public static class VariousExtensions
charaDataToUpdate[objectKind].Add(PlayerChanges.Heels);
}
bool honorificDataDifferent = !string.Equals(oldData.HonorificData, newData.HonorificData, StringComparison.Ordinal);
bool honorificDataDifferent = !string.Equals(oldHonorificData, newData.HonorificData, StringComparison.Ordinal);
if (honorificDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.HonorificData)))
{
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff honorific data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Honorific);