mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Change entirely backward compatible API functions to do reasonable things in new system.
This commit is contained in:
parent
2fac923452
commit
893e0a13bd
3 changed files with 135 additions and 39 deletions
|
|
@ -210,14 +210,22 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
return ResolvePath( path, Penumbra.ModManager, PathResolver.PlayerCollection() );
|
return ResolvePath( path, Penumbra.ModManager, PathResolver.PlayerCollection() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: cleanup when incrementing API level
|
||||||
public string ResolvePath( string path, string characterName )
|
public string ResolvePath( string path, string characterName )
|
||||||
|
=> ResolvePath( path, characterName, ushort.MaxValue );
|
||||||
|
|
||||||
|
public string ResolvePath( string path, string characterName, ushort worldId )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
return ResolvePath( path, Penumbra.ModManager,
|
return ResolvePath( path, Penumbra.ModManager,
|
||||||
Penumbra.CollectionManager.Individual( NameToIdentifier( characterName ) ) );
|
Penumbra.CollectionManager.Individual( NameToIdentifier( characterName, worldId ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: cleanup when incrementing API level
|
||||||
public string[] ReverseResolvePath( string path, string characterName )
|
public string[] ReverseResolvePath( string path, string characterName )
|
||||||
|
=> ReverseResolvePath( path, characterName, ushort.MaxValue );
|
||||||
|
|
||||||
|
public string[] ReverseResolvePath( string path, string characterName, ushort worldId )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
if( !Penumbra.Config.EnableMods )
|
if( !Penumbra.Config.EnableMods )
|
||||||
|
|
@ -225,7 +233,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
return new[] { path };
|
return new[] { path };
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = Penumbra.CollectionManager.Individual( NameToIdentifier( characterName ) ).ReverseResolvePath( new FullPath( path ) );
|
var ret = Penumbra.CollectionManager.Individual( NameToIdentifier( characterName, worldId ) ).ReverseResolvePath( new FullPath( path ) );
|
||||||
return ret.Select( r => r.ToString() ).ToArray();
|
return ret.Select( r => r.ToString() ).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,10 +304,14 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
return Penumbra.CollectionManager.Interface.Name;
|
return Penumbra.CollectionManager.Interface.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: cleanup when incrementing API level
|
||||||
public (string, bool) GetCharacterCollection( string characterName )
|
public (string, bool) GetCharacterCollection( string characterName )
|
||||||
|
=> GetCharacterCollection( characterName, ushort.MaxValue );
|
||||||
|
|
||||||
|
public (string, bool) GetCharacterCollection( string characterName, ushort worldId )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
return Penumbra.CollectionManager.Individuals.TryGetCollection( NameToIdentifier( characterName ), out var collection )
|
return Penumbra.CollectionManager.Individuals.TryGetCollection( NameToIdentifier( characterName, worldId ), out var collection )
|
||||||
? ( collection.Name, true )
|
? ( collection.Name, true )
|
||||||
: ( Penumbra.CollectionManager.Default.Name, false );
|
: ( Penumbra.CollectionManager.Default.Name, false );
|
||||||
}
|
}
|
||||||
|
|
@ -371,7 +383,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
public PenumbraApiEc AddMod( string modDirectory )
|
public PenumbraApiEc AddMod( string modDirectory )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
var dir = new DirectoryInfo( Path.Join( Penumbra.ModManager.BasePath.FullName, Path.GetFileName(modDirectory) ) );
|
var dir = new DirectoryInfo( Path.Join( Penumbra.ModManager.BasePath.FullName, Path.GetFileName( modDirectory ) ) );
|
||||||
if( !dir.Exists )
|
if( !dir.Exists )
|
||||||
{
|
{
|
||||||
return PenumbraApiEc.FileMissing;
|
return PenumbraApiEc.FileMissing;
|
||||||
|
|
@ -564,34 +576,50 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
}
|
}
|
||||||
|
|
||||||
public (PenumbraApiEc, string) CreateTemporaryCollection( string tag, string character, bool forceOverwriteCharacter )
|
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 )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
|
|
||||||
if( character.Length is 0 or > 32 || tag.Length == 0 )
|
if( !ActorManager.VerifyPlayerName( character.AsSpan() ) || tag.Length == 0 )
|
||||||
{
|
{
|
||||||
return ( PenumbraApiEc.InvalidArgument, string.Empty );
|
return ( PenumbraApiEc.InvalidArgument, string.Empty );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !forceOverwriteCharacter && Penumbra.CollectionManager.Individuals.Individuals.ContainsKey( NameToIdentifier( character ) )
|
var identifier = NameToIdentifier( character, worldId );
|
||||||
|| Penumbra.TempMods.Collections.ContainsKey( character ) )
|
if( !identifier.IsValid )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.InvalidArgument, string.Empty );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !forceOverwriteCharacter && Penumbra.CollectionManager.Individuals.Individuals.ContainsKey( identifier )
|
||||||
|
|| Penumbra.TempMods.Collections.Individuals.ContainsKey( identifier ) )
|
||||||
{
|
{
|
||||||
return ( PenumbraApiEc.CharacterCollectionExists, string.Empty );
|
return ( PenumbraApiEc.CharacterCollectionExists, string.Empty );
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = Penumbra.TempMods.SetTemporaryCollection( tag, character );
|
var name = Penumbra.TempMods.CreateTemporaryCollection( tag, character );
|
||||||
return ( PenumbraApiEc.Success, name );
|
if( name.Length == 0 )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.CharacterCollectionExists, string.Empty );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Penumbra.TempMods.AddIdentifier( name, identifier ) )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.Success, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
Penumbra.TempMods.RemoveTemporaryCollection( name );
|
||||||
|
return ( PenumbraApiEc.UnknownError, string.Empty );
|
||||||
}
|
}
|
||||||
|
|
||||||
public PenumbraApiEc RemoveTemporaryCollection( string character )
|
public PenumbraApiEc RemoveTemporaryCollection( string character )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
if( !Penumbra.TempMods.Collections.ContainsKey( character ) )
|
return Penumbra.TempMods.RemoveByCharacterName( character )
|
||||||
{
|
? PenumbraApiEc.Success
|
||||||
return PenumbraApiEc.NothingChanged;
|
: PenumbraApiEc.NothingChanged;
|
||||||
}
|
|
||||||
|
|
||||||
Penumbra.TempMods.RemoveTemporaryCollection( character );
|
|
||||||
return PenumbraApiEc.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority )
|
public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority )
|
||||||
|
|
@ -677,12 +705,17 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: cleanup when incrementing API
|
||||||
public string GetMetaManipulations( string characterName )
|
public string GetMetaManipulations( string characterName )
|
||||||
|
=> GetMetaManipulations( characterName, ushort.MaxValue );
|
||||||
|
|
||||||
|
public string GetMetaManipulations( string characterName, ushort worldId )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
var collection = Penumbra.TempMods.Collections.TryGetValue( characterName, out var c )
|
var identifier = NameToIdentifier( characterName, worldId );
|
||||||
|
var collection = Penumbra.TempMods.Collections.TryGetCollection( identifier, out var c )
|
||||||
? c
|
? c
|
||||||
: Penumbra.CollectionManager.Individual( NameToIdentifier( characterName ) );
|
: Penumbra.CollectionManager.Individual( identifier );
|
||||||
var set = collection.MetaCache?.Manipulations.ToArray() ?? Array.Empty< MetaManipulation >();
|
var set = collection.MetaCache?.Manipulations.ToArray() ?? Array.Empty< MetaManipulation >();
|
||||||
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
||||||
}
|
}
|
||||||
|
|
@ -830,10 +863,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
public void InvokePostSettingsPanel( string modDirectory )
|
public void InvokePostSettingsPanel( string modDirectory )
|
||||||
=> PostSettingsPanelDraw?.Invoke( modDirectory );
|
=> PostSettingsPanelDraw?.Invoke( modDirectory );
|
||||||
|
|
||||||
// TODO
|
// TODO: replace all usages with ActorIdentifier stuff when incrementing API
|
||||||
private static ActorIdentifier NameToIdentifier( string name )
|
private static ActorIdentifier NameToIdentifier( string name, ushort worldId )
|
||||||
{
|
{
|
||||||
|
// Verified to be valid name beforehand.
|
||||||
var b = ByteString.FromStringUnsafe( name, false );
|
var b = ByteString.FromStringUnsafe( name, false );
|
||||||
return Penumbra.Actors.CreatePlayer( b, ( ushort )( Dalamud.ClientState.LocalPlayer?.HomeWorld.Id ?? ushort.MaxValue ) );
|
return Penumbra.Actors.CreatePlayer( b, worldId );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using OtterGui;
|
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
using Penumbra.String;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Api;
|
namespace Penumbra.Api;
|
||||||
|
|
@ -21,7 +22,10 @@ public class TempModManager
|
||||||
{
|
{
|
||||||
private readonly Dictionary< ModCollection, List< Mod.TemporaryMod > > _mods = new();
|
private readonly Dictionary< ModCollection, List< Mod.TemporaryMod > > _mods = new();
|
||||||
private readonly List< Mod.TemporaryMod > _modsForAllCollections = new();
|
private readonly List< Mod.TemporaryMod > _modsForAllCollections = new();
|
||||||
private readonly Dictionary< string, ModCollection > _collections = new();
|
private readonly Dictionary< string, ModCollection > _customCollections = new();
|
||||||
|
public readonly IndividualCollections Collections = new(Penumbra.Actors);
|
||||||
|
|
||||||
|
public event ModCollection.Manager.CollectionChangeDelegate? CollectionChanged;
|
||||||
|
|
||||||
public IReadOnlyDictionary< ModCollection, List< Mod.TemporaryMod > > Mods
|
public IReadOnlyDictionary< ModCollection, List< Mod.TemporaryMod > > Mods
|
||||||
=> _mods;
|
=> _mods;
|
||||||
|
|
@ -29,13 +33,11 @@ public class TempModManager
|
||||||
public IReadOnlyList< Mod.TemporaryMod > ModsForAllCollections
|
public IReadOnlyList< Mod.TemporaryMod > ModsForAllCollections
|
||||||
=> _modsForAllCollections;
|
=> _modsForAllCollections;
|
||||||
|
|
||||||
public IReadOnlyDictionary< string, ModCollection > Collections
|
public IReadOnlyDictionary< string, ModCollection > CustomCollections
|
||||||
=> _collections;
|
=> _customCollections;
|
||||||
|
|
||||||
public bool CollectionByName( string name, [NotNullWhen( true )] out ModCollection? collection )
|
public bool CollectionByName( string name, [NotNullWhen( true )] out ModCollection? collection )
|
||||||
=> Collections.Values.FindFirst( c => string.Equals( c.Name, name, StringComparison.OrdinalIgnoreCase ), out collection );
|
=> _customCollections.TryGetValue( name, out collection );
|
||||||
|
|
||||||
public event ModCollection.Manager.CollectionChangeDelegate? CollectionChanged;
|
|
||||||
|
|
||||||
// These functions to check specific redirections or meta manipulations for existence are currently unused.
|
// These functions to check specific redirections or meta manipulations for existence are currently unused.
|
||||||
//public bool IsRegistered( string tag, ModCollection? collection, Utf8GamePath gamePath, out FullPath? fullPath, out int priority )
|
//public bool IsRegistered( string tag, ModCollection? collection, Utf8GamePath gamePath, out FullPath? fullPath, out int priority )
|
||||||
|
|
@ -149,27 +151,87 @@ public class TempModManager
|
||||||
return RedirectResult.Success;
|
return RedirectResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SetTemporaryCollection( string tag, string characterName )
|
public string CreateTemporaryCollection( string tag, string customName )
|
||||||
{
|
{
|
||||||
var collection = ModCollection.CreateNewTemporary( tag, characterName );
|
var collection = ModCollection.CreateNewTemporary( tag, customName );
|
||||||
_collections[ characterName ] = collection;
|
if( _customCollections.ContainsKey( collection.Name ) )
|
||||||
CollectionChanged?.Invoke(CollectionType.Temporary, null, collection );
|
{
|
||||||
|
collection.ClearCache();
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
_customCollections.Add( collection.Name, collection );
|
||||||
return collection.Name;
|
return collection.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveTemporaryCollection( string characterName )
|
public bool RemoveTemporaryCollection( string collectionName )
|
||||||
{
|
{
|
||||||
if( _collections.Remove( characterName, out var c ) )
|
if( !_customCollections.Remove( collectionName, out var collection ) )
|
||||||
{
|
{
|
||||||
_mods.Remove( c );
|
return false;
|
||||||
c.ClearCache();
|
}
|
||||||
CollectionChanged?.Invoke( CollectionType.Temporary, c, null );
|
|
||||||
|
_mods.Remove( collection );
|
||||||
|
collection.ClearCache();
|
||||||
|
for( var i = 0; i < Collections.Count; ++i )
|
||||||
|
{
|
||||||
|
if( Collections[ i ].Collection == collection )
|
||||||
|
{
|
||||||
|
CollectionChanged?.Invoke( CollectionType.Temporary, collection, null, Collections[ i ].DisplayName );
|
||||||
|
Collections.Delete( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddIdentifier( ModCollection collection, params ActorIdentifier[] identifiers )
|
||||||
|
{
|
||||||
|
if( Collections.Add( identifiers, collection ) )
|
||||||
|
{
|
||||||
|
CollectionChanged?.Invoke( CollectionType.Temporary, null, collection, Collections.Last().DisplayName );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AddIdentifier( string collectionName, params ActorIdentifier[] identifiers )
|
||||||
|
{
|
||||||
|
if( !_customCollections.TryGetValue( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AddIdentifier( collection, identifiers );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddIdentifier( string collectionName, string characterName, ushort worldId = ushort.MaxValue )
|
||||||
|
{
|
||||||
|
if( !ByteString.FromString( characterName, out var byteString, false ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var identifier = Penumbra.Actors.CreatePlayer( byteString, worldId );
|
||||||
|
if( !identifier.IsValid )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AddIdentifier( collectionName, identifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool RemoveByCharacterName( string characterName, ushort worldId = ushort.MaxValue )
|
||||||
|
{
|
||||||
|
if( !ByteString.FromString( characterName, out var byteString, false ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var identifier = Penumbra.Actors.CreatePlayer( byteString, worldId );
|
||||||
|
return Collections.Individuals.TryGetValue( identifier, out var collection ) && RemoveTemporaryCollection( collection.Name );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Apply any new changes to the temporary mod.
|
// Apply any new changes to the temporary mod.
|
||||||
private static void ApplyModChange( Mod.TemporaryMod mod, ModCollection? collection, bool created, bool removed )
|
private static void ApplyModChange( Mod.TemporaryMod mod, ModCollection? collection, bool created, bool removed )
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ public unsafe partial class PathResolver
|
||||||
|
|
||||||
// Check both temporary and permanent character collections. Temporary first.
|
// Check both temporary and permanent character collections. Temporary first.
|
||||||
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier )
|
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier )
|
||||||
=> Penumbra.TempMods.Collections.TryGetValue( identifier.ToString(), out var collection )
|
=> Penumbra.TempMods.Collections.TryGetCollection( identifier, out var collection )
|
||||||
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection )
|
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection )
|
||||||
? collection
|
? collection
|
||||||
: null;
|
: null;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue