add moodles integration (temporary)

get ready for moodles

don't ignore moodles warning

apply moodles after forced redraw
This commit is contained in:
rootdarkarchon
2024-02-29 13:04:12 +01:00
committed by Loporrit
parent da10895987
commit 98a0327294
13 changed files with 174 additions and 17 deletions

View File

@@ -0,0 +1,104 @@
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Interop.Ipc;
public sealed class IpcCallerMoodles : IIpcCaller
{
private readonly ICallGateSubscriber<int> _moodlesApiVersion;
private readonly ICallGateSubscriber<IPlayerCharacter, object> _moodlesOnChange;
private readonly ICallGateSubscriber<nint, string> _moodlesGetStatus;
private readonly ICallGateSubscriber<nint, string, object> _moodlesSetStatus;
private readonly ICallGateSubscriber<nint, object> _moodlesRevertStatus;
private readonly ILogger<IpcCallerMoodles> _logger;
private readonly DalamudUtilService _dalamudUtil;
private readonly MareMediator _mareMediator;
public IpcCallerMoodles(ILogger<IpcCallerMoodles> logger, IDalamudPluginInterface pi, DalamudUtilService dalamudUtil,
MareMediator mareMediator)
{
_logger = logger;
_dalamudUtil = dalamudUtil;
_mareMediator = mareMediator;
_moodlesApiVersion = pi.GetIpcSubscriber<int>("Moodles.Version");
_moodlesOnChange = pi.GetIpcSubscriber<IPlayerCharacter, object>("Moodles.StatusManagerModified");
_moodlesGetStatus = pi.GetIpcSubscriber<nint, string>("Moodles.GetStatusManagerByPtr");
_moodlesSetStatus = pi.GetIpcSubscriber<nint, string, object>("Moodles.SetStatusManagerByPtr");
_moodlesRevertStatus = pi.GetIpcSubscriber<nint, object>("Moodles.ClearStatusManagerByPtr");
_moodlesOnChange.Subscribe(OnMoodlesChange);
CheckAPI();
}
private void OnMoodlesChange(IPlayerCharacter character)
{
_mareMediator.Publish(new MoodlesMessage(character.Address));
}
public bool APIAvailable { get; private set; } = false;
public void CheckAPI()
{
try
{
APIAvailable = _moodlesApiVersion.InvokeFunc() == 1;
}
catch
{
APIAvailable = false;
}
}
public void Dispose()
{
_moodlesOnChange.Unsubscribe(OnMoodlesChange);
}
public async Task<string?> GetStatusAsync(nint address)
{
if (!APIAvailable) return null;
try
{
return await _dalamudUtil.RunOnFrameworkThread(() => _moodlesGetStatus.InvokeFunc(address)).ConfigureAwait(false);
}
catch (Exception e)
{
_logger.LogWarning(e, "Could not Get Moodles Status");
return null;
}
}
public async Task SetStatusAsync(nint pointer, string status)
{
if (!APIAvailable) return;
try
{
await _dalamudUtil.RunOnFrameworkThread(() => _moodlesSetStatus.InvokeAction(pointer, status)).ConfigureAwait(false);
}
catch (Exception e)
{
_logger.LogWarning(e, "Could not Set Moodles Status");
}
}
public async Task RevertStatusAsync(nint pointer)
{
if (!APIAvailable) return;
try
{
await _dalamudUtil.RunOnFrameworkThread(() => _moodlesRevertStatus.InvokeAction(pointer)).ConfigureAwait(false);
}
catch (Exception e)
{
_logger.LogWarning(e, "Could not Set Moodles Status");
}
}
}

View File

@@ -7,7 +7,7 @@ public sealed partial class IpcManager : DisposableMediatorSubscriberBase
{
public IpcManager(ILogger<IpcManager> logger, MareMediator mediator,
IpcCallerPenumbra penumbraIpc, IpcCallerGlamourer glamourerIpc, IpcCallerCustomize customizeIpc, IpcCallerHeels heelsIpc,
IpcCallerHonorific honorificIpc, IpcCallerPetNames ipcCallerPetNames) : base(logger, mediator)
IpcCallerHonorific honorificIpc, IpcCallerPetNames ipcCallerPetNames, IpcCallerMoodles moodlesIpc) : base(logger, mediator)
{
CustomizePlus = customizeIpc;
Heels = heelsIpc;
@@ -15,6 +15,7 @@ public sealed partial class IpcManager : DisposableMediatorSubscriberBase
Penumbra = penumbraIpc;
Honorific = honorificIpc;
PetNames = ipcCallerPetNames;
Moodles = moodlesIpc;
if (Initialized)
{
@@ -41,6 +42,7 @@ public sealed partial class IpcManager : DisposableMediatorSubscriberBase
public IpcCallerGlamourer Glamourer { get; }
public IpcCallerPenumbra Penumbra { get; }
public IpcCallerPetNames PetNames { get; }
public IpcCallerMoodles Moodles { get; }
private void PeriodicApiStateCheck()
{
@@ -51,5 +53,6 @@ public sealed partial class IpcManager : DisposableMediatorSubscriberBase
CustomizePlus.CheckAPI();
Honorific.CheckAPI();
PetNames.CheckAPI();
Moodles.CheckAPI();
}
}

View File

@@ -2,8 +2,6 @@
using MareSynchronos.API.Data.Enum;
using System.Text;
namespace MareSynchronos.PlayerData.Data;
public class CharacterData
@@ -15,6 +13,7 @@ public class CharacterData
public string HonorificData { get; set; } = string.Empty;
public string ManipulationString { get; set; } = string.Empty;
public string PetNamesData { get; set; } = string.Empty;
public string MoodlesData { get; set; } = string.Empty;
public API.Data.CharacterData ToAPI()
{
@@ -44,17 +43,8 @@ public class CharacterData
HeelsData = HeelsData,
CustomizePlusData = CustomizePlusScale.ToDictionary(d => d.Key, d => d.Value),
HonorificData = HonorificData,
PetNamesData = PetNamesData
PetNamesData = PetNamesData,
MoodlesData = MoodlesData
};
}
public override string ToString()
{
StringBuilder stringBuilder = new();
foreach (var fileReplacement in FileReplacements.SelectMany(k => k.Value).OrderBy(a => a.GamePaths.First(), StringComparer.Ordinal))
{
stringBuilder.Append(fileReplacement).AppendLine();
}
return stringBuilder.ToString();
}
}

View File

@@ -9,5 +9,6 @@ public enum PlayerChanges
Heels = 5,
Honorific = 7,
ForcedRedraw = 8,
Moodles = 9,
PetNames = 10,
}

View File

@@ -218,6 +218,7 @@ public class PlayerDataFactory
{
previousData.PetNamesData = _ipcManager.PetNames.GetLocalNames();
_logger.LogDebug("Pet Nicknames is now: {petnames}", previousData.PetNamesData);
previousData.MoodlesData = await _ipcManager.Moodles.GetStatusAsync(playerRelatedObject.Address).ConfigureAwait(false) ?? string.Empty;
}
if (previousData.FileReplacements.TryGetValue(objectKind, out HashSet<FileReplacement>? fileReplacements))

View File

@@ -404,6 +404,10 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
await _ipcManager.PetNames.SetPlayerData(handler.Address, charaData.PetNamesData).ConfigureAwait(false);
break;
case PlayerChanges.Moodles:
await _ipcManager.Moodles.SetStatusAsync(handler.Address, charaData.MoodlesData).ConfigureAwait(false);
break;
case PlayerChanges.ForcedRedraw:
await _ipcManager.Penumbra.RedrawAsync(Logger, handler, applicationId, token).ConfigureAwait(false);
break;
@@ -714,6 +718,8 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
await _ipcManager.Honorific.ClearTitleAsync(address).ConfigureAwait(false);
Logger.LogDebug("[{applicationId}] Restoring Pet Nicknames for {alias}/{name}", applicationId, Pair.UserData.AliasOrUID, name);
await _ipcManager.PetNames.ClearPlayerData(address).ConfigureAwait(false);
Logger.LogDebug("[{applicationId}] Restoring Moodles for {alias}/{name}", applicationId, Pair.UserData.AliasOrUID, name);
await _ipcManager.Moodles.RevertStatusAsync(address).ConfigureAwait(false);
}
else if (objectKind == ObjectKind.MinionOrMount)
{

View File

@@ -6,4 +6,5 @@ public record OptionalPluginWarning
public bool ShownCustomizePlusWarning { get; set; } = false;
public bool ShownHonorificWarning { get; set; } = false;
public bool ShowPetNicknamesWarning { get; set; } = false;
public bool ShownMoodlesWarning { get; set; } = false;
}

View File

@@ -21,6 +21,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
private Task? _cacheCreationTask;
private CancellationTokenSource _honorificCts = new();
private CancellationTokenSource _petNicknamesCts = new();
private CancellationTokenSource _moodlesCts = new();
private bool _isZoning = false;
private readonly Dictionary<ObjectKind, CancellationTokenSource> _glamourerCts = new();
@@ -122,7 +123,17 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
PetNicknamesChanged();
}
});
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, (msg) =>
Mediator.Subscribe<MoodlesMessage>(this, (msg) =>
{
if (_isZoning) return;
var changedType = _playerRelatedObjects.FirstOrDefault(f => f.Value.Address == msg.Address);
if (!default(KeyValuePair<ObjectKind, GameObjectHandler>).Equals(changedType) && changedType.Key == ObjectKind.Player)
{
Logger.LogDebug("Received Moodles change, updating player");
MoodlesChanged();
}
});
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, async (msg) =>
{
Logger.LogDebug("Received Penumbra Mod settings change, updating player");
_ = AddPlayerCacheToCreate();
@@ -191,6 +202,20 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
}, token);
}
private void MoodlesChanged()
{
_moodlesCts?.Cancel();
_moodlesCts?.Dispose();
_moodlesCts = new();
var token = _moodlesCts.Token;
_ = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(2), token).ConfigureAwait(false);
await AddPlayerCacheToCreate().ConfigureAwait(false);
}, token);
}
private void ProcessCacheCreation()
{
if (_isZoning) return;

View File

@@ -114,13 +114,16 @@ public sealed class Plugin : IDalamudPlugin
s.GetRequiredService<DalamudUtilService>(), s.GetRequiredService<MareMediator>()));
collection.AddSingleton((s) => new IpcCallerPetNames(s.GetRequiredService<ILogger<IpcCallerPetNames>>(), pluginInterface,
s.GetRequiredService<DalamudUtilService>(), s.GetRequiredService<MareMediator>()));
collection.AddSingleton((s) => new IpcCallerMoodles(s.GetRequiredService<ILogger<IpcCallerMoodles>>(), pluginInterface,
s.GetRequiredService<DalamudUtilService>(), s.GetRequiredService<MareMediator>()));
collection.AddSingleton((s) => new IpcManager(s.GetRequiredService<ILogger<IpcManager>>(),
s.GetRequiredService<MareMediator>(), s.GetRequiredService<IpcCallerPenumbra>(), s.GetRequiredService<IpcCallerGlamourer>(),
s.GetRequiredService<IpcCallerCustomize>(), s.GetRequiredService<IpcCallerHeels>(), s.GetRequiredService<IpcCallerHonorific>(),
s.GetRequiredService<IpcCallerPetNames>()));
s.GetRequiredService<IpcCallerPetNames>(), s.GetRequiredService<IpcCallerMoodles>()));
collection.AddSingleton((s) => new NotificationService(s.GetRequiredService<ILogger<NotificationService>>(),
s.GetRequiredService<MareMediator>(), s.GetRequiredService<DalamudUtilService>(),
notificationManager, chatGui, s.GetRequiredService<MareConfigService>()));
collection.AddSingleton((s) => new MareConfigService(pluginInterface.ConfigDirectory.FullName));
collection.AddSingleton((s) => new ServerConfigService(pluginInterface.ConfigDirectory.FullName));
collection.AddSingleton((s) => new NotesConfigService(pluginInterface.ConfigDirectory.FullName));

View File

@@ -42,6 +42,7 @@ public record CustomizePlusMessage(nint? Address) : MessageBase;
public record HonorificMessage(string NewHonorificTitle) : MessageBase;
public record PetNamesReadyMessage : MessageBase;
public record PetNamesMessage(string PetNicknamesData) : MessageBase;
public record MoodlesMessage(IntPtr Address) : MessageBase;
public record HonorificReadyMessage : MessageBase;
public record PlayerChangedMessage(CharacterData Data) : MessageBase;
public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : MessageBase;

View File

@@ -31,7 +31,8 @@ public class PluginWarningNotificationService
ShownCustomizePlusWarning = _mareConfigService.Current.DisableOptionalPluginWarnings,
ShownHeelsWarning = _mareConfigService.Current.DisableOptionalPluginWarnings,
ShownHonorificWarning = _mareConfigService.Current.DisableOptionalPluginWarnings,
ShowPetNicknamesWarning = _mareConfigService.Current.DisableOptionalPluginWarnings
ShowPetNicknamesWarning = _mareConfigService.Current.DisableOptionalPluginWarnings,
ShownMoodlesWarning = _mareConfigService.Current.DisableOptionalPluginWarnings
};
}
@@ -59,6 +60,12 @@ public class PluginWarningNotificationService
warning.ShowPetNicknamesWarning = true;
}
if (changes.Contains(PlayerChanges.Moodles) && !warning.ShownMoodlesWarning && !_ipcManager.Moodles.APIAvailable)
{
missingPluginsForData.Add("Moodles");
warning.ShownMoodlesWarning = true;
}
if (missingPluginsForData.Any())
{
_mediator.Publish(new NotificationMessage("Missing plugins for " + playerName,

View File

@@ -110,6 +110,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
_heelsExists = _ipcManager.Heels.APIAvailable;
_honorificExists = _ipcManager.Honorific.APIAvailable;
_petNamesExists = _ipcManager.PetNames.APIAvailable;
_moodlesExists = _ipcManager.Moodles.APIAvailable;
});
UidFont = _pluginInterface.UiBuilder.FontAtlas.NewDelegateFontHandle(e =>
@@ -792,6 +793,13 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
AttachToolTip($"PetNicknames is " + (_petNamesExists ? "available and up to date." : "unavailable or not up to date."));
ImGui.Spacing();
ImGui.TextUnformatted("Moodles");
ImGui.SameLine();
IconText(_moodlesExists ? check : cross, GetBoolColor(_moodlesExists));
ImGui.SameLine();
AttachToolTip($"Moodles is " + (_moodlesExists ? "available and up to date." : "unavailable or not up to date."));
ImGui.Spacing();
if (!_penumbraExists || !_glamourerExists)
{
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Loporrit.");

View File

@@ -195,6 +195,13 @@ public static class VariousExtensions
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff petnames data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.PetNames);
charaDataToUpdate[objectKind].Add(PlayerChanges.PetNames);
}
bool moodlesDataDifferent = !string.Equals(oldData.MoodlesData, newData.MoodlesData, StringComparison.Ordinal);
if (moodlesDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.MoodlesData)))
{
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff moodles data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Moodles);
charaDataToUpdate[objectKind].Add(PlayerChanges.Moodles);
}
}
foreach (KeyValuePair<ObjectKind, HashSet<PlayerChanges>> data in charaDataToUpdate.ToList())