Dalamud API10

This commit is contained in:
Loporrit
2024-07-03 18:44:23 +00:00
parent 00ab63a253
commit 47b292f4bb
31 changed files with 220 additions and 223 deletions

View File

@@ -1,6 +1,6 @@
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Glamourer.Api.Helpers;
@@ -21,13 +21,13 @@ namespace MareSynchronos.Interop;
public sealed class IpcManager : DisposableMediatorSubscriberBase
{
private readonly ICallGateSubscriber<(int, int)> _customizePlusApiVersion;
private readonly ICallGateSubscriber<Character, (int, Guid?)> _customizePlusGetActiveProfile;
private readonly ICallGateSubscriber<ICharacter, (int, Guid?)> _customizePlusGetActiveProfile;
private readonly ICallGateSubscriber<Guid, (int, string?)> _customizePlusGetProfileById;
private readonly ICallGateSubscriber<Character, Guid, object> _customizePlusOnScaleUpdate;
private readonly ICallGateSubscriber<Character, int> _customizePlusRevertCharacter;
private readonly ICallGateSubscriber<Character, string, (int, Guid?)> _customizePlusSetBodyScaleToCharacter;
private readonly ICallGateSubscriber<ICharacter, Guid, object> _customizePlusOnScaleUpdate;
private readonly ICallGateSubscriber<ICharacter, int> _customizePlusRevertCharacter;
private readonly ICallGateSubscriber<ICharacter, string, (int, Guid?)> _customizePlusSetBodyScaleToCharacter;
private readonly ICallGateSubscriber<Guid, int> _customizePlusDeleteByUniqueId;
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
private readonly DalamudUtilService _dalamudUtil;
private readonly Glamourer.Api.IpcSubscribers.ApiVersion _glamourerApiVersions;
private readonly Glamourer.Api.IpcSubscribers.ApplyState? _glamourerApplyAll;
@@ -40,15 +40,15 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
private readonly ICallGateSubscriber<(int, int)> _heelsGetApiVersion;
private readonly ICallGateSubscriber<string> _heelsGetOffset;
private readonly ICallGateSubscriber<string, object?> _heelsOffsetUpdate;
private readonly ICallGateSubscriber<GameObject, string, object?> _heelsRegisterPlayer;
private readonly ICallGateSubscriber<GameObject, object?> _heelsUnregisterPlayer;
private readonly ICallGateSubscriber<IGameObject, string, object?> _heelsRegisterPlayer;
private readonly ICallGateSubscriber<IGameObject, object?> _heelsUnregisterPlayer;
private readonly ICallGateSubscriber<(uint major, uint minor)> _honorificApiVersion;
private readonly ICallGateSubscriber<Character, object> _honorificClearCharacterTitle;
private readonly ICallGateSubscriber<ICharacter, object> _honorificClearCharacterTitle;
private readonly ICallGateSubscriber<object> _honorificDisposing;
private readonly ICallGateSubscriber<string> _honorificGetLocalCharacterTitle;
private readonly ICallGateSubscriber<string, object> _honorificLocalCharacterTitleChanged;
private readonly ICallGateSubscriber<object> _honorificReady;
private readonly ICallGateSubscriber<Character, string, object> _honorificSetCharacterTitle;
private readonly ICallGateSubscriber<ICharacter, string, object> _honorificSetCharacterTitle;
private readonly ConcurrentDictionary<IntPtr, bool> _penumbraRedrawRequests = new();
private readonly Penumbra.Api.Helpers.EventSubscriber _penumbraDispose;
private readonly Penumbra.Api.Helpers.EventSubscriber<nint, string, string> _penumbraGameObjectResourcePathResolved;
@@ -82,9 +82,9 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
private bool _useLegacyGlamourer = false;
private readonly Glamourer.Api.IpcSubscribers.Legacy.ApiVersions _glamourerApiVersionLegacy;
private readonly ICallGateSubscriber<string, GameObject?, uint, object>? _glamourerApplyAllLegacy;
private readonly ICallGateSubscriber<GameObject?, string>? _glamourerGetAllCustomizationLegacy;
private readonly ICallGateSubscriber<Character?, uint, object?> _glamourerRevertLegacy;
private readonly ICallGateSubscriber<string, IGameObject?, uint, object>? _glamourerApplyAllLegacy;
private readonly ICallGateSubscriber<IGameObject?, string>? _glamourerGetAllCustomizationLegacy;
private readonly ICallGateSubscriber<ICharacter?, uint, object?> _glamourerRevertLegacy;
private readonly Glamourer.Api.IpcSubscribers.Legacy.RevertLock _glamourerRevertByNameLegacy;
private readonly Glamourer.Api.IpcSubscribers.Legacy.UnlockName _glamourerUnlockLegacy;
private readonly Glamourer.Api.Helpers.EventSubscriber<int, nint, Lazy<string>>? _glamourerStateChangedLegacy;
@@ -99,7 +99,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
private readonly Penumbra.Api.IpcSubscribers.Legacy.RedrawObjectByIndex _penumbraRedrawLegacy;
private readonly Penumbra.Api.IpcSubscribers.Legacy.GetGameObjectResourcePaths _penumbraResourcePathsLegacy;
public IpcManager(ILogger<IpcManager> logger, DalamudPluginInterface pi, DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator)
public IpcManager(ILogger<IpcManager> logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator)
{
_pi = pi;
_dalamudUtil = dalamudUtil;
@@ -148,34 +148,34 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
_glamourerStateChanged.Enable();
_glamourerApiVersionLegacy = new(pi);
_glamourerApplyAllLegacy = pi.GetIpcSubscriber<string, GameObject?, uint, object>("Glamourer.ApplyAllToCharacterLock");
_glamourerGetAllCustomizationLegacy = pi.GetIpcSubscriber<GameObject?, string>("Glamourer.GetAllCustomizationFromCharacter");
_glamourerRevertLegacy = pi.GetIpcSubscriber<Character?, uint, object?>("Glamourer.RevertCharacterLock");
_glamourerApplyAllLegacy = pi.GetIpcSubscriber<string, IGameObject?, uint, object>("Glamourer.ApplyAllToCharacterLock");
_glamourerGetAllCustomizationLegacy = pi.GetIpcSubscriber<IGameObject?, string>("Glamourer.GetAllCustomizationFromCharacter");
_glamourerRevertLegacy = pi.GetIpcSubscriber<ICharacter?, uint, object?>("Glamourer.RevertCharacterLock");
_glamourerRevertByNameLegacy = new(pi);
_glamourerUnlockLegacy = new(pi);
_heelsGetApiVersion = pi.GetIpcSubscriber<(int, int)>("SimpleHeels.ApiVersion");
_heelsGetOffset = pi.GetIpcSubscriber<string>("SimpleHeels.GetLocalPlayer");
_heelsRegisterPlayer = pi.GetIpcSubscriber<GameObject, string, object?>("SimpleHeels.RegisterPlayer");
_heelsUnregisterPlayer = pi.GetIpcSubscriber<GameObject, object?>("SimpleHeels.UnregisterPlayer");
_heelsRegisterPlayer = pi.GetIpcSubscriber<IGameObject, string, object?>("SimpleHeels.RegisterPlayer");
_heelsUnregisterPlayer = pi.GetIpcSubscriber<IGameObject, object?>("SimpleHeels.UnregisterPlayer");
_heelsOffsetUpdate = pi.GetIpcSubscriber<string, object?>("SimpleHeels.LocalChanged");
_heelsOffsetUpdate.Subscribe(HeelsOffsetChange);
_customizePlusApiVersion = pi.GetIpcSubscriber<(int, int)>("CustomizePlus.General.GetApiVersion");
_customizePlusGetActiveProfile = pi.GetIpcSubscriber<Character, (int, Guid?)>("CustomizePlus.Profile.GetActiveProfileIdOnCharacter");
_customizePlusGetActiveProfile = pi.GetIpcSubscriber<ICharacter, (int, Guid?)>("CustomizePlus.Profile.GetActiveProfileIdOnCharacter");
_customizePlusGetProfileById = pi.GetIpcSubscriber<Guid, (int, string?)>("CustomizePlus.Profile.GetByUniqueId");
_customizePlusRevertCharacter = pi.GetIpcSubscriber<Character, int>("CustomizePlus.Profile.DeleteTemporaryProfileOnCharacter");
_customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber<Character, string, (int, Guid?)>("CustomizePlus.Profile.SetTemporaryProfileOnCharacter");
_customizePlusOnScaleUpdate = pi.GetIpcSubscriber<Character, Guid, object>("CustomizePlus.Profile.OnUpdate");
_customizePlusRevertCharacter = pi.GetIpcSubscriber<ICharacter, int>("CustomizePlus.Profile.DeleteTemporaryProfileOnCharacter");
_customizePlusSetBodyScaleToCharacter = pi.GetIpcSubscriber<ICharacter, string, (int, Guid?)>("CustomizePlus.Profile.SetTemporaryProfileOnCharacter");
_customizePlusOnScaleUpdate = pi.GetIpcSubscriber<ICharacter, Guid, object>("CustomizePlus.Profile.OnUpdate");
_customizePlusDeleteByUniqueId = pi.GetIpcSubscriber<Guid, int>("CustomizePlus.Profile.DeleteTemporaryProfileByUniqueId");
_customizePlusOnScaleUpdate.Subscribe(OnCustomizePlusScaleChange);
_honorificApiVersion = pi.GetIpcSubscriber<(uint, uint)>("Honorific.ApiVersion");
_honorificGetLocalCharacterTitle = pi.GetIpcSubscriber<string>("Honorific.GetLocalCharacterTitle");
_honorificClearCharacterTitle = pi.GetIpcSubscriber<Character, object>("Honorific.ClearCharacterTitle");
_honorificSetCharacterTitle = pi.GetIpcSubscriber<Character, string, object>("Honorific.SetCharacterTitle");
_honorificClearCharacterTitle = pi.GetIpcSubscriber<ICharacter, object>("Honorific.ClearCharacterTitle");
_honorificSetCharacterTitle = pi.GetIpcSubscriber<ICharacter, string, object>("Honorific.SetCharacterTitle");
_honorificLocalCharacterTitleChanged = pi.GetIpcSubscriber<string, object>("Honorific.LocalCharacterTitleChanged");
_honorificDisposing = pi.GetIpcSubscriber<object>("Honorific.Disposing");
_honorificReady = pi.GetIpcSubscriber<object>("Honorific.Ready");
@@ -231,7 +231,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is Character c)
if (gameObj is ICharacter c)
{
Logger.LogTrace("CustomizePlus reverting for {chara}", c.Address.ToString("X"));
_customizePlusRevertCharacter!.InvokeFunc(c);
@@ -254,7 +254,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
return await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is Character c)
if (gameObj is ICharacter c)
{
string decodedScale = Encoding.UTF8.GetString(Convert.FromBase64String(scale));
Logger.LogTrace("CustomizePlus applying for {chara}", c.Address.ToString("X"));
@@ -280,7 +280,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
var scale = await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is Character c)
if (gameObj is ICharacter c)
{
var res = _customizePlusGetActiveProfile.InvokeFunc(c);
Logger.LogTrace("CustomizePlus GetActiveProfile returned {err}", res.Item1);
@@ -341,7 +341,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
return await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is Character c)
if (gameObj is ICharacter c)
{
if (_useLegacyGlamourer)
return _glamourerGetAllCustomizationLegacy.InvokeFunc(c) ?? string.Empty;
@@ -470,7 +470,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is PlayerCharacter c)
if (gameObj is IPlayerCharacter c)
{
Logger.LogTrace("Honorific removing for {addr}", c.Address.ToString("X"));
_honorificClearCharacterTitle!.InvokeAction(c);
@@ -494,7 +494,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
await _dalamudUtil.RunOnFrameworkThread(() =>
{
var gameObj = _dalamudUtil.CreateGameObject(character);
if (gameObj is PlayerCharacter pc)
if (gameObj is IPlayerCharacter pc)
{
string honorificData = string.IsNullOrEmpty(honorificDataB64) ? string.Empty : Encoding.UTF8.GetString(Convert.FromBase64String(honorificDataB64));
if (string.IsNullOrEmpty(honorificData))
@@ -848,7 +848,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
Mediator.Publish(new HeelsOffsetMessage());
}
private void OnCustomizePlusScaleChange(Character c, Guid g)
private void OnCustomizePlusScaleChange(ICharacter c, Guid g)
{
Mediator.Publish(new CustomizePlusMessage(c.Name.ToString() ?? string.Empty));
}
@@ -889,7 +889,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
_penumbraRedraw!.Invoke(0, RedrawType.Redraw);
}
private async Task PenumbraRedrawInternalAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, Action<Character> action)
private async Task PenumbraRedrawInternalAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, Action<ICharacter> action)
{
Mediator.Publish(new PenumbraStartRedrawMessage(handler.Address));

View File

@@ -6,7 +6,7 @@ using Newtonsoft.Json;
namespace MareSynchronos.MareConfiguration;
public class ConfigurationMigrator(ILogger<ConfigurationMigrator> logger, DalamudPluginInterface pi,
public class ConfigurationMigrator(ILogger<ConfigurationMigrator> logger, IDalamudPluginInterface pi,
NotesConfigService notesConfig) : IHostedService
{
public void Migrate()

View File

@@ -153,7 +153,7 @@ public class MarePlugin : MediatorSubscriberBase, IHostedService
{
Mediator.Publish(new NotificationMessage("Abnormal Log Level",
$"Your log level is set to '{_mareConfigService.Current.LogLevel}' which is not recommended for normal usage. Set it to '{LogLevel.Information}' in \"Loporrit Settings -> Debug\" unless instructed otherwise.",
Dalamud.Interface.Internal.Notifications.NotificationType.Error, 15000));
Dalamud.Interface.ImGuiNotification.NotificationType.Error, 15000));
}
#endif
}

View File

@@ -30,28 +30,26 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dalamud.ContextMenu" Version="1.3.1" />
<PackageReference Include="DalamudPackager" Version="2.1.12" />
<PackageReference Include="DalamudPackager" Version="2.1.13" />
<PackageReference Include="Downloader" Version="3.0.6" />
<PackageReference Include="K4os.Compression.LZ4.Legacy" Version="1.3.6" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.3.6" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.92">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.152">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="7.0.11" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Glamourer.Api" Version="2.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.2" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.11.0.78383">
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.5" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.5" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.25.0.90414">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.32.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.2" />
</ItemGroup>
<ItemGroup Condition="Exists('..\Penumbra.Api\Penumbra.Api.csproj')">
<ItemGroup Condition="Exists('..\Penumbra.Api\Penumbra.Api.csproj')">
<ProjectReference Include="..\Penumbra.Api\Penumbra.Api.csproj" />
</ItemGroup>
@@ -59,7 +57,7 @@
<PackageReference Include="Penumbra.Api" Version="5.1.0" />
</ItemGroup>
<ItemGroup Condition="Exists('..\Penumbra.Api\Penumbra.Api.csproj')">
<ItemGroup Condition="Exists('..\Glamourer.Api\Glamourer.Api.csproj')">
<ProjectReference Include="..\Glamourer.Api\Glamourer.Api.csproj" />
</ItemGroup>

View File

@@ -73,7 +73,7 @@ public class MareCharaFileManager : DisposableMediatorSubscriberBase
public bool CurrentlyWorking { get; private set; } = false;
public MareCharaFileHeader? LoadedCharaFile { get; private set; }
public async Task ApplyMareCharaFile(GameObject? charaTarget, long expectedLength)
public async Task ApplyMareCharaFile(IGameObject? charaTarget, long expectedLength)
{
if (charaTarget == null) return;
Dictionary<string, string> extractedFiles = new(StringComparer.Ordinal);

View File

@@ -1,5 +1,7 @@
using Dalamud.Memory;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
@@ -112,13 +114,13 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
private ushort[] MainHandData { get; set; } = new ushort[3];
private ushort[] OffHandData { get; set; } = new ushort[3];
public async Task ActOnFrameworkAfterEnsureNoDrawAsync(Action<Dalamud.Game.ClientState.Objects.Types.Character> act, CancellationToken token)
public async Task ActOnFrameworkAfterEnsureNoDrawAsync(Action<ICharacter> act, CancellationToken token)
{
while (await _dalamudUtil.RunOnFrameworkThread(() =>
{
if (IsBeingDrawn()) return true;
var gameObj = _dalamudUtil.CreateGameObject(Address);
if (gameObj is Dalamud.Game.ClientState.Objects.Types.Character chara)
if (gameObj is ICharacter chara)
{
act.Invoke(chara);
}
@@ -147,7 +149,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
return _getAddress.Invoke();
}
public Dalamud.Game.ClientState.Objects.Types.GameObject? GetGameObject()
public IGameObject? GetGameObject()
{
return _dalamudUtil.CreateGameObject(Address);
}
@@ -187,7 +189,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
if (Address != IntPtr.Zero)
{
_ptrNullCounter = 0;
var drawObjAddr = (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)Address)->DrawObject;
var drawObjAddr = (IntPtr)((GameObject*)Address)->DrawObject;
DrawObjectAddress = drawObjAddr;
}
else
@@ -209,7 +211,9 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
_clearCts = null;
}
var chara = (Character*)Address;
MemoryHelper.ReadStringNullTerminated((nint)chara->GameObject.Name, out var name);
string name;
fixed (byte* nameData = chara->GameObject.Name)
MemoryHelper.ReadStringNullTerminated((nint)nameData, out name);
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
if (nameChange)
{
@@ -240,7 +244,8 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
}
else
{
equipDiff = CompareAndUpdateEquipByteData((byte*)&chara->DrawData.Head);
fixed (EquipmentModelId* equipmentData = chara->DrawData.EquipmentModelIds)
equipDiff = CompareAndUpdateEquipByteData((byte*)equipmentData);
if (equipDiff)
Logger.LogTrace("Checking [{this}] equip data from game obj, result: {diff}", this, equipDiff);
}
@@ -259,7 +264,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
{
var gender = ((Human*)DrawObjectAddress)->Customize.Sex;
var raceId = ((Human*)DrawObjectAddress)->Customize.Race;
var tribeId = ((Human*)DrawObjectAddress)->Customize.Clan;
var tribeId = ((Human*)DrawObjectAddress)->Customize.Tribe;
if (_isOwnedObject && ObjectKind == ObjectKind.Player
&& (gender != Gender || raceId != RaceId || tribeId != TribeId))
@@ -270,13 +275,15 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
TribeId = tribeId;
}
customizeDiff = CompareAndUpdateCustomizeData(((Human*)DrawObjectAddress)->Customize.Data);
fixed (byte* customizeData = ((Human*)DrawObjectAddress)->Customize.Data)
customizeDiff = CompareAndUpdateCustomizeData(customizeData);
if (customizeDiff)
Logger.LogTrace("Checking [{this}] customize data as human from draw obj, result: {diff}", this, customizeDiff);
}
else
{
customizeDiff = CompareAndUpdateCustomizeData(chara->DrawData.CustomizeData.Data);
fixed (byte* customizeData = ((Human*)DrawObjectAddress)->Customize.Data)
customizeDiff = CompareAndUpdateCustomizeData(customizeData);
if (customizeDiff)
Logger.LogTrace("Checking [{this}] customize data from game obj, result: {diff}", this, equipDiff);
}
@@ -385,7 +392,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
private unsafe IntPtr GetDrawObjUnsafe(nint curPtr)
{
return (IntPtr)((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->DrawObject;
return (IntPtr)((GameObject*)curPtr)->DrawObject;
}
private bool IsBeingDrawn()
@@ -426,7 +433,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
{
var drawObjZero = drawObj == IntPtr.Zero;
if (drawObjZero) return DrawCondition.DrawObjectZero;
var renderFlags = (((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)curPtr)->RenderFlags) != 0x0;
var renderFlags = ((GameObject*)curPtr)->RenderFlags != 0x0;
if (renderFlags) return DrawCondition.RenderFlags;
if (ObjectKind == ObjectKind.Player)

View File

@@ -118,7 +118,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
public nint PlayerCharacter => _charaHandler?.Address ?? nint.Zero;
public unsafe uint PlayerCharacterId => (_charaHandler?.Address ?? nint.Zero) == nint.Zero
? uint.MaxValue
: ((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_charaHandler!.Address)->ObjectID;
: ((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_charaHandler!.Address)->EntityId;
public string? PlayerName { get; private set; }
public string PlayerNameHash => OnlineUser.Ident;

View File

@@ -1,4 +1,4 @@
using Dalamud.ContextMenu;
using Dalamud.Game.Gui.ContextMenu;
using Dalamud.Game.Text.SeStringHandling;
using Lumina.Excel.GeneratedSheets2;
using MareSynchronos.API.Data;
@@ -57,34 +57,38 @@ public class Pair
private PairHandler? CachedPlayer { get; set; }
public void AddContextMenu(GameObjectContextMenuOpenArgs args)
public void AddContextMenu(IMenuOpenedArgs args)
{
if (CachedPlayer == null || args.ObjectId != CachedPlayer.PlayerCharacterId || IsPaused) return;
if (CachedPlayer == null || true /* TODO: Check target */ || IsPaused) return;
SeStringBuilder seStringBuilder = new();
SeStringBuilder seStringBuilder2 = new();
SeStringBuilder seStringBuilder3 = new();
SeStringBuilder seStringBuilder4 = new();
var openProfileSeString = seStringBuilder.AddUiForeground(559).AddText(" ").AddUiForegroundOff().AddText("Open Profile").Build();
var reapplyDataSeString = seStringBuilder2.AddUiForeground(559).AddText(" ").AddUiForegroundOff().AddText("Reapply last data").Build();
var cyclePauseState = seStringBuilder3.AddUiForeground(559).AddText(" ").AddUiForegroundOff().AddText("Cycle pause state").Build();
var changePermissions = seStringBuilder4.AddUiForeground(559).AddText(" ").AddUiForegroundOff().AddText("Change Permissions").Build();
args.AddCustomItem(new GameObjectContextMenuItem(openProfileSeString, (a) =>
args.AddMenuItem(new MenuItem()
{
_mediator.Publish(new ProfileOpenStandaloneMessage(this));
}));
args.AddCustomItem(new GameObjectContextMenuItem(reapplyDataSeString, (a) =>
Name = "Open Profile",
OnClicked = (a) => _mediator.Publish(new ProfileOpenStandaloneMessage(this)),
PrefixColor = 559,
PrefixChar = '',
});
args.AddMenuItem(new MenuItem()
{
ApplyLastReceivedData(forced: true);
}, useDalamudIndicator: false));
args.AddCustomItem(new GameObjectContextMenuItem(changePermissions, (a) =>
Name = "Reapply last data",
OnClicked = (a) => ApplyLastReceivedData(forced: true),
PrefixColor = 559,
PrefixChar = '',
});
args.AddMenuItem(new MenuItem()
{
_mediator.Publish(new OpenPermissionWindow(this));
}, useDalamudIndicator: false));
args.AddCustomItem(new GameObjectContextMenuItem(cyclePauseState, (a) =>
Name = "Change Permissions",
OnClicked = (a) => _mediator.Publish(new OpenPermissionWindow(this)),
PrefixColor = 559,
PrefixChar = '',
});
args.AddMenuItem(new MenuItem()
{
_mediator.Publish(new CyclePauseMessage(UserData));
}, useDalamudIndicator: false));
Name = "Cycle pause state",
OnClicked = (a) => _mediator.Publish(new CyclePauseMessage(UserData)),
PrefixColor = 559,
PrefixChar = '',
});
}
public void ApplyData(OnlineUserCharaDataDto data)

View File

@@ -1,5 +1,6 @@
using Dalamud.ContextMenu;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Game.Gui.ContextMenu;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin.Services;
using MareSynchronos.API.Data;
using MareSynchronos.API.Data.Comparer;
using MareSynchronos.API.Data.Extensions;
@@ -18,14 +19,14 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
private readonly ConcurrentDictionary<UserData, Pair> _allClientPairs = new(UserDataComparer.Instance);
private readonly ConcurrentDictionary<GroupData, GroupFullInfoDto> _allGroups = new(GroupDataComparer.Instance);
private readonly MareConfigService _configurationService;
private readonly DalamudContextMenu _dalamudContextMenu;
private readonly IContextMenu _dalamudContextMenu;
private readonly PairFactory _pairFactory;
private Lazy<List<Pair>> _directPairsInternal;
private Lazy<Dictionary<GroupFullInfoDto, List<Pair>>> _groupPairsInternal;
public PairManager(ILogger<PairManager> logger, PairFactory pairFactory,
MareConfigService configurationService, MareMediator mediator,
DalamudContextMenu dalamudContextMenu) : base(logger, mediator)
IContextMenu dalamudContextMenu) : base(logger, mediator)
{
_pairFactory = pairFactory;
_configurationService = configurationService;
@@ -35,7 +36,7 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
_directPairsInternal = DirectPairsLazy();
_groupPairsInternal = GroupPairsLazy();
_dalamudContextMenu.OnOpenGameObjectContextMenu += DalamudContextMenuOnOnOpenGameObjectContextMenu;
_dalamudContextMenu.OnMenuOpened += DalamudContextMenuOnMenuOpened;
}
public List<Pair> DirectPairs => _directPairsInternal.Value;
@@ -329,14 +330,14 @@ public sealed class PairManager : DisposableMediatorSubscriberBase
{
base.Dispose(disposing);
_dalamudContextMenu.OnOpenGameObjectContextMenu -= DalamudContextMenuOnOnOpenGameObjectContextMenu;
_dalamudContextMenu.OnMenuOpened -= DalamudContextMenuOnMenuOpened;
DisposePairs();
}
private void DalamudContextMenuOnOnOpenGameObjectContextMenu(GameObjectContextMenuOpenArgs args)
private void DalamudContextMenuOnMenuOpened(IMenuOpenedArgs args)
{
if (args.ObjectId == 0xE000000) return;
/* TODO: Check empty target */
if (!_configurationService.Current.EnableRightClickMenus) return;
foreach (var pair in _allClientPairs.Where((p => p.Value.IsVisible)))

View File

@@ -1,5 +1,4 @@
using Dalamud.ContextMenu;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
@@ -44,9 +43,10 @@ public sealed class Plugin : IDalamudPlugin
_realOnFrameworkUpdate(framework);
}
public Plugin(DalamudPluginInterface pluginInterface, ICommandManager commandManager, IDataManager gameData,
public Plugin(IDalamudPluginInterface pluginInterface, ICommandManager commandManager, IDataManager gameData,
IFramework framework, IObjectTable objectTable, IClientState clientState, ICondition condition, IChatGui chatGui,
IGameGui gameGui, IDtrBar dtrBar, IToastGui toastGui, IPluginLog pluginLog, ITargetManager targetManager, IGameLifecycle addonLifecycle)
IGameGui gameGui, IDtrBar dtrBar, IToastGui toastGui, IPluginLog pluginLog, ITargetManager targetManager, IGameLifecycle addonLifecycle,
INotificationManager notificationManager, ITextureProvider textureProvider, IContextMenu contextMenu)
{
Plugin.Self = this;
_hostBuilderRunTask = new HostBuilder()
@@ -67,7 +67,8 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton<MareMediator>();
collection.AddSingleton<FileCacheManager>();
collection.AddSingleton<ServerConfigurationManager>();
collection.AddSingleton<PairManager>();
collection.AddSingleton<PairManager>((s) => new PairManager(s.GetRequiredService<ILogger<PairManager>>(), s.GetRequiredService<PairFactory>(),
s.GetRequiredService<MareConfigService>(), s.GetRequiredService<MareMediator>(), contextMenu));
collection.AddSingleton<ApiController>();
collection.AddSingleton<MareCharaFileManager>();
collection.AddSingleton<PerformanceCollectorService>();
@@ -90,7 +91,6 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton<FileCompactor>();
collection.AddSingleton<TagHandler>();
collection.AddSingleton<UidDisplayHandler>();
collection.AddSingleton((s) => new DalamudContextMenu(pluginInterface));
collection.AddSingleton((s) => new DalamudUtilService(s.GetRequiredService<ILogger<DalamudUtilService>>(),
clientState, objectTable, framework, gameGui, toastGui, condition, gameData, targetManager,
s.GetRequiredService<MareMediator>(), s.GetRequiredService<PerformanceCollectorService>()));
@@ -136,10 +136,10 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<ServerConfigurationManager>(), s.GetRequiredService<PeriodicFileScanner>(), s.GetRequiredService<ApiController>(),
s.GetRequiredService<MareMediator>(), s.GetRequiredService<MareConfigService>()));
collection.AddScoped((s) => new NotificationService(s.GetRequiredService<ILogger<NotificationService>>(),
s.GetRequiredService<MareMediator>(), pluginInterface.UiBuilder, chatGui, s.GetRequiredService<MareConfigService>()));
s.GetRequiredService<MareMediator>(), notificationManager, chatGui, s.GetRequiredService<MareConfigService>()));
collection.AddScoped((s) => new UiSharedService(s.GetRequiredService<ILogger<UiSharedService>>(), s.GetRequiredService<IpcManager>(), s.GetRequiredService<ApiController>(),
s.GetRequiredService<PeriodicFileScanner>(), s.GetRequiredService<FileDialogManager>(), s.GetRequiredService<MareConfigService>(), s.GetRequiredService<DalamudUtilService>(),
pluginInterface, s.GetRequiredService<Dalamud.Localization>(), s.GetRequiredService<ServerConfigurationManager>(), s.GetRequiredService<MareMediator>()));
pluginInterface, textureProvider, s.GetRequiredService<Dalamud.Localization>(), s.GetRequiredService<ServerConfigurationManager>(), s.GetRequiredService<MareMediator>()));
collection.AddHostedService(p => p.GetRequiredService<MareMediator>());
collection.AddHostedService(p => p.GetRequiredService<ConfigurationMigrator>());

View File

@@ -1,4 +1,5 @@
using Dalamud.Game.Command;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin.Services;
using MareSynchronos.FileCache;
using MareSynchronos.MareConfiguration;
@@ -69,7 +70,7 @@ public sealed class CommandManagerService : IDisposable
if (_apiController.ServerState == WebAPI.SignalR.Utils.ServerState.Disconnecting)
{
_mediator.Publish(new NotificationMessage("Loporrit disconnecting", "Cannot use /toggle while Loporrit is still disconnecting",
Dalamud.Interface.Internal.Notifications.NotificationType.Error));
NotificationType.Error));
}
if (_serverConfigurationManager.CurrentServer == null) return;

View File

@@ -1,6 +1,5 @@
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Control;
@@ -13,7 +12,7 @@ using Microsoft.Extensions.Logging;
using System.Numerics;
using System.Runtime.CompilerServices;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
using DalamudGameObject = Dalamud.Game.ClientState.Objects.Types.GameObject;
using DalamudGameObject = Dalamud.Game.ClientState.Objects.Types.IGameObject;
namespace MareSynchronos.Services;
@@ -67,7 +66,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_performanceCollector = performanceCollector;
WorldData = new(() =>
{
return gameData.GetExcelSheet<Lumina.Excel.GeneratedSheets.World>(Dalamud.ClientLanguage.English)!
return gameData.GetExcelSheet<Lumina.Excel.GeneratedSheets.World>(Dalamud.Game.ClientLanguage.English)!
.Where(w => w.IsPublic && !w.Name.RawData.IsEmpty)
.ToDictionary(w => (ushort)w.RowId, w => w.Name.ToString());
});
@@ -90,7 +89,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
}
public unsafe GameObject* GposeTarget => TargetSystem.Instance()->GPoseTarget;
public unsafe Dalamud.Game.ClientState.Objects.Types.GameObject? GposeTargetGameObject => GposeTarget == null ? null : _objectTable[GposeTarget->ObjectIndex];
public unsafe DalamudGameObject? GposeTargetGameObject => GposeTarget == null ? null : _objectTable[GposeTarget->ObjectIndex];
public bool IsAnythingDrawing { get; private set; } = false;
public bool IsInCutscene { get; private set; } = false;
public bool IsInGpose { get; private set; } = false;
@@ -103,13 +102,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public MareMediator Mediator { get; }
public Dalamud.Game.ClientState.Objects.Types.GameObject? CreateGameObject(IntPtr reference)
public DalamudGameObject? CreateGameObject(IntPtr reference)
{
EnsureIsOnFramework();
return _objectTable.CreateObjectReference(reference);
}
public async Task<Dalamud.Game.ClientState.Objects.Types.GameObject?> CreateGameObjectAsync(IntPtr reference)
public async Task<DalamudGameObject?> CreateGameObjectAsync(IntPtr reference)
{
return await RunOnFrameworkThread(() => _objectTable.CreateObjectReference(reference)).ConfigureAwait(false);
}
@@ -119,12 +118,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
if (!_framework.IsInFrameworkUpdateThread) throw new InvalidOperationException("Can only be run on Framework");
}
public Dalamud.Game.ClientState.Objects.Types.Character? GetCharacterFromObjectTableByIndex(int index)
public Dalamud.Game.ClientState.Objects.Types.ICharacter? GetCharacterFromObjectTableByIndex(int index)
{
EnsureIsOnFramework();
var objTableObj = _objectTable[index];
if (objTableObj!.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) return null;
return (Dalamud.Game.ClientState.Objects.Types.Character)objTableObj;
return (Dalamud.Game.ClientState.Objects.Types.ICharacter)objTableObj;
}
public unsafe IntPtr GetCompanion(IntPtr? playerPointer = null)
@@ -141,10 +140,10 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
return await RunOnFrameworkThread(() => GetCompanion(playerPointer)).ConfigureAwait(false);
}
public Dalamud.Game.ClientState.Objects.Types.Character? GetGposeCharacterFromObjectTableByName(string name, bool onlyGposeCharacters = false)
public Dalamud.Game.ClientState.Objects.Types.ICharacter? GetGposeCharacterFromObjectTableByName(string name, bool onlyGposeCharacters = false)
{
EnsureIsOnFramework();
return (Dalamud.Game.ClientState.Objects.Types.Character?)_objectTable
return (Dalamud.Game.ClientState.Objects.Types.ICharacter?)_objectTable
.FirstOrDefault(i => (!onlyGposeCharacters || i.ObjectIndex >= 200) && string.Equals(i.Name.ToString(), name, StringComparison.Ordinal));
}
@@ -247,13 +246,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
return _objectTable.Any(f => f.Address == key);
}
public bool IsObjectPresent(Dalamud.Game.ClientState.Objects.Types.GameObject? obj)
public bool IsObjectPresent(Dalamud.Game.ClientState.Objects.Types.IGameObject? obj)
{
EnsureIsOnFramework();
return obj != null && obj.IsValid();
}
public async Task<bool> IsObjectPresentAsync(Dalamud.Game.ClientState.Objects.Types.GameObject? obj)
public async Task<bool> IsObjectPresentAsync(Dalamud.Game.ClientState.Objects.Types.IGameObject? obj)
{
return await RunOnFrameworkThread(() => IsObjectPresent(obj)).ConfigureAwait(false);
}
@@ -368,7 +367,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
Thread.Sleep(tick * 2);
}
public Vector2 WorldToScreen(Dalamud.Game.ClientState.Objects.Types.GameObject? obj)
public Vector2 WorldToScreen(Dalamud.Game.ClientState.Objects.Types.IGameObject? obj)
{
if (obj == null) return Vector2.Zero;
return _gameGui.WorldToScreen(obj.Position, out var screenPos) ? screenPos : Vector2.Zero;
@@ -382,12 +381,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
private unsafe PlayerInfo GetPlayerInfo(DalamudGameObject chara)
{
uint id = chara.ObjectId;
uint id = chara.EntityId;
if (!_playerInfoCache.TryGetValue(id, out var info))
{
info.Character.ObjectId = id;
MemoryHelper.ReadStringNullTerminated((nint)((GameObject*)chara.Address)->Name, out info.Character.Name);
info.Character.Name = chara.Name.TextValue; // ?
info.Character.HomeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld;
info.Character.Address = chara.Address;
info.Hash = Crypto.GetHash256(info.Character.Name + info.Character.HomeWorldId.ToString());

View File

@@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using MareSynchronos.API.Data;
using MareSynchronos.API.Dto;
using MareSynchronos.API.Dto.Group;

View File

@@ -1,6 +1,6 @@
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Interface;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin.Services;
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Models;
@@ -11,13 +11,13 @@ namespace MareSynchronos.Services;
public class NotificationService : DisposableMediatorSubscriberBase
{
private readonly INotificationManager _notificationManager;
private readonly IChatGui _chatGui;
private readonly MareConfigService _configurationService;
private readonly UiBuilder _uiBuilder;
public NotificationService(ILogger<NotificationService> logger, MareMediator mediator, UiBuilder uiBuilder, IChatGui chatGui, MareConfigService configurationService) : base(logger, mediator)
public NotificationService(ILogger<NotificationService> logger, MareMediator mediator, INotificationManager notificationManager, IChatGui chatGui, MareConfigService configurationService) : base(logger, mediator)
{
_uiBuilder = uiBuilder;
_notificationManager = notificationManager;
_chatGui = chatGui;
_configurationService = configurationService;
@@ -108,6 +108,12 @@ public class NotificationService : DisposableMediatorSubscriberBase
private void ShowToast(NotificationMessage msg)
{
_uiBuilder.AddNotification(msg.Message ?? string.Empty, "[LoporritSync] " + msg.Title, msg.Type, msg.TimeShownOnScreen);
var notification = new Notification{
Content = msg.Message ?? string.Empty,
Title = "[LoporritSync] " + msg.Title,
Type = msg.Type,
InitialDuration = TimeSpan.FromMilliseconds(msg.TimeShownOnScreen)
};
_notificationManager.AddNotification(notification);
}
}

View File

@@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using MareSynchronos.API.Data;
using MareSynchronos.API.Data.Comparer;
using MareSynchronos.Interop;

View File

@@ -12,14 +12,14 @@ namespace MareSynchronos.Services;
public sealed class UiService : DisposableMediatorSubscriberBase
{
private readonly List<WindowMediatorSubscriberBase> _createdWindows = [];
private readonly UiBuilder _uiBuilder;
private readonly IUiBuilder _uiBuilder;
private readonly FileDialogManager _fileDialogManager;
private readonly ILogger<UiService> _logger;
private readonly MareConfigService _mareConfigService;
private readonly WindowSystem _windowSystem;
private readonly UiFactory _uiFactory;
public UiService(ILogger<UiService> logger, UiBuilder uiBuilder,
public UiService(ILogger<UiService> logger, IUiBuilder uiBuilder,
MareConfigService mareConfigService, WindowSystem windowSystem,
IEnumerable<WindowMediatorSubscriberBase> windows,
UiFactory uiFactory, FileDialogManager fileDialogManager,

View File

@@ -116,12 +116,12 @@ public class CompactUi : WindowMediatorSubscriberBase
if (!_apiController.IsCurrentVersion)
{
var ver = _apiController.CurrentClientVersion;
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
var unsupported = "UNSUPPORTED VERSION";
var uidTextSize = ImGui.CalcTextSize(unsupported);
ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMax().X + ImGui.GetWindowContentRegionMin().X) / 2 - uidTextSize.X / 2);
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
UiSharedService.ColorTextWrapped($"Your Loporrit installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " +
$"It is highly recommended to keep Loporrit up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed);
}
@@ -510,9 +510,9 @@ public class CompactUi : WindowMediatorSubscriberBase
var uidText = GetUidText();
var buttonSizeX = 0f;
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
var uidTextSize = ImGui.CalcTextSize(uidText);
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
var originalPos = ImGui.GetCursorPos();
ImGui.SetWindowFontScale(1.5f);
@@ -544,9 +544,9 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.SetCursorPosY(originalPos.Y + buttonSize.Y / 2 - uidTextSize.Y / 2 - ImGui.GetStyle().ItemSpacing.Y / 2);
ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMax().X + ImGui.GetWindowContentRegionMin().X) / 2 + buttonSizeX - uidTextSize.X / 2);
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
ImGui.TextColored(GetUidColor(), uidText);
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
if (_apiController.ServerState is not ServerState.Connected)
{

View File

@@ -28,7 +28,7 @@ internal class ReportPopupHandler : IPopupHandler
public void DrawContent()
{
using (ImRaii.PushFont(_uiSharedService.UidFont))
using (_uiSharedService.UidFont.Push())
UiSharedService.TextWrapped("Report " + _reportedPair!.UserData.AliasOrUID + " Profile");
ImGui.InputTextMultiline("##reportReason", ref _reportReason, 500, new Vector2(500 - ImGui.GetStyle().ItemSpacing.X * 2, 200));

View File

@@ -187,7 +187,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
try
{
if (_uiShared.UidFontBuilt && _configService.Current.ShowUploadingBigText) ImGui.PushFont(_uiShared.UidFont);
if (_configService.Current.ShowUploadingBigText) _uiShared.UidFont.Push();
var uploadText = "Uploading";
var textSize = ImGui.CalcTextSize(uploadText);
@@ -204,7 +204,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
}
finally
{
if (_uiShared.UidFontBuilt && _configService.Current.ShowUploadingBigText) ImGui.PopFont();
if (_configService.Current.ShowUploadingBigText) _uiShared.UidFont.Pop();
}
}
}

View File

@@ -32,7 +32,7 @@ public sealed class DtrEntry : IDisposable, IHostedService
private readonly CancellationTokenSource _cancellationTokenSource = new();
private readonly ConfigurationServiceBase<MareConfig> _configService;
private readonly IDtrBar _dtrBar;
private readonly Lazy<DtrBarEntry> _entry;
private readonly Lazy<IDtrBarEntry> _entry;
private readonly ILogger<DtrEntry> _logger;
private readonly MareMediator _mareMediator;
private readonly PairManager _pairManager;
@@ -56,7 +56,7 @@ public sealed class DtrEntry : IDisposable, IHostedService
{
_logger.LogDebug("Disposing DtrEntry");
Clear();
_entry.Value.Dispose();
_entry.Value.Remove();
}
}
@@ -92,7 +92,7 @@ public sealed class DtrEntry : IDisposable, IHostedService
_entry.Value.Shown = false;
}
private DtrBarEntry CreateEntry()
private IDtrBarEntry CreateEntry()
{
_logger.LogTrace("Creating new DtrBar entry");
var entry = _dtrBar.Get("Loporrit");

View File

@@ -1,8 +1,7 @@
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using ImGuiNET;
using MareSynchronos.API.Data;
@@ -12,6 +11,8 @@ using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.WebAPI;
using Microsoft.Extensions.Logging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace MareSynchronos.UI;
@@ -20,7 +21,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
private readonly ApiController _apiController;
private readonly FileDialogManager _fileDialogManager;
private readonly MareProfileManager _mareProfileManager;
private readonly UiBuilder _uiBuilder;
private readonly IUiBuilder _uiBuilder;
private readonly UiSharedService _uiSharedService;
private readonly ServerConfigurationManager _serverConfigurationManager;
private bool _adjustedForScollBarsLocalProfile = false;
@@ -33,7 +34,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
private bool _wasOpen;
public EditProfileUi(ILogger<EditProfileUi> logger, MareMediator mediator,
ApiController apiController, UiBuilder uiBuilder, UiSharedService uiSharedService,
ApiController apiController, IUiBuilder uiBuilder, UiSharedService uiSharedService,
FileDialogManager fileDialogManager, ServerConfigurationManager serverConfigurationManager,
MareProfileManager mareProfileManager) : base(logger, mediator, "Loporrit Edit Profile###LoporritSyncEditProfileUI")
{
@@ -79,7 +80,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
{
_profileImage = profile.ImageData.Value;
_pfpTextureWrap?.Dispose();
_pfpTextureWrap = _uiBuilder.LoadImage(_profileImage);
_pfpTextureWrap = _uiSharedService.LoadImage(_profileImage);
}
if (!string.Equals(_profileDescription, profile.Description, StringComparison.OrdinalIgnoreCase))
@@ -95,7 +96,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
var spacing = ImGui.GetStyle().ItemSpacing.X;
ImGuiHelpers.ScaledRelativeSameLine(256, spacing);
ImGui.PushFont(_uiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Axis12)).ImFont);
_uiSharedService.GameFont.Push();
var descriptionTextSize = ImGui.CalcTextSize(profile.Description, 256f);
var childFrame = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 256);
if (descriptionTextSize.Y > childFrame.Y)
@@ -115,7 +116,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
UiSharedService.TextWrapped(profile.Description);
}
ImGui.EndChildFrame();
ImGui.PopFont();
_uiSharedService.GameFont.Pop();
var nsfw = profile.IsNSFW;
ImGui.BeginDisabled();
@@ -191,13 +192,12 @@ public class EditProfileUi : WindowMediatorSubscriberBase
ImGui.SetCursorPosX(posX);
ImGuiHelpers.ScaledRelativeSameLine(widthTextBox, ImGui.GetStyle().ItemSpacing.X);
ImGui.TextUnformatted("Preview (approximate)");
ImGui.PushFont(_uiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Axis12)).ImFont);
ImGui.InputTextMultiline("##description", ref _descriptionText, 1500, ImGuiHelpers.ScaledVector2(widthTextBox, 200));
ImGui.PopFont();
using (_uiSharedService.GameFont.Push())
ImGui.InputTextMultiline("##description", ref _descriptionText, 1500, ImGuiHelpers.ScaledVector2(widthTextBox, 200));
ImGui.SameLine();
ImGui.PushFont(_uiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Axis12)).ImFont);
_uiSharedService.GameFont.Push();
var descriptionTextSizeLocal = ImGui.CalcTextSize(_descriptionText, 256f);
var childFrameLocal = ImGuiHelpers.ScaledVector2(256 + ImGui.GetStyle().WindowPadding.X + ImGui.GetStyle().WindowBorderSize, 200);
if (descriptionTextSizeLocal.Y > childFrameLocal.Y)
@@ -217,7 +217,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
UiSharedService.TextWrapped(_descriptionText);
}
ImGui.EndChildFrame();
ImGui.PopFont();
_uiSharedService.GameFont.Pop();
if (UiSharedService.NormalizedIconTextButton(FontAwesomeIcon.Save, "Save Description"))
{

View File

@@ -101,10 +101,10 @@ public class IntroUi : WindowMediatorSubscriberBase
}
else if (!_configService.Current.AcceptedAgreement && _readFirstPage)
{
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
var textSize = ImGui.CalcTextSize(Strings.ToS.LanguageLabel);
ImGui.TextUnformatted(Strings.ToS.AgreementLabel);
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
ImGui.SameLine();
var languageSize = ImGui.CalcTextSize(Strings.ToS.LanguageLabel);
@@ -155,9 +155,9 @@ public class IntroUi : WindowMediatorSubscriberBase
|| !_configService.Current.InitialScanComplete
|| !Directory.Exists(_configService.Current.CacheFolder)))
{
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
ImGui.TextUnformatted("File Storage Setup");
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
ImGui.Separator();
if (!_uiShared.HasValidPenumbraModPath)
@@ -201,9 +201,9 @@ public class IntroUi : WindowMediatorSubscriberBase
}
else if (!_uiShared.ApiController.ServerAlive)
{
if (_uiShared.UidFontBuilt) ImGui.PushFont(_uiShared.UidFont);
_uiShared.UidFont.Push();
ImGui.TextUnformatted("Service Registration");
if (_uiShared.UidFontBuilt) ImGui.PopFont();
_uiShared.UidFont.Pop();
ImGui.Separator();
UiSharedService.TextWrapped("To be able to use Loporrit you will have to register an account.");
UiSharedService.TextWrapped("Refer to the instructions at the location you obtained this plugin for more information or support.");

View File

@@ -1,6 +1,5 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
@@ -29,11 +28,11 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
private IDalamudTextureWrap? _supporterTextureWrap;
private IDalamudTextureWrap? _textureWrap;
public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiBuilder,
public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiSharedService,
ServerConfigurationManager serverManager, MareConfigService mareConfigService,
MareProfileManager mareProfileManager, PairManager pairManager) : base(logger, mediator, "###LoporritSyncPopoutProfileUI")
{
_uiSharedService = uiBuilder;
_uiSharedService = uiSharedService;
_serverManager = serverManager;
_mareProfileManager = mareProfileManager;
_pairManager = pairManager;
@@ -111,7 +110,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
var rectMin = drawList.GetClipRectMin();
var rectMax = drawList.GetClipRectMax();
using (ImRaii.PushFont(_uiSharedService.UidFont, _uiSharedService.UidFontBuilt))
using (_uiSharedService.UidFont.Push())
UiSharedService.ColorText(_pair.UserData.AliasOrUID, UiSharedService.AccentColor);
ImGuiHelpers.ScaledDummy(spacing.Y, spacing.Y);
@@ -158,7 +157,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
}
ImGui.Separator();
ImGui.PushFont(_uiSharedService.GetGameFontHandle());
_uiSharedService.GameFont.Push();
var remaining = ImGui.GetWindowContentRegionMax().Y - ImGui.GetCursorPosY();
var descText = mareProfile.Description;
var textSize = ImGui.CalcTextSize(descText, 256f * ImGuiHelpers.GlobalScale);
@@ -169,7 +168,8 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
textSize = ImGui.CalcTextSize(descText + $"...{Environment.NewLine}[Open Full Profile for complete description]", 256f * ImGuiHelpers.GlobalScale);
}
UiSharedService.TextWrapped(trimmed ? descText + $"...{Environment.NewLine}[Open Full Profile for complete description]" : mareProfile.Description);
ImGui.PopFont();
_uiSharedService.GameFont.Pop();
var padding = ImGui.GetStyle().WindowPadding.X / 2;
bool tallerThanWide = _textureWrap.Height >= _textureWrap.Width;

View File

@@ -1,6 +1,5 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
@@ -77,7 +76,7 @@ public class StandaloneProfileUi : WindowMediatorSubscriberBase
var rectMax = drawList.GetClipRectMax();
var headerSize = ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y;
using (ImRaii.PushFont(_uiSharedService.UidFont, _uiSharedService.UidFontBuilt))
using (_uiSharedService.UidFont.Push())
UiSharedService.ColorText(Pair.UserData.AliasOrUID, UiSharedService.AccentColor);
ImGuiHelpers.ScaledDummy(new Vector2(spacing.Y, spacing.Y));
@@ -107,9 +106,8 @@ public class StandaloneProfileUi : WindowMediatorSubscriberBase
};
if (ImGui.BeginChildFrame(1000, childFrame))
{
ImGui.PushFont(_uiSharedService.GetGameFontHandle());
ImGui.TextWrapped(mareProfile.Description);
ImGui.PopFont();
using (_uiSharedService.GameFont.Push())
ImGui.TextWrapped(mareProfile.Description);
}
ImGui.EndChildFrame();

View File

@@ -61,7 +61,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
using var id = ImRaii.PushId("syncshell_admin_" + GroupFullInfo.GID);
using (ImRaii.PushFont(_uiSharedService.UidFont))
using (_uiSharedService.UidFont.Push())
ImGui.TextUnformatted(GroupFullInfo.GroupAliasOrGID + " Administrative Panel");
ImGui.Separator();

View File

@@ -2,10 +2,12 @@
using Dalamud.Interface.Colors;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Internal;
using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using ImGuiNET;
using MareSynchronos.FileCache;
@@ -48,7 +50,8 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
private readonly DalamudUtilService _dalamudUtil;
private readonly IpcManager _ipcManager;
private readonly Dalamud.Localization _localization;
private readonly DalamudPluginInterface _pluginInterface;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly ITextureProvider _textureProvider;
private readonly Dictionary<string, object> _selectedComboItems = new(StringComparer.Ordinal);
private readonly ServerConfigurationManager _serverConfigurationManager;
private bool _cacheDirectoryHasOtherFilesThanCache = false;
@@ -76,7 +79,8 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public UiSharedService(ILogger<UiSharedService> logger, IpcManager ipcManager, ApiController apiController,
PeriodicFileScanner cacheScanner, FileDialogManager fileDialogManager,
MareConfigService configService, DalamudUtilService dalamudUtil, DalamudPluginInterface pluginInterface, Dalamud.Localization localization,
MareConfigService configService, DalamudUtilService dalamudUtil, IDalamudPluginInterface pluginInterface,
ITextureProvider textureProvider, Dalamud.Localization localization,
ServerConfigurationManager serverManager, MareMediator mediator) : base(logger, mediator)
{
_ipcManager = ipcManager;
@@ -86,6 +90,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
_configService = configService;
_dalamudUtil = dalamudUtil;
_pluginInterface = pluginInterface;
_textureProvider = textureProvider;
_localization = localization;
_serverConfigurationManager = serverManager;
@@ -93,8 +98,14 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
_isDirectoryWritable = IsDirectoryWritable(_configService.Current.CacheFolder);
_pluginInterface.UiBuilder.BuildFonts += BuildFont;
_pluginInterface.UiBuilder.RebuildFonts();
UidFont = _pluginInterface.UiBuilder.FontAtlas.NewDelegateFontHandle(e =>
{
e.OnPreBuild(tk => tk.AddDalamudAssetFont(Dalamud.DalamudAsset.NotoSansJpMedium, new()
{
SizePx = 35
}));
});
GameFont = _pluginInterface.UiBuilder.FontAtlas.NewGameFontHandle(new(GameFontFamilyAndSize.Axis12));
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (_) =>
{
@@ -118,9 +129,8 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public string PlayerName => _dalamudUtil.GetPlayerName();
public ImFontPtr UidFont { get; private set; }
public bool UidFontBuilt { get; private set; }
public IFontHandle UidFont { get; init; }
public IFontHandle GameFont { get; init; }
public Dictionary<ushort, string> WorldData => _dalamudUtil.WorldData.Value;
@@ -287,6 +297,13 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
ImGui.TextUnformatted(text);
}
public static void FontText(string text, IFontHandle font, Vector4? color = null)
{
using var pushedFont = font.Push();
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, Color(color ?? new Vector4(1, 1, 1, 1)), color != null);
ImGui.TextUnformatted(text);
}
public static Vector4 GetBoolColor(bool input) => input ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
public static Vector2 GetIconButtonSize(FontAwesomeIcon icon)
@@ -563,7 +580,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public void BigText(string text)
{
using var font = ImRaii.PushFont(UidFont, UidFontBuilt);
using var font = UidFont.Push();
ImGui.TextUnformatted(text);
}
@@ -903,21 +920,9 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
[LibraryImport("user32")]
internal static partial short GetKeyState(int nVirtKey);
internal ImFontPtr GetGameFontHandle()
{
return _pluginInterface.UiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Axis12)).ImFont;
}
internal IDalamudTextureWrap LoadImage(byte[] imageData)
{
return _pluginInterface.UiBuilder.LoadImage(imageData);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_pluginInterface.UiBuilder.BuildFonts -= BuildFont;
return _textureProvider.CreateFromImageAsync(imageData).Result;
}
private static void CenterWindow(float width, float height, ImGuiCond cond = ImGuiCond.None)
@@ -930,27 +935,4 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
[GeneratedRegex(@"^(?:[a-zA-Z]:\\[\w\s\-\\]+?|\/(?:[\w\s\-\/])+?)$", RegexOptions.ECMAScript)]
#pragma warning restore MA0009 // Add regex evaluation timeout
private static partial Regex PathRegex();
private void BuildFont()
{
var fontFile = Path.Combine(_pluginInterface.DalamudAssetDirectory.FullName, "UIRes", "NotoSansCJKjp-Medium.otf");
UidFontBuilt = false;
if (File.Exists(fontFile))
{
try
{
UidFont = ImGui.GetIO().Fonts.AddFontFromFileTTF(fontFile, 35);
UidFontBuilt = true;
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Font failed to load. {fontFile}", fontFile);
}
}
else
{
Logger.LogDebug("Font doesn't exist. {fontFile}", fontFile);
}
}
}

View File

@@ -196,7 +196,7 @@ public static class VariousExtensions
return JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(obj))!;
}
public static unsafe int? ObjectTableIndex(this GameObject? gameObject)
public static unsafe int? ObjectTableIndex(this IGameObject? gameObject)
{
if (gameObject == null || gameObject.Address == IntPtr.Zero)
{

View File

@@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using MareSynchronos.API.Data.Enum;
using MareSynchronos.API.Dto;
using MareSynchronos.API.Dto.Group;

View File

@@ -1,4 +1,5 @@
using Dalamud.Utility;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Utility;
using MareSynchronos.API.Data;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.API.Dto;
@@ -179,7 +180,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
$"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " +
$"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " +
$"This client version is incompatible and will not be able to connect. Please update your Loporrit client.",
Dalamud.Interface.Internal.Notifications.NotificationType.Error));
NotificationType.Error));
}
await StopConnection(ServerState.VersionMisMatch).ConfigureAwait(false);
return;
@@ -191,7 +192,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
$"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " +
$"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " +
$"Please keep your Loporrit client up-to-date.",
Dalamud.Interface.Internal.Notifications.NotificationType.Warning));
NotificationType.Warning));
}
await LoadIninitialPairs().ConfigureAwait(false);

View File

@@ -1,4 +1,5 @@
using MareSynchronos.API.Routes;
using Dalamud.Interface.ImGuiNotification;
using MareSynchronos.API.Routes;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
@@ -83,8 +84,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
if (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
Mediator.Publish(new NotificationMessage("Error refreshing token", "Your authentication token could not be renewed. Try reconnecting manually.",
Dalamud.Interface.Internal.Notifications.NotificationType.Error));
Mediator.Publish(new NotificationMessage("Error refreshing token", "Your authentication token could not be renewed. Try reconnecting manually.", NotificationType.Error));
Mediator.Publish(new DisconnectedMessage());
throw new MareAuthFailureException(response);
}

View File

@@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using MareSynchronos.Services.Mediator;
using Microsoft.AspNetCore.SignalR.Client;