mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Stuff.
This commit is contained in:
parent
e33f49e097
commit
ef9022a746
12 changed files with 205 additions and 204 deletions
|
|
@ -1253,7 +1253,7 @@ public class IpcTester : IDisposable
|
|||
.FirstOrDefault()
|
||||
?? "Unknown";
|
||||
if (ImGui.Button($"Save##{collection.Name}"))
|
||||
Mod.TemporaryMod.SaveTempCollection(_modManager, collection, character);
|
||||
TemporaryMod.SaveTempCollection(_modManager, collection, character);
|
||||
|
||||
ImGuiUtil.DrawTableColumn(collection.Name);
|
||||
ImGuiUtil.DrawTableColumn(collection.ResolvedFiles.Count.ToString());
|
||||
|
|
@ -1271,7 +1271,7 @@ public class IpcTester : IDisposable
|
|||
|
||||
using var table = ImRaii.Table("##modTree", 5);
|
||||
|
||||
void PrintList(string collectionName, IReadOnlyList<Mod.TemporaryMod> list)
|
||||
void PrintList(string collectionName, IReadOnlyList<TemporaryMod> list)
|
||||
{
|
||||
foreach (var mod in list)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class TempCollectionManager : IDisposable
|
|||
_communicator.TemporaryGlobalModChange.Event -= OnGlobalModChange;
|
||||
}
|
||||
|
||||
private void OnGlobalModChange(Mod.TemporaryMod mod, bool created, bool removed)
|
||||
private void OnGlobalModChange(TemporaryMod mod, bool created, bool removed)
|
||||
=> TempModManager.OnGlobalModChange(_customCollections.Values, mod, created, removed);
|
||||
|
||||
public int Count
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ public class TempModManager : IDisposable
|
|||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
|
||||
private readonly Dictionary<ModCollection, List<Mod.TemporaryMod>> _mods = new();
|
||||
private readonly List<Mod.TemporaryMod> _modsForAllCollections = new();
|
||||
private readonly Dictionary<ModCollection, List<TemporaryMod>> _mods = new();
|
||||
private readonly List<TemporaryMod> _modsForAllCollections = new();
|
||||
|
||||
public TempModManager(CommunicatorService communicator)
|
||||
{
|
||||
|
|
@ -34,10 +34,10 @@ public class TempModManager : IDisposable
|
|||
_communicator.CollectionChange.Event -= OnCollectionChange;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<ModCollection, List<Mod.TemporaryMod>> Mods
|
||||
public IReadOnlyDictionary<ModCollection, List<TemporaryMod>> Mods
|
||||
=> _mods;
|
||||
|
||||
public IReadOnlyList<Mod.TemporaryMod> ModsForAllCollections
|
||||
public IReadOnlyList<TemporaryMod> ModsForAllCollections
|
||||
=> _modsForAllCollections;
|
||||
|
||||
public RedirectResult Register(string tag, ModCollection? collection, Dictionary<Utf8GamePath, FullPath> dict,
|
||||
|
|
@ -74,7 +74,7 @@ public class TempModManager : IDisposable
|
|||
}
|
||||
|
||||
// Apply any new changes to the temporary mod.
|
||||
private void ApplyModChange(Mod.TemporaryMod mod, ModCollection? collection, bool created, bool removed)
|
||||
private void ApplyModChange(TemporaryMod mod, ModCollection? collection, bool created, bool removed)
|
||||
{
|
||||
if (collection != null)
|
||||
{
|
||||
|
|
@ -92,7 +92,7 @@ public class TempModManager : IDisposable
|
|||
/// <summary>
|
||||
/// Apply a mod change to a set of collections.
|
||||
/// </summary>
|
||||
public static void OnGlobalModChange(IEnumerable<ModCollection> collections, Mod.TemporaryMod mod, bool created, bool removed)
|
||||
public static void OnGlobalModChange(IEnumerable<ModCollection> collections, TemporaryMod mod, bool created, bool removed)
|
||||
{
|
||||
if (removed)
|
||||
foreach (var c in collections)
|
||||
|
|
@ -104,9 +104,9 @@ public class TempModManager : IDisposable
|
|||
|
||||
// Find or create a mod with the given tag as name and the given priority, for the given collection (or all collections).
|
||||
// Returns the found or created mod and whether it was newly created.
|
||||
private Mod.TemporaryMod GetOrCreateMod(string tag, ModCollection? collection, int priority, out bool created)
|
||||
private TemporaryMod GetOrCreateMod(string tag, ModCollection? collection, int priority, out bool created)
|
||||
{
|
||||
List<Mod.TemporaryMod> list;
|
||||
List<TemporaryMod> list;
|
||||
if (collection == null)
|
||||
{
|
||||
list = _modsForAllCollections;
|
||||
|
|
@ -117,14 +117,14 @@ public class TempModManager : IDisposable
|
|||
}
|
||||
else
|
||||
{
|
||||
list = new List<Mod.TemporaryMod>();
|
||||
list = new List<TemporaryMod>();
|
||||
_mods.Add(collection, list);
|
||||
}
|
||||
|
||||
var mod = list.Find(m => m.Priority == priority && m.Name == tag);
|
||||
if (mod == null)
|
||||
{
|
||||
mod = new Mod.TemporaryMod()
|
||||
mod = new TemporaryMod()
|
||||
{
|
||||
Name = tag,
|
||||
Priority = priority,
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public partial class ModCollection
|
|||
_modManager.ModPathChanged -= OnModPathChange;
|
||||
}
|
||||
|
||||
private void OnGlobalModChange(Mod.TemporaryMod mod, bool created, bool removed)
|
||||
private void OnGlobalModChange(TemporaryMod mod, bool created, bool removed)
|
||||
=> TempModManager.OnGlobalModChange(_collections, mod, created, removed);
|
||||
|
||||
// Returns true if the name is not empty, it is not the name of the empty collection
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public partial class ModCollection
|
|||
=> CalculateEffectiveFileList(this == Penumbra.CollectionManager.Default);
|
||||
|
||||
// Handle temporary mods for this collection.
|
||||
public void Apply(Mod.TemporaryMod tempMod, bool created)
|
||||
public void Apply(TemporaryMod tempMod, bool created)
|
||||
{
|
||||
if (created)
|
||||
_cache?.AddMod(tempMod, tempMod.TotalManipulations > 0);
|
||||
|
|
@ -52,7 +52,7 @@ public partial class ModCollection
|
|||
_cache?.ReloadMod(tempMod, tempMod.TotalManipulations > 0);
|
||||
}
|
||||
|
||||
public void Remove(Mod.TemporaryMod tempMod)
|
||||
public void Remove(TemporaryMod tempMod)
|
||||
{
|
||||
_cache?.RemoveMod(tempMod, tempMod.TotalManipulations > 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public partial class ModCollection
|
|||
|
||||
// Add all forced redirects.
|
||||
foreach( var tempMod in Penumbra.TempMods.ModsForAllCollections.Concat(
|
||||
Penumbra.TempMods.Mods.TryGetValue( _collection, out var list ) ? list : Array.Empty< Mod.TemporaryMod >() ) )
|
||||
Penumbra.TempMods.Mods.TryGetValue( _collection, out var list ) ? list : Array.Empty< TemporaryMod >() ) )
|
||||
{
|
||||
AddMod( tempMod, false );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class ModDataEditor
|
|||
mod.Description = description ?? mod.Description;
|
||||
mod.Version = version ?? mod.Version;
|
||||
mod.Website = website ?? mod.Website;
|
||||
_saveService.ImmediateSave(new ModMeta(mod));
|
||||
_saveService.ImmediateSave(new Mod.ModMeta(mod));
|
||||
}
|
||||
|
||||
public ModDataChangeType LoadLocalData(Mod mod)
|
||||
|
|
@ -96,7 +96,7 @@ public class ModDataEditor
|
|||
}
|
||||
|
||||
if (save)
|
||||
_saveService.QueueSave(new ModData(mod));
|
||||
_saveService.QueueSave(new Mod.ModData(mod));
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ public class ModDataEditor
|
|||
if (Mod.Migration.Migrate(mod, json))
|
||||
{
|
||||
changes |= ModDataChangeType.Migration;
|
||||
_saveService.ImmediateSave(new ModMeta(mod));
|
||||
_saveService.ImmediateSave(new Mod.ModMeta(mod));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +189,7 @@ public class ModDataEditor
|
|||
|
||||
var oldName = mod.Name;
|
||||
mod.Name = newName;
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Name, mod, oldName.Text);
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Author = newAuthor;
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Author, mod, null);
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Description = newDescription;
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Description, mod, null);
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Version = newVersion;
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Version, mod, null);
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Website = newWebsite;
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Website, mod, null);
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Favorite = state;
|
||||
_saveService.QueueSave(new ModData(mod));
|
||||
_saveService.QueueSave(new Mod.ModData(mod));
|
||||
;
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Favorite, mod, null);
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ public class ModDataEditor
|
|||
return;
|
||||
|
||||
mod.Note = newNote;
|
||||
_saveService.QueueSave(new ModData(mod));
|
||||
_saveService.QueueSave(new Mod.ModData(mod));
|
||||
;
|
||||
_communicatorService.ModDataChanged.Invoke(ModDataChangeType.Favorite, mod, null);
|
||||
}
|
||||
|
|
@ -281,10 +281,10 @@ public class ModDataEditor
|
|||
}
|
||||
|
||||
if (flags.HasFlag(ModDataChangeType.ModTags))
|
||||
_saveService.QueueSave(new ModMeta(mod));
|
||||
_saveService.QueueSave(new Mod.ModMeta(mod));
|
||||
|
||||
if (flags.HasFlag(ModDataChangeType.LocalTags))
|
||||
_saveService.QueueSave(new ModData(mod));
|
||||
_saveService.QueueSave(new Mod.ModData(mod));
|
||||
|
||||
if (flags != 0)
|
||||
_communicatorService.ModDataChanged.Invoke(flags, mod, null);
|
||||
|
|
@ -306,57 +306,4 @@ public class ModDataEditor
|
|||
Penumbra.Log.Error($"Could not move local data file {oldFile} to {newFile}:\n{e}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private readonly struct ModMeta : ISavable
|
||||
{
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModMeta(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.ModMetaPath(_mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(Mod.FileVersion), JToken.FromObject(_mod.FileVersion) },
|
||||
{ nameof(Mod.Name), JToken.FromObject(_mod.Name) },
|
||||
{ nameof(Mod.Author), JToken.FromObject(_mod.Author) },
|
||||
{ nameof(Mod.Description), JToken.FromObject(_mod.Description) },
|
||||
{ nameof(Mod.Version), JToken.FromObject(_mod.Version) },
|
||||
{ nameof(Mod.Website), JToken.FromObject(_mod.Website) },
|
||||
{ nameof(Mod.ModTags), JToken.FromObject(_mod.ModTags) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct ModData : ISavable
|
||||
{
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModData(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.LocalDataFile(_mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(Mod.FileVersion), JToken.FromObject(_mod.FileVersion) },
|
||||
{ nameof(Mod.ImportDate), JToken.FromObject(_mod.ImportDate) },
|
||||
{ nameof(Mod.LocalTags), JToken.FromObject(_mod.LocalTags) },
|
||||
{ nameof(Mod.Note), JToken.FromObject(_mod.Note) },
|
||||
{ nameof(Mod.Favorite), JToken.FromObject(_mod.Favorite) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -49,4 +51,29 @@ public sealed partial class Mod
|
|||
|
||||
return type;
|
||||
}
|
||||
|
||||
internal readonly struct ModData : ISavable
|
||||
{
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModData(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.LocalDataFile(_mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(FileVersion), JToken.FromObject(_mod.FileVersion) },
|
||||
{ nameof(ImportDate), JToken.FromObject(_mod.ImportDate) },
|
||||
{ nameof(LocalTags), JToken.FromObject(_mod.LocalTags) },
|
||||
{ nameof(Note), JToken.FromObject(_mod.Note) },
|
||||
{ nameof(Favorite), JToken.FromObject(_mod.Favorite) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
||||
public sealed partial class Mod : IMod
|
||||
{
|
||||
public static readonly TemporaryMod ForcedFiles = new()
|
||||
|
|
@ -13,15 +18,42 @@ public sealed partial class Mod : IMod
|
|||
Priority = int.MaxValue,
|
||||
};
|
||||
|
||||
public const uint CurrentFileVersion = 3;
|
||||
public uint FileVersion { get; internal set; } = CurrentFileVersion;
|
||||
public LowerString Name { get; internal set; } = "New Mod";
|
||||
public LowerString Author { get; internal set; } = LowerString.Empty;
|
||||
public string Description { get; internal set; } = string.Empty;
|
||||
public string Version { get; internal set; } = string.Empty;
|
||||
public string Website { get; internal set; } = string.Empty;
|
||||
public IReadOnlyList< string > ModTags { get; internal set; } = Array.Empty< string >();
|
||||
public const uint CurrentFileVersion = 3;
|
||||
public uint FileVersion { get; internal set; } = CurrentFileVersion;
|
||||
public LowerString Name { get; internal set; } = "New Mod";
|
||||
public LowerString Author { get; internal set; } = LowerString.Empty;
|
||||
public string Description { get; internal set; } = string.Empty;
|
||||
public string Version { get; internal set; } = string.Empty;
|
||||
public string Website { get; internal set; } = string.Empty;
|
||||
public IReadOnlyList<string> ModTags { get; internal set; } = Array.Empty<string>();
|
||||
|
||||
public override string ToString()
|
||||
=> Name.Text;
|
||||
}
|
||||
|
||||
internal readonly struct ModMeta : ISavable
|
||||
{
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModMeta(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.ModMetaPath(_mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(FileVersion), JToken.FromObject(_mod.FileVersion) },
|
||||
{ nameof(Name), JToken.FromObject(_mod.Name) },
|
||||
{ nameof(Author), JToken.FromObject(_mod.Author) },
|
||||
{ nameof(Description), JToken.FromObject(_mod.Description) },
|
||||
{ nameof(Version), JToken.FromObject(_mod.Version) },
|
||||
{ nameof(Website), JToken.FromObject(_mod.Website) },
|
||||
{ nameof(ModTags), JToken.FromObject(_mod.ModTags) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public sealed partial class Mod
|
||||
{
|
||||
public class TemporaryMod : IMod
|
||||
{
|
||||
public LowerString Name { get; init; } = LowerString.Empty;
|
||||
public int Index { get; init; } = -2;
|
||||
public int Priority { get; init; } = int.MaxValue;
|
||||
|
||||
public int TotalManipulations
|
||||
=> Default.Manipulations.Count;
|
||||
|
||||
public ISubMod Default
|
||||
=> _default;
|
||||
|
||||
public IReadOnlyList< IModGroup > Groups
|
||||
=> Array.Empty< IModGroup >();
|
||||
|
||||
public IEnumerable< ISubMod > AllSubMods
|
||||
=> new[] { Default };
|
||||
|
||||
private readonly SubMod _default;
|
||||
|
||||
public TemporaryMod()
|
||||
=> _default = new SubMod( this );
|
||||
|
||||
public void SetFile( Utf8GamePath gamePath, FullPath fullPath )
|
||||
=> _default.FileData[ gamePath ] = fullPath;
|
||||
|
||||
public bool SetManipulation( MetaManipulation manip )
|
||||
=> _default.ManipulationData.Remove( manip ) | _default.ManipulationData.Add( manip );
|
||||
|
||||
public void SetAll( Dictionary< Utf8GamePath, FullPath > dict, HashSet< MetaManipulation > manips )
|
||||
{
|
||||
_default.FileData = dict;
|
||||
_default.ManipulationData = manips;
|
||||
}
|
||||
|
||||
public static void SaveTempCollection( Mod.Manager modManager, ModCollection collection, string? character = null )
|
||||
{
|
||||
DirectoryInfo? dir = null;
|
||||
try
|
||||
{
|
||||
dir = Creator.CreateModFolder( Penumbra.ModManager.BasePath, collection.Name );
|
||||
var fileDir = Directory.CreateDirectory( Path.Combine( dir.FullName, "files" ) );
|
||||
modManager.DataEditor.CreateMeta( dir, collection.Name, character ?? Penumbra.Config.DefaultModAuthor,
|
||||
$"Mod generated from temporary collection {collection.Name} for {character ?? "Unknown Character"}.", null, null );
|
||||
var mod = new Mod( dir );
|
||||
var defaultMod = mod._default;
|
||||
foreach( var (gamePath, fullPath) in collection.ResolvedFiles )
|
||||
{
|
||||
if( gamePath.Path.EndsWith( ".imc"u8 ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var targetPath = fullPath.Path.FullName;
|
||||
if( fullPath.Path.Name.StartsWith( '|' ) )
|
||||
{
|
||||
targetPath = targetPath.Split( '|', 3, StringSplitOptions.RemoveEmptyEntries ).Last();
|
||||
}
|
||||
|
||||
if( Path.IsPathRooted(targetPath) )
|
||||
{
|
||||
var target = Path.Combine( fileDir.FullName, Path.GetFileName(targetPath) );
|
||||
File.Copy( targetPath, target, true );
|
||||
defaultMod.FileData[ gamePath ] = new FullPath( target );
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultMod.FileSwapData[ gamePath ] = new FullPath(targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach( var manip in collection.MetaCache?.Manipulations ?? Array.Empty< MetaManipulation >() )
|
||||
{
|
||||
defaultMod.ManipulationData.Add( manip );
|
||||
}
|
||||
|
||||
mod.SaveDefaultMod();
|
||||
modManager.AddMod( dir );
|
||||
Penumbra.Log.Information( $"Successfully generated mod {mod.Name} at {mod.ModPath.FullName} for collection {collection.Name}." );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Could not save temporary collection {collection.Name} to permanent Mod:\n{e}" );
|
||||
if( dir != null && Directory.Exists( dir.FullName ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete( dir.FullName, true );
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
106
Penumbra/Mods/TemporaryMod.cs
Normal file
106
Penumbra/Mods/TemporaryMod.cs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public class TemporaryMod : IMod
|
||||
{
|
||||
public LowerString Name { get; init; } = LowerString.Empty;
|
||||
public int Index { get; init; } = -2;
|
||||
public int Priority { get; init; } = int.MaxValue;
|
||||
|
||||
public int TotalManipulations
|
||||
=> Default.Manipulations.Count;
|
||||
|
||||
public ISubMod Default
|
||||
=> _default;
|
||||
|
||||
public IReadOnlyList< IModGroup > Groups
|
||||
=> Array.Empty< IModGroup >();
|
||||
|
||||
public IEnumerable< ISubMod > AllSubMods
|
||||
=> new[] { Default };
|
||||
|
||||
private readonly Mod.SubMod _default;
|
||||
|
||||
public TemporaryMod()
|
||||
=> _default = new Mod.SubMod( this );
|
||||
|
||||
public void SetFile( Utf8GamePath gamePath, FullPath fullPath )
|
||||
=> _default.FileData[ gamePath ] = fullPath;
|
||||
|
||||
public bool SetManipulation( MetaManipulation manip )
|
||||
=> _default.ManipulationData.Remove( manip ) | _default.ManipulationData.Add( manip );
|
||||
|
||||
public void SetAll( Dictionary< Utf8GamePath, FullPath > dict, HashSet< MetaManipulation > manips )
|
||||
{
|
||||
_default.FileData = dict;
|
||||
_default.ManipulationData = manips;
|
||||
}
|
||||
|
||||
public static void SaveTempCollection( Mod.Manager modManager, ModCollection collection, string? character = null )
|
||||
{
|
||||
DirectoryInfo? dir = null;
|
||||
try
|
||||
{
|
||||
dir = Mod.Creator.CreateModFolder( Penumbra.ModManager.BasePath, collection.Name );
|
||||
var fileDir = Directory.CreateDirectory( Path.Combine( dir.FullName, "files" ) );
|
||||
modManager.DataEditor.CreateMeta( dir, collection.Name, character ?? Penumbra.Config.DefaultModAuthor,
|
||||
$"Mod generated from temporary collection {collection.Name} for {character ?? "Unknown Character"}.", null, null );
|
||||
var mod = new Mod( dir );
|
||||
var defaultMod = (Mod.SubMod) mod.Default;
|
||||
foreach( var (gamePath, fullPath) in collection.ResolvedFiles )
|
||||
{
|
||||
if( gamePath.Path.EndsWith( ".imc"u8 ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var targetPath = fullPath.Path.FullName;
|
||||
if( fullPath.Path.Name.StartsWith( '|' ) )
|
||||
{
|
||||
targetPath = targetPath.Split( '|', 3, StringSplitOptions.RemoveEmptyEntries ).Last();
|
||||
}
|
||||
|
||||
if( Path.IsPathRooted(targetPath) )
|
||||
{
|
||||
var target = Path.Combine( fileDir.FullName, Path.GetFileName(targetPath) );
|
||||
File.Copy( targetPath, target, true );
|
||||
defaultMod.FileData[ gamePath ] = new FullPath( target );
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultMod.FileSwapData[ gamePath ] = new FullPath(targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach( var manip in collection.MetaCache?.Manipulations ?? Array.Empty< MetaManipulation >() )
|
||||
defaultMod.ManipulationData.Add( manip );
|
||||
|
||||
mod.SaveDefaultMod();
|
||||
modManager.AddMod( dir );
|
||||
Penumbra.Log.Information( $"Successfully generated mod {mod.Name} at {mod.ModPath.FullName} for collection {collection.Name}." );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Could not save temporary collection {collection.Name} to permanent Mod:\n{e}" );
|
||||
if( dir != null && Directory.Exists( dir.FullName ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete( dir.FullName, true );
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ public class CommunicatorService : IDisposable
|
|||
/// <item>Parameter is whether the mod was newly created.</item>
|
||||
/// <item>Parameter is whether the mod was deleted.</item>
|
||||
/// </list> </summary>
|
||||
public readonly EventWrapper<Mod.TemporaryMod, bool, bool> TemporaryGlobalModChange = new(nameof(TemporaryGlobalModChange));
|
||||
public readonly EventWrapper<TemporaryMod, bool, bool> TemporaryGlobalModChange = new(nameof(TemporaryGlobalModChange));
|
||||
|
||||
/// <summary> <list type="number">
|
||||
/// <item>Parameter is the type of change. </item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue