mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 06:13:45 +01:00
Use external library for API interface and IPC.
This commit is contained in:
parent
b3f048bfe6
commit
918d5db6a6
69 changed files with 4026 additions and 1873 deletions
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Util;
|
||||
|
|
@ -16,7 +17,7 @@ public sealed partial class Mod
|
|||
public delegate void ModOptionChangeDelegate( ModOptionChangeType type, Mod mod, int groupIdx, int optionIdx, int movedToIdx );
|
||||
public event ModOptionChangeDelegate ModOptionChanged;
|
||||
|
||||
public void ChangeModGroupType( Mod mod, int groupIdx, SelectType type )
|
||||
public void ChangeModGroupType( Mod mod, int groupIdx, GroupType type )
|
||||
{
|
||||
var group = mod._groups[ groupIdx ];
|
||||
if( group.Type == type )
|
||||
|
|
@ -61,7 +62,7 @@ public sealed partial class Mod
|
|||
ModOptionChanged.Invoke( ModOptionChangeType.GroupRenamed, mod, groupIdx, -1, -1 );
|
||||
}
|
||||
|
||||
public void AddModGroup( Mod mod, SelectType type, string newName )
|
||||
public void AddModGroup( Mod mod, GroupType type, string newName )
|
||||
{
|
||||
if( !VerifyFileName( mod, null, newName, true ) )
|
||||
{
|
||||
|
|
@ -70,7 +71,7 @@ public sealed partial class Mod
|
|||
|
||||
var maxPriority = mod._groups.Count == 0 ? 0 : mod._groups.Max( o => o.Priority ) + 1;
|
||||
|
||||
mod._groups.Add( type == SelectType.Multi
|
||||
mod._groups.Add( type == GroupType.Multi
|
||||
? new MultiModGroup { Name = newName, Priority = maxPriority }
|
||||
: new SingleModGroup { Name = newName, Priority = maxPriority } );
|
||||
ModOptionChanged.Invoke( ModOptionChangeType.GroupAdded, mod, mod._groups.Count - 1, -1, -1 );
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using Dalamud.Utility;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Import;
|
||||
|
||||
|
|
@ -62,12 +63,12 @@ public partial class Mod
|
|||
}
|
||||
|
||||
// Create a file for an option group from given data.
|
||||
internal static void CreateOptionGroup( DirectoryInfo baseFolder, SelectType type, string name,
|
||||
internal static void CreateOptionGroup( DirectoryInfo baseFolder, GroupType type, string name,
|
||||
int priority, int index, uint defaultSettings, string desc, IEnumerable< ISubMod > subMods )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Multi:
|
||||
case GroupType.Multi:
|
||||
{
|
||||
var group = new MultiModGroup()
|
||||
{
|
||||
|
|
@ -80,7 +81,7 @@ public partial class Mod
|
|||
IModGroup.Save( group, baseFolder, index );
|
||||
break;
|
||||
}
|
||||
case SelectType.Single:
|
||||
case GroupType.Single:
|
||||
{
|
||||
var group = new SingleModGroup()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
||||
|
|
@ -79,10 +80,10 @@ public partial class Mod
|
|||
try
|
||||
{
|
||||
var json = JObject.Parse( File.ReadAllText( file.FullName ) );
|
||||
switch( json[ nameof( Type ) ]?.ToObject< SelectType >() ?? SelectType.Single )
|
||||
switch( json[ nameof( Type ) ]?.ToObject< GroupType >() ?? GroupType.Single )
|
||||
{
|
||||
case SelectType.Multi: return MultiModGroup.Load( mod, json, groupIdx );
|
||||
case SelectType.Single: return SingleModGroup.Load( mod, json, groupIdx );
|
||||
case GroupType.Multi: return MultiModGroup.Load( mod, json, groupIdx );
|
||||
case GroupType.Single: return SingleModGroup.Load( mod, json, groupIdx );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
|
@ -128,7 +129,7 @@ public sealed partial class Mod
|
|||
|
||||
switch( group.SelectionType )
|
||||
{
|
||||
case SelectType.Multi:
|
||||
case GroupType.Multi:
|
||||
|
||||
var optionPriority = 0;
|
||||
var newMultiGroup = new MultiModGroup()
|
||||
|
|
@ -144,7 +145,7 @@ public sealed partial class Mod
|
|||
}
|
||||
|
||||
break;
|
||||
case SelectType.Single:
|
||||
case GroupType.Single:
|
||||
if( group.Options.Count == 1 )
|
||||
{
|
||||
AddFilesToSubMod( mod._default, mod.ModPath, group.Options[ 0 ], seenMetaFiles );
|
||||
|
|
@ -209,7 +210,7 @@ public sealed partial class Mod
|
|||
public string GroupName = string.Empty;
|
||||
|
||||
[JsonConverter( typeof( Newtonsoft.Json.Converters.StringEnumConverter ) )]
|
||||
public SelectType SelectionType = SelectType.Single;
|
||||
public GroupType SelectionType = GroupType.Single;
|
||||
|
||||
public List< OptionV0 > Options = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
|
@ -121,8 +122,7 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
CreateLeaf( Root, name, mod );
|
||||
break;
|
||||
case ModPathChangeType.Deleted:
|
||||
var leaf = Root.GetAllDescendants( ISortMode< Mod >.Lexicographical ).OfType< Leaf >().FirstOrDefault( l => l.Value == mod );
|
||||
if( leaf != null )
|
||||
if( FindLeaf( mod, out var leaf ) )
|
||||
{
|
||||
Delete( leaf );
|
||||
}
|
||||
|
|
@ -137,6 +137,16 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
// Search the entire filesystem for the leaf corresponding to a mod.
|
||||
public bool FindLeaf( Mod mod, [NotNullWhen( true )] out Leaf? leaf )
|
||||
{
|
||||
leaf = Root.GetAllDescendants( ISortMode< Mod >.Lexicographical )
|
||||
.OfType< Leaf >()
|
||||
.FirstOrDefault( l => l.Value == mod );
|
||||
return leaf != null;
|
||||
}
|
||||
|
||||
|
||||
// Used for saving and loading.
|
||||
private static string ModToIdentifier( Mod mod )
|
||||
=> mod.ModPath.Name;
|
||||
|
|
@ -144,15 +154,16 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
private static string ModToName( Mod mod )
|
||||
=> mod.Name.Text.FixName();
|
||||
|
||||
private static (string, bool) SaveMod( Mod mod, string fullPath )
|
||||
// Return whether a mod has a custom path or is just a numbered default path.
|
||||
public static bool ModHasDefaultPath( Mod mod, string fullPath )
|
||||
{
|
||||
var regex = new Regex( $@"^{Regex.Escape( ModToName( mod ) )}( \(\d+\))?$" );
|
||||
// Only save pairs with non-default paths.
|
||||
if( regex.IsMatch( fullPath ) )
|
||||
{
|
||||
return ( string.Empty, false );
|
||||
}
|
||||
|
||||
return ( ModToIdentifier( mod ), true );
|
||||
return regex.IsMatch( fullPath );
|
||||
}
|
||||
|
||||
private static (string, bool) SaveMod( Mod mod, string fullPath )
|
||||
// Only save pairs with non-default paths.
|
||||
=> ModHasDefaultPath( mod, fullPath )
|
||||
? ( string.Empty, false )
|
||||
: ( ModToIdentifier( mod ), true );
|
||||
}
|
||||
|
|
@ -3,22 +3,17 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public enum SelectType
|
||||
{
|
||||
Single,
|
||||
Multi,
|
||||
}
|
||||
|
||||
public interface IModGroup : IEnumerable< ISubMod >
|
||||
{
|
||||
public const int MaxMultiOptions = 32;
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public SelectType Type { get; }
|
||||
public GroupType Type { get; }
|
||||
public int Priority { get; }
|
||||
public uint DefaultSettings { get; set; }
|
||||
|
||||
|
|
@ -31,8 +26,8 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
public bool IsOption
|
||||
=> Type switch
|
||||
{
|
||||
SelectType.Single => Count > 1,
|
||||
SelectType.Multi => Count > 0,
|
||||
GroupType.Single => Count > 1,
|
||||
GroupType.Multi => Count > 0,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
@ -90,7 +85,7 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
j.WriteStartArray();
|
||||
for( var idx = 0; idx < group.Count; ++idx )
|
||||
{
|
||||
ISubMod.WriteSubMod( j, serializer, group[ idx ], basePath, group.Type == SelectType.Multi ? group.OptionPriority( idx ) : null );
|
||||
ISubMod.WriteSubMod( j, serializer, group[ idx ], basePath, group.Type == GroupType.Multi ? group.OptionPriority( idx ) : null );
|
||||
}
|
||||
|
||||
j.WriteEndArray();
|
||||
|
|
@ -98,7 +93,7 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
Penumbra.Log.Debug( $"Saved group file {file} for group {groupIdx + 1}: {group.Name}." );
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type );
|
||||
public IModGroup Convert( GroupType type );
|
||||
public bool MoveOption( int optionIdxFrom, int optionIdxTo );
|
||||
public void UpdatePositions( int from = 0 );
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -15,8 +16,8 @@ public partial class Mod
|
|||
// Groups that allow all available options to be selected at once.
|
||||
private sealed class MultiModGroup : IModGroup
|
||||
{
|
||||
public SelectType Type
|
||||
=> SelectType.Multi;
|
||||
public GroupType Type
|
||||
=> GroupType.Multi;
|
||||
|
||||
public string Name { get; set; } = "Group";
|
||||
public string Description { get; set; } = "A non-exclusive group of settings.";
|
||||
|
|
@ -79,12 +80,12 @@ public partial class Mod
|
|||
return ret;
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type )
|
||||
public IModGroup Convert( GroupType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Multi: return this;
|
||||
case SelectType.Single:
|
||||
case GroupType.Multi: return this;
|
||||
case GroupType.Single:
|
||||
var multi = new SingleModGroup()
|
||||
{
|
||||
Name = Name,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -14,8 +15,8 @@ public partial class Mod
|
|||
// Groups that allow only one of their available options to be selected.
|
||||
private sealed class SingleModGroup : IModGroup
|
||||
{
|
||||
public SelectType Type
|
||||
=> SelectType.Single;
|
||||
public GroupType Type
|
||||
=> GroupType.Single;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
public string Description { get; set; } = "A mutually exclusive group of settings.";
|
||||
|
|
@ -72,12 +73,12 @@ public partial class Mod
|
|||
return ret;
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type )
|
||||
public IModGroup Convert( GroupType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Single: return this;
|
||||
case SelectType.Multi:
|
||||
case GroupType.Single: return this;
|
||||
case GroupType.Multi:
|
||||
var multi = new MultiModGroup()
|
||||
{
|
||||
Name = Name,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -56,8 +57,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => ( uint )Math.Max( Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ), 0 ),
|
||||
SelectType.Multi => 1u << ( int )config,
|
||||
GroupType.Single => ( uint )Math.Max( Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ), 0 ),
|
||||
GroupType.Multi => 1u << ( int )config,
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -70,8 +71,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => config >= optionIdx ? config > 1 ? config - 1 : 0 : config,
|
||||
SelectType.Multi => Functions.RemoveBit( config, optionIdx ),
|
||||
GroupType.Single => config >= optionIdx ? config > 1 ? config - 1 : 0 : config,
|
||||
GroupType.Multi => Functions.RemoveBit( config, optionIdx ),
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -87,8 +88,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => config == optionIdx ? ( uint )movedToIdx : config,
|
||||
SelectType.Multi => Functions.MoveBit( config, optionIdx, movedToIdx ),
|
||||
GroupType.Single => config == optionIdx ? ( uint )movedToIdx : config,
|
||||
GroupType.Multi => Functions.MoveBit( config, optionIdx, movedToIdx ),
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -101,8 +102,8 @@ public class ModSettings
|
|||
private static uint FixSetting( IModGroup group, uint value )
|
||||
=> group.Type switch
|
||||
{
|
||||
SelectType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
||||
SelectType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
||||
GroupType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
||||
GroupType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
||||
_ => value,
|
||||
};
|
||||
|
||||
|
|
@ -202,7 +203,7 @@ public class ModSettings
|
|||
}
|
||||
|
||||
var group = mod.Groups[ idx ];
|
||||
if( group.Type == SelectType.Single && setting < group.Count )
|
||||
if( group.Type == GroupType.Single && setting < group.Count )
|
||||
{
|
||||
dict.Add( group.Name, new[] { group[ ( int )setting ].Name } );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue