Update IPC to use better mechanisms for temporary collections without breaking backwards compatibility.

This commit is contained in:
Ottermandias 2022-11-21 16:57:17 +01:00
parent 16a56eb5d0
commit 74ed6edd6f
6 changed files with 106 additions and 19 deletions

@ -1 +1 @@
Subproject commit 27e8873e9f4633421e736757574b502a8d65e79d
Subproject commit 15f782dd7d3b823db5203769578b9edd7b92e309

View file

@ -1087,6 +1087,7 @@ public class IpcTester : IDisposable
private string _tempFilePath = "test/success.mtrl";
private string _tempManipulation = string.Empty;
private PenumbraApiEc _lastTempError;
private int _tempActorIndex = 0;
private bool _forceOverwrite;
public void Draw()
@ -1099,6 +1100,7 @@ public class IpcTester : IDisposable
ImGui.InputTextWithHint( "##tempCollection", "Collection Name...", ref _tempCollectionName, 128 );
ImGui.InputTextWithHint( "##tempCollectionChar", "Collection Character...", ref _tempCharacterName, 32 );
ImGui.InputInt( "##tempActorIndex", ref _tempActorIndex, 0, 0 );
ImGui.InputTextWithHint( "##tempMod", "Temporary Mod Name...", ref _tempModName, 32 );
ImGui.InputTextWithHint( "##tempGame", "Game Path...", ref _tempGamePath, 256 );
ImGui.InputTextWithHint( "##tempFile", "File Path...", ref _tempFilePath, 256 );
@ -1115,16 +1117,35 @@ public class IpcTester : IDisposable
DrawIntro( "Last Error", _lastTempError.ToString() );
DrawIntro( "Last Created Collection", LastCreatedCollectionName );
DrawIntro( Ipc.CreateTemporaryCollection.Label, "Create Temporary Collection" );
#pragma warning disable 0612
if( ImGui.Button( "Create##Collection" ) )
{
( _lastTempError, LastCreatedCollectionName ) = Ipc.CreateTemporaryCollection.Subscriber( _pi ).Invoke( _tempCollectionName, _tempCharacterName, _forceOverwrite );
}
DrawIntro( Ipc.CreateNamedTemporaryCollection.Label, "Create Named Temporary Collection" );
if( ImGui.Button( "Create##NamedCollection" ) )
{
_lastTempError = Ipc.CreateNamedTemporaryCollection.Subscriber( _pi ).Invoke( _tempCollectionName );
}
DrawIntro( Ipc.RemoveTemporaryCollection.Label, "Remove Temporary Collection from Character" );
if( ImGui.Button( "Delete##Collection" ) )
{
_lastTempError = Ipc.RemoveTemporaryCollection.Subscriber( _pi ).Invoke( _tempCharacterName );
}
#pragma warning restore 0612
DrawIntro( Ipc.RemoveTemporaryCollectionByName.Label, "Remove Temporary Collection" );
if( ImGui.Button( "Delete##NamedCollection" ) )
{
_lastTempError = Ipc.RemoveTemporaryCollectionByName.Subscriber( _pi ).Invoke( _tempCollectionName );
}
DrawIntro( Ipc.AssignTemporaryCollection.Label, "Assign Temporary Collection" );
if( ImGui.Button( "Assign##NamedCollection" ) )
{
_lastTempError = Ipc.AssignTemporaryCollection.Subscriber( _pi ).Invoke( _tempCollectionName, _tempActorIndex, _forceOverwrite );
}
DrawIntro( Ipc.AddTemporaryMod.Label, "Add Temporary Mod to specific Collection" );
if( ImGui.Button( "Add##Mod" ) )

View file

@ -23,7 +23,7 @@ namespace Penumbra.Api;
public class PenumbraApi : IDisposable, IPenumbraApi
{
public (int, int) ApiVersion
=> ( 4, 15 );
=> ( 4, 16 );
private Penumbra? _penumbra;
private Lumina.GameData? _lumina;
@ -575,10 +575,8 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return collection.SetModSetting( mod.Index, groupIdx, setting ) ? PenumbraApiEc.Success : PenumbraApiEc.NothingChanged;
}
public (PenumbraApiEc, string) CreateTemporaryCollection( string tag, string character, bool forceOverwriteCharacter )
=> CreateTemporaryCollection( tag, character, forceOverwriteCharacter, ushort.MaxValue );
public (PenumbraApiEc, string) CreateTemporaryCollection( string tag, string character, bool forceOverwriteCharacter, ushort worldId )
public (PenumbraApiEc, string) CreateTemporaryCollection( string tag, string character, bool forceOverwriteCharacter )
{
CheckInitialized();
@ -587,7 +585,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return ( PenumbraApiEc.InvalidArgument, string.Empty );
}
var identifier = NameToIdentifier( character, worldId );
var identifier = NameToIdentifier( character, ushort.MaxValue );
if( !identifier.IsValid )
{
return ( PenumbraApiEc.InvalidArgument, string.Empty );
@ -599,10 +597,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return ( PenumbraApiEc.CharacterCollectionExists, string.Empty );
}
var name = Penumbra.TempMods.CreateTemporaryCollection( tag, character );
if( name.Length == 0 )
var name = $"{tag}_{character}";
var ret = CreateNamedTemporaryCollection( name );
if( ret != PenumbraApiEc.Success )
{
return ( PenumbraApiEc.CharacterCollectionExists, string.Empty );
return ( ret, name );
}
if( Penumbra.TempMods.AddIdentifier( name, identifier ) )
@ -614,6 +613,51 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return ( PenumbraApiEc.UnknownError, string.Empty );
}
public PenumbraApiEc CreateNamedTemporaryCollection( string name )
{
CheckInitialized();
if( name.Length == 0 || Mod.ReplaceBadXivSymbols( name ) != name )
{
return PenumbraApiEc.InvalidArgument;
}
return Penumbra.TempMods.CreateTemporaryCollection( name ).Length > 0
? PenumbraApiEc.Success
: PenumbraApiEc.CollectionExists;
}
public PenumbraApiEc AssignTemporaryCollection( string collectionName, int actorIndex, bool forceAssignment )
{
CheckInitialized();
if( actorIndex < 0 || actorIndex >= Dalamud.Objects.Length )
{
return PenumbraApiEc.InvalidArgument;
}
var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ] );
if( !identifier.IsValid )
{
return PenumbraApiEc.InvalidArgument;
}
if( !Penumbra.TempMods.CollectionByName( collectionName, out var collection ) )
{
return PenumbraApiEc.CollectionMissing;
}
if( !forceAssignment
&& ( Penumbra.TempMods.Collections.Individuals.ContainsKey( identifier ) || Penumbra.CollectionManager.Individuals.Individuals.ContainsKey( identifier ) ) )
{
return PenumbraApiEc.CharacterCollectionExists;
}
var group = Penumbra.TempMods.Collections.GetGroup( identifier );
return Penumbra.TempMods.AddIdentifier( collection, group )
? PenumbraApiEc.Success
: PenumbraApiEc.UnknownError;
}
public PenumbraApiEc RemoveTemporaryCollection( string character )
{
CheckInitialized();
@ -622,6 +666,14 @@ public class PenumbraApi : IDisposable, IPenumbraApi
: PenumbraApiEc.NothingChanged;
}
public PenumbraApiEc RemoveTemporaryCollectionByName( string name )
{
CheckInitialized();
return Penumbra.TempMods.RemoveTemporaryCollection( name )
? PenumbraApiEc.Success
: PenumbraApiEc.NothingChanged;
}
public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority )
{
CheckInitialized();

View file

@ -89,6 +89,9 @@ public class PenumbraIpcProviders : IDisposable
// Temporary
internal readonly FuncProvider< string, string, bool, (PenumbraApiEc, string) > CreateTemporaryCollection;
internal readonly FuncProvider< string, PenumbraApiEc > RemoveTemporaryCollection;
internal readonly FuncProvider< string, PenumbraApiEc > CreateNamedTemporaryCollection;
internal readonly FuncProvider< string, PenumbraApiEc > RemoveTemporaryCollectionByName;
internal readonly FuncProvider< string, int, bool, PenumbraApiEc > AssignTemporaryCollection;
internal readonly FuncProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryModAll;
internal readonly FuncProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryMod;
internal readonly FuncProvider< string, int, PenumbraApiEc > RemoveTemporaryModAll;
@ -178,12 +181,15 @@ public class PenumbraIpcProviders : IDisposable
() => Api.ModSettingChanged -= ModSettingChangedEvent );
// Temporary
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider( pi, Api.CreateTemporaryCollection );
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider( pi, Api.RemoveTemporaryCollection );
AddTemporaryModAll = Ipc.AddTemporaryModAll.Provider( pi, Api.AddTemporaryModAll );
AddTemporaryMod = Ipc.AddTemporaryMod.Provider( pi, Api.AddTemporaryMod );
RemoveTemporaryModAll = Ipc.RemoveTemporaryModAll.Provider( pi, Api.RemoveTemporaryModAll );
RemoveTemporaryMod = Ipc.RemoveTemporaryMod.Provider( pi, Api.RemoveTemporaryMod );
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider( pi, Api.CreateTemporaryCollection );
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider( pi, Api.RemoveTemporaryCollection );
CreateNamedTemporaryCollection = Ipc.CreateNamedTemporaryCollection.Provider( pi, Api.CreateNamedTemporaryCollection );
RemoveTemporaryCollectionByName = Ipc.RemoveTemporaryCollectionByName.Provider( pi, Api.RemoveTemporaryCollectionByName );
AssignTemporaryCollection = Ipc.AssignTemporaryCollection.Provider( pi, Api.AssignTemporaryCollection );
AddTemporaryModAll = Ipc.AddTemporaryModAll.Provider( pi, Api.AddTemporaryModAll );
AddTemporaryMod = Ipc.AddTemporaryMod.Provider( pi, Api.AddTemporaryMod );
RemoveTemporaryModAll = Ipc.RemoveTemporaryModAll.Provider( pi, Api.RemoveTemporaryModAll );
RemoveTemporaryMod = Ipc.RemoveTemporaryMod.Provider( pi, Api.RemoveTemporaryMod );
Tester = new IpcTester( pi, this );
@ -267,6 +273,9 @@ public class PenumbraIpcProviders : IDisposable
// Temporary
CreateTemporaryCollection.Dispose();
RemoveTemporaryCollection.Dispose();
CreateNamedTemporaryCollection.Dispose();
RemoveTemporaryCollectionByName.Dispose();
AssignTemporaryCollection.Dispose();
AddTemporaryModAll.Dispose();
AddTemporaryMod.Dispose();
RemoveTemporaryModAll.Dispose();

View file

@ -151,9 +151,14 @@ public class TempModManager
return RedirectResult.Success;
}
public string CreateTemporaryCollection( string tag, string customName )
public string CreateTemporaryCollection( string name )
{
var collection = ModCollection.CreateNewTemporary( tag, customName );
if( Penumbra.CollectionManager.ByName( name, out _ ) )
{
return string.Empty;
}
var collection = ModCollection.CreateNewTemporary( name );
if( _customCollections.TryAdd( collection.Name.ToLowerInvariant(), collection ) )
{
return collection.Name;

View file

@ -84,9 +84,9 @@ public partial class ModCollection
=> new(name, CurrentVersion, new Dictionary< string, ModSettings.SavedSettings >());
// Create a new temporary collection that does not save and has a negative index.
public static ModCollection CreateNewTemporary( string tag, string characterName )
public static ModCollection CreateNewTemporary( string name )
{
var collection = new ModCollection( $"{tag}_{characterName}", Empty );
var collection = new ModCollection( name, Empty );
collection.ModSettingChanged -= collection.SaveOnChange;
collection.InheritanceChanged -= collection.SaveOnChange;
collection.Index = ~Penumbra.TempMods.Collections.Count;