From f0bdecd472c34f44fc549b70e63944d406497343 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Thu, 23 Jun 2022 15:55:40 +0200 Subject: [PATCH] Let manipulations use a single string and re-add redrawing by object. --- Penumbra/Api/IPenumbraApi.cs | 9 ++++--- Penumbra/Api/IpcTester.cs | 18 ++++++++++---- Penumbra/Api/PenumbraApi.cs | 47 ++++++++++++++++++++++-------------- Penumbra/Api/PenumbraIpc.cs | 29 ++++++++++++++++------ 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/Penumbra/Api/IPenumbraApi.cs b/Penumbra/Api/IPenumbraApi.cs index cc9c7e56..1d81b973 100644 --- a/Penumbra/Api/IPenumbraApi.cs +++ b/Penumbra/Api/IPenumbraApi.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Dalamud.Game.ClientState.Objects.Types; using Lumina.Data; using Penumbra.GameData.Enums; using Penumbra.Mods; @@ -53,6 +54,9 @@ public interface IPenumbraApi : IPenumbraApiBase // Queue redrawing of all actors of the given name with the given RedrawType. public void RedrawObject( string name, RedrawType setting ); + // Queue redrawing of the specific actor with the given RedrawType. Should only be used when the actor is sure to be valid. + public void RedrawObject( GameObject gameObject, RedrawType setting ); + // Queue redrawing of the actor with the given object table index, if it exists, with the given RedrawType. public void RedrawObject( int tableIndex, RedrawType setting ); @@ -148,12 +152,11 @@ public interface IPenumbraApi : IPenumbraApiBase // Set a temporary mod with the given paths, manipulations and priority and the name tag to all collections. // Can return Okay, InvalidGamePath, or InvalidManipulation. - public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, HashSet< string > manipCodes, - int priority ); + public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority ); // Set a temporary mod with the given paths, manipulations and priority and the name tag to the collection with the given name, which can be temporary. // Can return Okay, MissingCollection InvalidGamePath, or InvalidManipulation. - public PenumbraApiEc AddTemporaryMod( string tag, string collectionName, Dictionary< string, string > paths, HashSet< string > manipCodes, + public PenumbraApiEc AddTemporaryMod( string tag, string collectionName, Dictionary< string, string > paths, string manipString, int priority ); // Remove the temporary mod with the given tag and priority from the temporary mods applying to all collections, if it exists. diff --git a/Penumbra/Api/IpcTester.cs b/Penumbra/Api/IpcTester.cs index 9a9794b5..da087527 100644 --- a/Penumbra/Api/IpcTester.cs +++ b/Penumbra/Api/IpcTester.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Linq; using System.Numerics; using System.Reflection; +using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Interface; using Dalamud.Logging; using Dalamud.Plugin; @@ -281,6 +282,13 @@ public class IpcTester : IDisposable .InvokeAction( _redrawName, ( int )RedrawType.Redraw ); } + DrawIntro( PenumbraIpc.LabelProviderRedrawObject, "Redraw Player Character" ); + if( ImGui.Button( "Redraw##pc" ) && Dalamud.ClientState.LocalPlayer != null ) + { + _pi.GetIpcSubscriber< GameObject, int, object? >( PenumbraIpc.LabelProviderRedrawObject ) + .InvokeAction( Dalamud.ClientState.LocalPlayer, ( int )RedrawType.Redraw ); + } + DrawIntro( PenumbraIpc.LabelProviderRedrawIndex, "Redraw by Index" ); var tmp = _redrawIndex; ImGui.SetNextItemWidth( 100 * ImGuiHelpers.GlobalScale ); @@ -448,7 +456,7 @@ public class IpcTester : IDisposable ImGui.OpenPopup( "Ipc Data" ); } - DrawIntro(PenumbraIpc.LabelProviderGetMetaManipulations, "Meta Manipulations" ); + DrawIntro( PenumbraIpc.LabelProviderGetMetaManipulations, "Meta Manipulations" ); if( ImGui.Button( "Copy to Clipboard" ) ) { var base64 = _pi.GetIpcSubscriber< string, string >( PenumbraIpc.LabelProviderGetMetaManipulations ) @@ -697,21 +705,21 @@ public class IpcTester : IDisposable if( ImGui.Button( "Add##Mod" ) ) { _lastTempError = _pi - .GetIpcSubscriber< string, string, IReadOnlyDictionary< string, string >, IReadOnlySet< string >, int, PenumbraApiEc >( + .GetIpcSubscriber< string, string, Dictionary< string, string >, string, int, PenumbraApiEc >( PenumbraIpc.LabelProviderAddTemporaryMod ) .InvokeFunc( _tempModName, _tempCollectionName, new Dictionary< string, string > { { _tempGamePath, _tempFilePath } }, - _tempManipulation.Length > 0 ? new HashSet< string > { _tempManipulation } : new HashSet< string >(), int.MaxValue ); + _tempManipulation.Length > 0 ? _tempManipulation : string.Empty, int.MaxValue ); } DrawIntro( PenumbraIpc.LabelProviderAddTemporaryModAll, "Add Temporary Mod to all Collections" ); if( ImGui.Button( "Add##All" ) ) { _lastTempError = _pi - .GetIpcSubscriber< string, IReadOnlyDictionary< string, string >, IReadOnlySet< string >, int, PenumbraApiEc >( + .GetIpcSubscriber< string, Dictionary< string, string >, string, int, PenumbraApiEc >( PenumbraIpc.LabelProviderAddTemporaryModAll ) .InvokeFunc( _tempModName, new Dictionary< string, string > { { _tempGamePath, _tempFilePath } }, - _tempManipulation.Length > 0 ? new HashSet< string > { _tempManipulation } : new HashSet< string >(), int.MaxValue ); + _tempManipulation.Length > 0 ? _tempManipulation : string.Empty, int.MaxValue ); } DrawIntro( PenumbraIpc.LabelProviderRemoveTemporaryMod, "Remove Temporary Mod from specific Collection" ); diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index e56f0b7a..f4403e50 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; +using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Logging; using Lumina.Data; using Newtonsoft.Json; @@ -73,6 +74,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi _penumbra!.ObjectReloader.RedrawObject( name, setting ); } + public void RedrawObject( GameObject? gameObject, RedrawType setting ) + { + CheckInitialized(); + _penumbra!.ObjectReloader.RedrawObject( gameObject, setting ); + } + public void RedrawAll( RedrawType setting ) { CheckInitialized(); @@ -368,7 +375,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi return PenumbraApiEc.Success; } - public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, HashSet< string > manipCodes, int priority ) + public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority ) { CheckInitialized(); if( !ConvertPaths( paths, out var p ) ) @@ -376,7 +383,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi return PenumbraApiEc.InvalidGamePath; } - if( !ConvertManips( manipCodes, out var m ) ) + if( !ConvertManips( manipString, out var m ) ) { return PenumbraApiEc.InvalidManipulation; } @@ -388,7 +395,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi }; } - public PenumbraApiEc AddTemporaryMod( string tag, string collectionName, Dictionary< string, string > paths, HashSet< string > manipCodes, + public PenumbraApiEc AddTemporaryMod( string tag, string collectionName, Dictionary< string, string > paths, string manipString, int priority ) { CheckInitialized(); @@ -403,7 +410,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi return PenumbraApiEc.InvalidGamePath; } - if( !ConvertManips( manipCodes, out var m ) ) + if( !ConvertManips( manipString, out var m ) ) { return PenumbraApiEc.InvalidManipulation; } @@ -535,28 +542,32 @@ public class PenumbraApi : IDisposable, IPenumbraApi return true; } - // Convert manipulations from transmitted base64 strings to actual manipulations. + // Convert manipulations from a transmitted base64 string to actual manipulations. + // The empty string is treated as an empty set. // Only returns true if all conversions are successful and distinct. - private static bool ConvertManips( IReadOnlyCollection< string > manipStrings, + private static bool ConvertManips( string manipString, [NotNullWhen( true )] out HashSet< MetaManipulation >? manips ) { - manips = new HashSet< MetaManipulation >( manipStrings.Count ); - foreach( var m in manipStrings ) + if( manipString.Length == 0 ) { - if( Functions.FromCompressedBase64< MetaManipulation[] >( m, out var manipArray ) != MetaManipulation.CurrentVersion ) + manips = new HashSet< MetaManipulation >(); + return true; + } + + if( Functions.FromCompressedBase64< MetaManipulation[] >( manipString, out var manipArray ) != MetaManipulation.CurrentVersion ) + { + manips = null; + return false; + } + + manips = new HashSet< MetaManipulation >( manipArray!.Length ); + foreach( var manip in manipArray ) + { + if( !manips.Add( manip ) ) { manips = null; return false; } - - foreach( var manip in manipArray! ) - { - if( !manips.Add( manip ) ) - { - manips = null; - return false; - } - } } return true; diff --git a/Penumbra/Api/PenumbraIpc.cs b/Penumbra/Api/PenumbraIpc.cs index a60d63f4..ceaacfc4 100644 --- a/Penumbra/Api/PenumbraIpc.cs +++ b/Penumbra/Api/PenumbraIpc.cs @@ -116,15 +116,17 @@ public partial class PenumbraIpc public partial class PenumbraIpc { + public const string LabelProviderRedrawObject = "Penumbra.RedrawObject"; public const string LabelProviderRedrawName = "Penumbra.RedrawObjectByName"; public const string LabelProviderRedrawIndex = "Penumbra.RedrawObjectByIndex"; public const string LabelProviderRedrawAll = "Penumbra.RedrawAll"; public const string LabelProviderGameObjectRedrawn = "Penumbra.GameObjectRedrawn"; - internal ICallGateProvider< string, int, object? >? ProviderRedrawName; - internal ICallGateProvider< int, int, object? >? ProviderRedrawIndex; - internal ICallGateProvider< int, object? >? ProviderRedrawAll; - internal ICallGateProvider< IntPtr, int, object? >? ProviderGameObjectRedrawn; + internal ICallGateProvider< string, int, object? >? ProviderRedrawName; + internal ICallGateProvider< GameObject, int, object? >? ProviderRedrawObject; + internal ICallGateProvider< int, int, object? >? ProviderRedrawIndex; + internal ICallGateProvider< int, object? >? ProviderRedrawAll; + internal ICallGateProvider< IntPtr, int, object? >? ProviderGameObjectRedrawn; private static RedrawType CheckRedrawType( int value ) { @@ -149,6 +151,16 @@ public partial class PenumbraIpc PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" ); } + try + { + ProviderRedrawObject = pi.GetIpcProvider< GameObject, int, object? >( LabelProviderRedrawObject ); + ProviderRedrawObject.RegisterAction( ( s, i ) => Api.RedrawObject( s, CheckRedrawType( i ) ) ); + } + catch( Exception e ) + { + PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawObject}:\n{e}" ); + } + try { ProviderRedrawIndex = pi.GetIpcProvider< int, int, object? >( LabelProviderRedrawIndex ); @@ -186,6 +198,7 @@ public partial class PenumbraIpc private void DisposeRedrawProviders() { ProviderRedrawName?.UnregisterAction(); + ProviderRedrawObject?.UnregisterAction(); ProviderRedrawIndex?.UnregisterAction(); ProviderRedrawAll?.UnregisterAction(); Api.GameObjectRedrawn -= OnGameObjectRedrawn; @@ -533,10 +546,10 @@ public partial class PenumbraIpc internal ICallGateProvider< string, string, bool, (PenumbraApiEc, string) >? ProviderCreateTemporaryCollection; internal ICallGateProvider< string, PenumbraApiEc >? ProviderRemoveTemporaryCollection; - internal ICallGateProvider< string, Dictionary< string, string >, HashSet< string >, int, PenumbraApiEc >? + internal ICallGateProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc >? ProviderAddTemporaryModAll; - internal ICallGateProvider< string, string, Dictionary< string, string >, HashSet< string >, int, PenumbraApiEc >? + internal ICallGateProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc >? ProviderAddTemporaryMod; internal ICallGateProvider< string, int, PenumbraApiEc >? ProviderRemoveTemporaryModAll; @@ -569,7 +582,7 @@ public partial class PenumbraIpc try { ProviderAddTemporaryModAll = - pi.GetIpcProvider< string, Dictionary< string, string >, HashSet< string >, int, PenumbraApiEc >( + pi.GetIpcProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc >( LabelProviderAddTemporaryModAll ); ProviderAddTemporaryModAll.RegisterFunc( Api.AddTemporaryModAll ); } @@ -581,7 +594,7 @@ public partial class PenumbraIpc try { ProviderAddTemporaryMod = - pi.GetIpcProvider< string, string, Dictionary< string, string >, HashSet< string >, int, PenumbraApiEc >( + pi.GetIpcProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc >( LabelProviderAddTemporaryMod ); ProviderAddTemporaryMod.RegisterFunc( Api.AddTemporaryMod ); }