Add API/IPC for collection handling.

This commit is contained in:
Ottermandias 2023-01-16 17:42:26 +01:00
parent 123ed256b1
commit 80f02e5377
6 changed files with 284 additions and 87 deletions

@ -1 +1 @@
Subproject commit 4409ad25e76c427692526f0e139d6811b0d138d4
Subproject commit 866f4c45bd21219a31d044c5eb55b162ee2bc0e2

View file

@ -9,8 +9,10 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Numerics;
using Dalamud.Utility;
using Penumbra.Api.Enums;
using Penumbra.Api.Helpers;
using Penumbra.Collections;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Meta.Manipulations;
@ -683,10 +685,18 @@ public class IpcTester : IDisposable
{
private readonly DalamudPluginInterface _pi;
private int _objectIdx = 0;
private string _collectionName = string.Empty;
private bool _allowCreation = true;
private bool _allowDeletion = true;
private ApiCollectionType _type = ApiCollectionType.Current;
private string _characterCollectionName = string.Empty;
private IList< string > _collections = new List< string >();
private string _changedItemCollection = string.Empty;
private IReadOnlyDictionary< string, object? > _changedItems = new Dictionary< string, object? >();
private PenumbraApiEc _returnCode = PenumbraApiEc.Success;
private string? _oldCollection = null;
public Collections( DalamudPluginInterface pi )
=> _pi = pi;
@ -699,12 +709,25 @@ public class IpcTester : IDisposable
return;
}
ImGuiUtil.GenericEnumCombo( "Collection Type", 200, _type, out _type, t => ((CollectionType)t).ToName() );
ImGui.InputInt( "Object Index##Collections", ref _objectIdx, 0, 0 );
ImGui.InputText( "Collection Name##Collections", ref _collectionName, 64 );
ImGui.Checkbox( "Allow Assignment Creation", ref _allowCreation );
ImGui.SameLine();
ImGui.Checkbox( "Allow Assignment Deletion", ref _allowDeletion );
using var table = ImRaii.Table( string.Empty, 3, ImGuiTableFlags.SizingFixedFit );
if( !table )
{
return;
}
DrawIntro( "Last Return Code", _returnCode.ToString() );
if( _oldCollection != null )
{
ImGui.TextUnformatted( _oldCollection.Length == 0 ? "Created" : _oldCollection );
}
DrawIntro( Ipc.GetCurrentCollectionName.Label, "Current Collection" );
ImGui.TextUnformatted( Ipc.GetCurrentCollectionName.Subscriber( _pi ).Invoke() );
DrawIntro( Ipc.GetDefaultCollectionName.Label, "Default Collection" );
@ -725,6 +748,27 @@ public class IpcTester : IDisposable
ImGui.OpenPopup( "Collections" );
}
DrawIntro( Ipc.GetCollectionForType.Label, "Get Special Collection" );
var name = Ipc.GetCollectionForType.Subscriber( _pi ).Invoke( _type );
ImGui.TextUnformatted( name.Length == 0 ? "Unassigned" : name );
DrawIntro( Ipc.SetCollectionForType.Label, "Set Special Collection" );
if( ImGui.Button( "Set##TypeCollection" ) )
{
( _returnCode, _oldCollection ) = Ipc.SetCollectionForType.Subscriber( _pi ).Invoke( _type, _collectionName, _allowCreation, _allowDeletion );
}
DrawIntro( Ipc.GetCollectionForObject.Label, "Get Object Collection" );
( var valid, var individual, name ) = Ipc.GetCollectionForObject.Subscriber( _pi ).Invoke( _objectIdx );
ImGui.TextUnformatted(
$"{( valid ? "Valid" : "Invalid" )} Object, {( name.Length == 0 ? "Unassigned" : name )}{( individual ? " (Individual Assignment)" : string.Empty )}" );
DrawIntro( Ipc.SetCollectionForObject.Label, "Set Object Collection" );
if( ImGui.Button( "Set##ObjectCollection" ) )
{
( _returnCode, _oldCollection ) = Ipc.SetCollectionForObject.Subscriber( _pi ).Invoke( _objectIdx, _collectionName, _allowCreation, _allowDeletion );
}
if( _returnCode == PenumbraApiEc.NothingChanged && _oldCollection.IsNullOrEmpty() )
_oldCollection = null;
DrawIntro( Ipc.GetChangedItems.Label, "Changed Item List" );
ImGui.SetNextItemWidth( 200 * ImGuiHelpers.GlobalScale );
ImGui.InputTextWithHint( "##changedCollection", "Collection Name...", ref _changedItemCollection, 64 );
@ -1089,6 +1133,7 @@ public class IpcTester : IDisposable
{
_lastSettingsError = Ipc.CopyModSettings.Subscriber( _pi ).Invoke( _settingsCollection, _settingsModDirectory, _settingsModName );
}
ImGuiUtil.HoverTooltip( "Copy settings from Mod Directory Name to Mod Name (as directory) in collection." );
DrawIntro( Ipc.TrySetModSetting.Label, "Set Setting(s)" );

View file

@ -23,7 +23,7 @@ namespace Penumbra.Api;
public class PenumbraApi : IDisposable, IPenumbraApi
{
public (int, int) ApiVersion
=> ( 4, 17 );
=> ( 4, 18 );
private Penumbra? _penumbra;
private Lumina.GameData? _lumina;
@ -302,6 +302,132 @@ public class PenumbraApi : IDisposable, IPenumbraApi
}
}
public string GetCollectionForType( Enums.ApiCollectionType type )
{
CheckInitialized();
if( !Enum.IsDefined( type ) )
return string.Empty;
var collection = Penumbra.CollectionManager.ByType( ( CollectionType )type );
return collection?.Name ?? string.Empty;
}
public (PenumbraApiEc, string OldCollection) SetCollectionForType( Enums.ApiCollectionType type, string collectionName, bool allowCreateNew, bool allowDelete )
{
CheckInitialized();
if( !Enum.IsDefined( type ) )
return ( PenumbraApiEc.InvalidArgument, string.Empty );
var oldCollection = Penumbra.CollectionManager.ByType( ( CollectionType )type )?.Name ?? string.Empty;
if( collectionName.Length == 0 )
{
if( oldCollection.Length == 0 )
{
return ( PenumbraApiEc.NothingChanged, oldCollection );
}
if( !allowDelete || type is Enums.ApiCollectionType.Current or Enums.ApiCollectionType.Default or Enums.ApiCollectionType.Interface )
{
return ( PenumbraApiEc.AssignmentDeletionDisallowed, oldCollection );
}
Penumbra.CollectionManager.RemoveSpecialCollection( (CollectionType) type );
return ( PenumbraApiEc.Success, oldCollection );
}
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
{
return (PenumbraApiEc.CollectionMissing, oldCollection);
}
if( oldCollection.Length == 0 )
{
if( !allowCreateNew )
{
return ( PenumbraApiEc.AssignmentCreationDisallowed, oldCollection );
}
Penumbra.CollectionManager.CreateSpecialCollection( ( CollectionType )type );
}
else if( oldCollection == collection.Name )
{
return ( PenumbraApiEc.NothingChanged, oldCollection );
}
Penumbra.CollectionManager.SetCollection( collection, (CollectionType) type );
return ( PenumbraApiEc.Success, oldCollection );
}
public (bool ObjectValid, bool IndividualSet, string EffectiveCollection) GetCollectionForObject( int gameObjectIdx )
{
CheckInitialized();
var id = AssociatedIdentifier( gameObjectIdx );
if( !id.IsValid )
{
return ( false, false, Penumbra.CollectionManager.Default.Name );
}
if( Penumbra.CollectionManager.Individuals.Individuals.TryGetValue( id, out var collection ) )
{
return ( true, true, collection.Name );
}
AssociatedCollection( gameObjectIdx, out collection );
return ( true, false, collection.Name );
}
public (PenumbraApiEc, string OldCollection) SetCollectionForObject( int gameObjectIdx, string collectionName, bool allowCreateNew, bool allowDelete )
{
CheckInitialized();
var id = AssociatedIdentifier( gameObjectIdx );
if( !id.IsValid )
{
return ( PenumbraApiEc.InvalidIdentifier, Penumbra.CollectionManager.Default.Name );
}
var oldCollection = Penumbra.CollectionManager.Individuals.Individuals.TryGetValue( id, out var c ) ? c.Name : string.Empty;
if( collectionName.Length == 0 )
{
if( oldCollection.Length == 0 )
{
return (PenumbraApiEc.NothingChanged, oldCollection);
}
if( !allowDelete )
{
return (PenumbraApiEc.AssignmentDeletionDisallowed, oldCollection);
}
var idx = Penumbra.CollectionManager.Individuals.Index( id );
Penumbra.CollectionManager.RemoveIndividualCollection(idx );
return (PenumbraApiEc.Success, oldCollection);
}
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
{
return (PenumbraApiEc.CollectionMissing, oldCollection);
}
if( oldCollection.Length == 0 )
{
if( !allowCreateNew )
{
return (PenumbraApiEc.AssignmentCreationDisallowed, oldCollection);
}
var ids = Penumbra.CollectionManager.Individuals.GetGroup( id );
Penumbra.CollectionManager.CreateIndividualCollection( ids );
}
else if( oldCollection == collection.Name )
{
return (PenumbraApiEc.NothingChanged, oldCollection);
}
Penumbra.CollectionManager.SetCollection( collection, CollectionType.Individual, Penumbra.CollectionManager.Individuals.Index( id ) );
return (PenumbraApiEc.Success, oldCollection);
}
public IList< string > GetCollections()
{
CheckInitialized();
@ -867,7 +993,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
// Return the collection associated to a current game object. If it does not exist, return the default collection.
// If the index is invalid, returns false and the default collection.
private unsafe bool AssociatedCollection( int gameObjectIdx, out ModCollection collection )
private static unsafe bool AssociatedCollection( int gameObjectIdx, out ModCollection collection )
{
collection = Penumbra.CollectionManager.Default;
if( gameObjectIdx < 0 || gameObjectIdx >= Dalamud.Objects.Length )
@ -885,6 +1011,16 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return true;
}
private static unsafe ActorIdentifier AssociatedIdentifier( int gameObjectIdx )
{
if( gameObjectIdx < 0 || gameObjectIdx >= Dalamud.Objects.Length )
{
return ActorIdentifier.Invalid;
}
var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx );
return Penumbra.Actors.FromObject( ptr, out _, false, true );
}
// Resolve a path given by string for a specific collection.
private static string ResolvePath( string path, Mod.Manager _, ModCollection collection )
{

View file

@ -59,12 +59,16 @@ public class PenumbraIpcProviders : IDisposable
internal readonly FuncProvider< string, string[] > ReverseResolvePlayerPath;
// Collections
internal readonly FuncProvider< IList< string > > GetCollections;
internal readonly FuncProvider< string > GetCurrentCollectionName;
internal readonly FuncProvider< string > GetDefaultCollectionName;
internal readonly FuncProvider< string > GetInterfaceCollectionName;
internal readonly FuncProvider< string, (string, bool) > GetCharacterCollectionName;
internal readonly FuncProvider< string, IReadOnlyDictionary< string, object? > > GetChangedItems;
internal readonly FuncProvider< IList< string > > GetCollections;
internal readonly FuncProvider< string > GetCurrentCollectionName;
internal readonly FuncProvider< string > GetDefaultCollectionName;
internal readonly FuncProvider< string > GetInterfaceCollectionName;
internal readonly FuncProvider< string, (string, bool) > GetCharacterCollectionName;
internal readonly FuncProvider< ApiCollectionType, string > GetCollectionForType;
internal readonly FuncProvider< ApiCollectionType, string, bool, bool, (PenumbraApiEc, string) > SetCollectionForType;
internal readonly FuncProvider< int, (bool, bool, string) > GetCollectionForObject;
internal readonly FuncProvider< int, string, bool, bool, (PenumbraApiEc, string) > SetCollectionForObject;
internal readonly FuncProvider< string, IReadOnlyDictionary< string, object? > > GetChangedItems;
// Meta
internal readonly FuncProvider< string > GetPlayerMetaManipulations;
@ -163,6 +167,10 @@ public class PenumbraIpcProviders : IDisposable
GetDefaultCollectionName = Ipc.GetDefaultCollectionName.Provider( pi, Api.GetDefaultCollection );
GetInterfaceCollectionName = Ipc.GetInterfaceCollectionName.Provider( pi, Api.GetInterfaceCollection );
GetCharacterCollectionName = Ipc.GetCharacterCollectionName.Provider( pi, Api.GetCharacterCollection );
GetCollectionForType = Ipc.GetCollectionForType.Provider( pi, Api.GetCollectionForType );
SetCollectionForType = Ipc.SetCollectionForType.Provider( pi, Api.SetCollectionForType );
GetCollectionForObject = Ipc.GetCollectionForObject.Provider( pi, Api.GetCollectionForObject );
SetCollectionForObject = Ipc.SetCollectionForObject.Provider( pi, Api.SetCollectionForObject );
GetChangedItems = Ipc.GetChangedItems.Provider( pi, Api.GetChangedItemsForCollection );
// Meta
@ -189,7 +197,7 @@ public class PenumbraIpcProviders : IDisposable
TrySetModPriority = Ipc.TrySetModPriority.Provider( pi, Api.TrySetModPriority );
TrySetModSetting = Ipc.TrySetModSetting.Provider( pi, Api.TrySetModSetting );
TrySetModSettings = Ipc.TrySetModSettings.Provider( pi, Api.TrySetModSettings );
ModSettingChanged = Ipc.ModSettingChanged.Provider( pi,
ModSettingChanged = Ipc.ModSettingChanged.Provider( pi,
() => Api.ModSettingChanged += ModSettingChangedEvent,
() => Api.ModSettingChanged -= ModSettingChangedEvent );
CopyModSettings = Ipc.CopyModSettings.Provider( pi, Api.CopyModSettings );
@ -262,6 +270,10 @@ public class PenumbraIpcProviders : IDisposable
GetDefaultCollectionName.Dispose();
GetInterfaceCollectionName.Dispose();
GetCharacterCollectionName.Dispose();
GetCollectionForType.Dispose();
SetCollectionForType.Dispose();
GetCollectionForObject.Dispose();
SetCollectionForObject.Dispose();
GetChangedItems.Dispose();
// Meta

View file

@ -45,7 +45,7 @@ public partial class ModCollection
=> Individuals.TryGetCollection( identifier, out var c ) ? c : Default;
// Special Collections
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues< CollectionType >().Length - 4];
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues< Api.Enums.ApiCollectionType >().Length - 3];
// Return the configured collection for the given type or null.
// Does not handle Inactive, use ByName instead.

View file

@ -7,105 +7,105 @@ namespace Penumbra.Collections;
public enum CollectionType : byte
{
// Special Collections
Yourself = 0,
Yourself = Api.Enums.ApiCollectionType.Yourself,
MalePlayerCharacter,
FemalePlayerCharacter,
MaleNonPlayerCharacter,
FemaleNonPlayerCharacter,
MalePlayerCharacter = Api.Enums.ApiCollectionType.MalePlayerCharacter,
FemalePlayerCharacter = Api.Enums.ApiCollectionType.FemalePlayerCharacter,
MaleNonPlayerCharacter = Api.Enums.ApiCollectionType.MaleNonPlayerCharacter,
FemaleNonPlayerCharacter = Api.Enums.ApiCollectionType.FemaleNonPlayerCharacter,
MaleMidlander,
FemaleMidlander,
MaleHighlander,
FemaleHighlander,
MaleMidlander = Api.Enums.ApiCollectionType.MaleMidlander,
FemaleMidlander = Api.Enums.ApiCollectionType.FemaleMidlander,
MaleHighlander = Api.Enums.ApiCollectionType.MaleHighlander,
FemaleHighlander = Api.Enums.ApiCollectionType.FemaleHighlander,
MaleWildwood,
FemaleWildwood,
MaleDuskwight,
FemaleDuskwight,
MaleWildwood = Api.Enums.ApiCollectionType.MaleWildwood,
FemaleWildwood = Api.Enums.ApiCollectionType.FemaleWildwood,
MaleDuskwight = Api.Enums.ApiCollectionType.MaleDuskwight,
FemaleDuskwight = Api.Enums.ApiCollectionType.FemaleDuskwight,
MalePlainsfolk,
FemalePlainsfolk,
MaleDunesfolk,
FemaleDunesfolk,
MalePlainsfolk = Api.Enums.ApiCollectionType.MalePlainsfolk,
FemalePlainsfolk = Api.Enums.ApiCollectionType.FemalePlainsfolk,
MaleDunesfolk = Api.Enums.ApiCollectionType.MaleDunesfolk,
FemaleDunesfolk = Api.Enums.ApiCollectionType.FemaleDunesfolk,
MaleSeekerOfTheSun,
FemaleSeekerOfTheSun,
MaleKeeperOfTheMoon,
FemaleKeeperOfTheMoon,
MaleSeekerOfTheSun = Api.Enums.ApiCollectionType.MaleSeekerOfTheSun,
FemaleSeekerOfTheSun = Api.Enums.ApiCollectionType.FemaleSeekerOfTheSun,
MaleKeeperOfTheMoon = Api.Enums.ApiCollectionType.MaleKeeperOfTheMoon,
FemaleKeeperOfTheMoon = Api.Enums.ApiCollectionType.FemaleKeeperOfTheMoon,
MaleSeawolf,
FemaleSeawolf,
MaleHellsguard,
FemaleHellsguard,
MaleSeawolf = Api.Enums.ApiCollectionType.MaleSeawolf,
FemaleSeawolf = Api.Enums.ApiCollectionType.FemaleSeawolf,
MaleHellsguard = Api.Enums.ApiCollectionType.MaleHellsguard,
FemaleHellsguard = Api.Enums.ApiCollectionType.FemaleHellsguard,
MaleRaen,
FemaleRaen,
MaleXaela,
FemaleXaela,
MaleRaen = Api.Enums.ApiCollectionType.MaleRaen,
FemaleRaen = Api.Enums.ApiCollectionType.FemaleRaen,
MaleXaela = Api.Enums.ApiCollectionType.MaleXaela,
FemaleXaela = Api.Enums.ApiCollectionType.FemaleXaela,
MaleHelion,
FemaleHelion,
MaleLost,
FemaleLost,
MaleHelion = Api.Enums.ApiCollectionType.MaleHelion,
FemaleHelion = Api.Enums.ApiCollectionType.FemaleHelion,
MaleLost = Api.Enums.ApiCollectionType.MaleLost,
FemaleLost = Api.Enums.ApiCollectionType.FemaleLost,
MaleRava,
FemaleRava,
MaleVeena,
FemaleVeena,
MaleRava = Api.Enums.ApiCollectionType.MaleRava,
FemaleRava = Api.Enums.ApiCollectionType.FemaleRava,
MaleVeena = Api.Enums.ApiCollectionType.MaleVeena,
FemaleVeena = Api.Enums.ApiCollectionType.FemaleVeena,
MaleMidlanderNpc,
FemaleMidlanderNpc,
MaleHighlanderNpc,
FemaleHighlanderNpc,
MaleMidlanderNpc = Api.Enums.ApiCollectionType.MaleMidlanderNpc,
FemaleMidlanderNpc = Api.Enums.ApiCollectionType.FemaleMidlanderNpc,
MaleHighlanderNpc = Api.Enums.ApiCollectionType.MaleHighlanderNpc,
FemaleHighlanderNpc = Api.Enums.ApiCollectionType.FemaleHighlanderNpc,
MaleWildwoodNpc,
FemaleWildwoodNpc,
MaleDuskwightNpc,
FemaleDuskwightNpc,
MaleWildwoodNpc = Api.Enums.ApiCollectionType.MaleWildwoodNpc,
FemaleWildwoodNpc = Api.Enums.ApiCollectionType.FemaleWildwoodNpc,
MaleDuskwightNpc = Api.Enums.ApiCollectionType.MaleDuskwightNpc,
FemaleDuskwightNpc = Api.Enums.ApiCollectionType.FemaleDuskwightNpc,
MalePlainsfolkNpc,
FemalePlainsfolkNpc,
MaleDunesfolkNpc,
FemaleDunesfolkNpc,
MalePlainsfolkNpc = Api.Enums.ApiCollectionType.MalePlainsfolkNpc,
FemalePlainsfolkNpc = Api.Enums.ApiCollectionType.FemalePlainsfolkNpc,
MaleDunesfolkNpc = Api.Enums.ApiCollectionType.MaleDunesfolkNpc,
FemaleDunesfolkNpc = Api.Enums.ApiCollectionType.FemaleDunesfolkNpc,
MaleSeekerOfTheSunNpc,
FemaleSeekerOfTheSunNpc,
MaleKeeperOfTheMoonNpc,
FemaleKeeperOfTheMoonNpc,
MaleSeekerOfTheSunNpc = Api.Enums.ApiCollectionType.MaleSeekerOfTheSunNpc,
FemaleSeekerOfTheSunNpc = Api.Enums.ApiCollectionType.FemaleSeekerOfTheSunNpc,
MaleKeeperOfTheMoonNpc = Api.Enums.ApiCollectionType.MaleKeeperOfTheMoonNpc,
FemaleKeeperOfTheMoonNpc = Api.Enums.ApiCollectionType.FemaleKeeperOfTheMoonNpc,
MaleSeawolfNpc,
FemaleSeawolfNpc,
MaleHellsguardNpc,
FemaleHellsguardNpc,
MaleSeawolfNpc = Api.Enums.ApiCollectionType.MaleSeawolfNpc,
FemaleSeawolfNpc = Api.Enums.ApiCollectionType.FemaleSeawolfNpc,
MaleHellsguardNpc = Api.Enums.ApiCollectionType.MaleHellsguardNpc,
FemaleHellsguardNpc = Api.Enums.ApiCollectionType.FemaleHellsguardNpc,
MaleRaenNpc,
FemaleRaenNpc,
MaleXaelaNpc,
FemaleXaelaNpc,
MaleRaenNpc = Api.Enums.ApiCollectionType.MaleRaenNpc,
FemaleRaenNpc = Api.Enums.ApiCollectionType.FemaleRaenNpc,
MaleXaelaNpc = Api.Enums.ApiCollectionType.MaleXaelaNpc,
FemaleXaelaNpc = Api.Enums.ApiCollectionType.FemaleXaelaNpc,
MaleHelionNpc,
FemaleHelionNpc,
MaleLostNpc,
FemaleLostNpc,
MaleHelionNpc = Api.Enums.ApiCollectionType.MaleHelionNpc,
FemaleHelionNpc = Api.Enums.ApiCollectionType.FemaleHelionNpc,
MaleLostNpc = Api.Enums.ApiCollectionType.MaleLostNpc,
FemaleLostNpc = Api.Enums.ApiCollectionType.FemaleLostNpc,
MaleRavaNpc,
FemaleRavaNpc,
MaleVeenaNpc,
FemaleVeenaNpc,
MaleRavaNpc = Api.Enums.ApiCollectionType.MaleRavaNpc,
FemaleRavaNpc = Api.Enums.ApiCollectionType.FemaleRavaNpc,
MaleVeenaNpc = Api.Enums.ApiCollectionType.MaleVeenaNpc,
FemaleVeenaNpc = Api.Enums.ApiCollectionType.FemaleVeenaNpc,
Inactive, // A collection was added or removed
Default, // The default collection was changed
Interface, // The ui collection was changed
Individual, // An individual collection was changed
Current, // The current collection was changed
Temporary, // A temporary collections was set or deleted via IPC
Default = Api.Enums.ApiCollectionType.Default, // The default collection was changed
Interface = Api.Enums.ApiCollectionType.Interface, // The ui collection was changed
Current = Api.Enums.ApiCollectionType.Current, // The current collection was changed
Individual, // An individual collection was changed
Inactive, // A collection was added or removed
Temporary, // A temporary collections was set or deleted via IPC
}
public static class CollectionTypeExtensions
{
public static bool IsSpecial( this CollectionType collectionType )
=> collectionType is >= CollectionType.Yourself and < CollectionType.Inactive;
=> collectionType is >= CollectionType.Yourself and < CollectionType.Default;
public static readonly (CollectionType, string, string)[] Special = Enum.GetValues< CollectionType >()
.Where( IsSpecial )
@ -216,7 +216,9 @@ public static class CollectionTypeExtensions
public static bool TryParse( string text, out CollectionType type )
{
if( Enum.TryParse( text, true, out type ) )
{
return type is not CollectionType.Inactive and not CollectionType.Temporary;
}
if( string.Equals( text, "character", StringComparison.OrdinalIgnoreCase ) )
{
@ -245,7 +247,9 @@ public static class CollectionTypeExtensions
foreach( var t in Enum.GetValues< CollectionType >() )
{
if( t is CollectionType.Inactive or CollectionType.Temporary )
{
continue;
}
if( string.Equals( text, t.ToName(), StringComparison.OrdinalIgnoreCase ) )
{