mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Added a whole lot of rudimentary comments, also importing selects the last imported mod if possible.
This commit is contained in:
parent
a19ec226c5
commit
d29049ca21
24 changed files with 83 additions and 23 deletions
|
|
@ -27,6 +27,7 @@ namespace Penumbra.Game.Enums
|
|||
Viera,
|
||||
}
|
||||
|
||||
// The combined gender-race-npc numerical code as used by the game.
|
||||
public enum GenderRace : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ namespace Penumbra.Hooks
|
|||
Marshal.GetDelegateForFunctionPointer< UnloadCharacterResourcePrototype >( unloadCharacterResourceAddress );
|
||||
}
|
||||
|
||||
// Forces the reload of a specific set of 85 files, notably containing the eqp, eqdp, gmp and est tables, by filename.
|
||||
public unsafe void ReloadPlayerResources()
|
||||
{
|
||||
ReloadCharacterResources();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ using Dalamud.Plugin;
|
|||
|
||||
namespace Penumbra.Hooks
|
||||
{
|
||||
// Use this to disable streaming of specific soundfiles,
|
||||
// which will allow replacement of .scd files.
|
||||
public unsafe class MusicManager
|
||||
{
|
||||
private readonly IntPtr _musicManager;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace Penumbra.Importer
|
|||
private const string TempFileName = "textools-import";
|
||||
private readonly string _resolvedTempFilePath;
|
||||
|
||||
public DirectoryInfo? ExtractedDirectory { get; private set; }
|
||||
|
||||
public ImporterState State { get; private set; }
|
||||
|
||||
public long TotalProgress { get; private set; }
|
||||
|
|
@ -161,14 +163,14 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( _outDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
ExtractedDirectory = CreateModFolder( _outDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine( newModFolder.FullName, "meta.json" ),
|
||||
Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||
JsonConvert.SerializeObject( modMeta )
|
||||
);
|
||||
|
||||
ExtractSimpleModList( newModFolder, modList, modData );
|
||||
ExtractSimpleModList( ExtractedDirectory, modList, modData );
|
||||
}
|
||||
|
||||
private void ImportV2ModPack( FileInfo modPackFile, ZipFile extractedModPack, string modRaw )
|
||||
|
|
@ -228,12 +230,12 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
ExtractedDirectory = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
|
||||
File.WriteAllText( Path.Combine( newModFolder.FullName, "meta.json" ),
|
||||
File.WriteAllText( Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||
JsonConvert.SerializeObject( modMeta ) );
|
||||
|
||||
ExtractSimpleModList( newModFolder, modList.SimpleModsList ?? Enumerable.Empty< SimpleMod >(), modData );
|
||||
ExtractSimpleModList( ExtractedDirectory, modList.SimpleModsList ?? Enumerable.Empty< SimpleMod >(), modData );
|
||||
}
|
||||
|
||||
private void ImportExtendedV2ModPack( ZipFile extractedModPack, string modRaw )
|
||||
|
|
@ -256,11 +258,11 @@ namespace Penumbra.Importer
|
|||
// Open the mod data file from the modpack as a SqPackStream
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
ExtractedDirectory = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||
|
||||
if( modList.SimpleModsList != null )
|
||||
{
|
||||
ExtractSimpleModList( newModFolder, modList.SimpleModsList, modData );
|
||||
ExtractSimpleModList( ExtractedDirectory, modList.SimpleModsList, modData );
|
||||
}
|
||||
|
||||
if( modList.ModPackPages == null )
|
||||
|
|
@ -278,7 +280,7 @@ namespace Penumbra.Importer
|
|||
|
||||
foreach( var group in page.ModGroups.Where( group => group.GroupName != null && group.OptionList != null ) )
|
||||
{
|
||||
var groupFolder = NewOptionDirectory( newModFolder, group.GroupName! );
|
||||
var groupFolder = NewOptionDirectory( ExtractedDirectory, group.GroupName! );
|
||||
if( groupFolder.Exists )
|
||||
{
|
||||
groupFolder = new DirectoryInfo( groupFolder.FullName + $" ({page.PageIndex})" );
|
||||
|
|
@ -291,12 +293,12 @@ namespace Penumbra.Importer
|
|||
ExtractSimpleModList( optionFolder, option.ModsJsons!, modData );
|
||||
}
|
||||
|
||||
AddMeta( newModFolder, groupFolder, group, modMeta );
|
||||
AddMeta( ExtractedDirectory, groupFolder, group, modMeta );
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine( newModFolder.FullName, "meta.json" ),
|
||||
Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||
JsonConvert.SerializeObject( modMeta, Formatting.Indented )
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,18 @@ using GameData = Penumbra.Game.Enums.GameData;
|
|||
|
||||
namespace Penumbra.Importer
|
||||
{
|
||||
// TexTools provices custom generated *.meta files for its modpacks, that contain changes to
|
||||
// - imc files
|
||||
// - eqp files
|
||||
// - gmp files
|
||||
// - est files
|
||||
// - eqdp files
|
||||
// made by the mod. The filename determines to what the changes are applied, and the binary file itself contains changes.
|
||||
// We parse every *.meta file in a mod and combine all actual changes that do not keep data on default values and that can be applied to the game in a .json.
|
||||
// TexTools may also generate files that contain non-existing changes, e.g. *.imc files for weapon offhands, which will be ignored.
|
||||
public class TexToolsMeta
|
||||
{
|
||||
// The info class determines the files or table locations the changes need to apply to from the filename.
|
||||
public class Info
|
||||
{
|
||||
private const string Pt = @"(?'PrimaryType'[a-z]*)"; // language=regex
|
||||
|
|
@ -28,6 +38,7 @@ namespace Penumbra.Importer
|
|||
private const string Slot = @"(_(?'Slot'[a-z]{3}))?"; // language=regex
|
||||
private const string Ext = @"\.meta";
|
||||
|
||||
// These are the valid regexes for .meta files that we are able to support at the moment.
|
||||
private static readonly Regex HousingMeta = new( $"bgcommon/hou/{Pt}/general/{Pi}/{Pir}{Ext}" );
|
||||
private static readonly Regex CharaMeta = new( $"chara/{Pt}/{Pp}{Pi}(/obj/{St}/{Sp}{Si})?/{File}{Slot}{Ext}" );
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ namespace Penumbra.Meta.Files
|
|||
{ }
|
||||
}
|
||||
|
||||
// Imc files are already supported in Lumina, but changing the provided data is not supported.
|
||||
// We use reflection and extension methods to support changing the data of a given Imc file.
|
||||
public static class ImcExtensions
|
||||
{
|
||||
public static ulong ToInteger( this ImcFile.ImageChangeData imc )
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Meta.Files
|
||||
{
|
||||
// This class manages the default meta files obtained via lumina from the game files themselves.
|
||||
// On first call, the default version of any supported file will be cached and can be returned without reparsing.
|
||||
public class MetaDefaults
|
||||
{
|
||||
private readonly DalamudPluginInterface _pi;
|
||||
|
|
@ -107,6 +109,7 @@ namespace Penumbra.Meta.Files
|
|||
private FileResource FetchFile( string name )
|
||||
=> _pi.Data.GetFile( name );
|
||||
|
||||
// Check that a given meta manipulation is an actual change to the default value. We don't need to keep changes to default.
|
||||
public bool CheckAgainstDefault( MetaManipulation m )
|
||||
{
|
||||
return m.Type switch
|
||||
|
|
@ -129,6 +132,7 @@ namespace Penumbra.Meta.Files
|
|||
};
|
||||
}
|
||||
|
||||
// Create a deep copy of a default file as a new file.
|
||||
public object? CreateNewFile( MetaManipulation m )
|
||||
{
|
||||
return m.Type switch
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Meta.Files
|
||||
{
|
||||
// Contains all filenames for meta changes depending on their parameters.
|
||||
public static class MetaFileNames
|
||||
{
|
||||
public static GamePath Eqp()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Penumbra.Game.Enums;
|
||||
|
||||
|
||||
// A struct for each type of meta change that contains all relevant information,
|
||||
// to uniquely identify the corresponding file and location for the change.
|
||||
// The first byte is guaranteed to be the MetaType enum for each case.
|
||||
namespace Penumbra.Meta
|
||||
{
|
||||
public enum MetaType : byte
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using ImcFile = Lumina.Data.Files.ImcFile;
|
|||
|
||||
namespace Penumbra.Meta
|
||||
{
|
||||
// Write a single meta manipulation as a Base64string of the 16 bytes defining it.
|
||||
public class MetaManipulationConverter : JsonConverter< MetaManipulation >
|
||||
{
|
||||
public override void WriteJson( JsonWriter writer, MetaManipulation manip, JsonSerializer serializer )
|
||||
|
|
@ -38,6 +39,10 @@ namespace Penumbra.Meta
|
|||
}
|
||||
}
|
||||
|
||||
// A MetaManipulation is a union of a type of Identifier (first 8 bytes, cf. Identifier.cs)
|
||||
// and the appropriate Value to change the meta entry to (the other 8 bytes).
|
||||
// Its comparison for sorting and hashes depends only on the identifier.
|
||||
// The first byte is guaranteed to be a MetaType enum value in any case, so Type can always be read.
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[JsonConverter( typeof( MetaManipulationConverter ) )]
|
||||
public struct MetaManipulation : IComparable
|
||||
|
|
@ -219,11 +224,11 @@ namespace Penumbra.Meta
|
|||
{
|
||||
return Type switch
|
||||
{
|
||||
MetaType.Eqp => $"EQP - {EqpIdentifier}",
|
||||
MetaType.Eqdp => $"EQDP - {EqdpIdentifier}",
|
||||
MetaType.Est => $"EST - {EstIdentifier}",
|
||||
MetaType.Gmp => $"GMP - {GmpIdentifier}",
|
||||
MetaType.Imc => $"IMC - {ImcIdentifier}",
|
||||
MetaType.Eqp => EqpIdentifier.ToString(),
|
||||
MetaType.Eqdp => EqdpIdentifier.ToString(),
|
||||
MetaType.Est => EstIdentifier.ToString(),
|
||||
MetaType.Gmp => GmpIdentifier.ToString(),
|
||||
MetaType.Imc => ImcIdentifier.ToString(),
|
||||
_ => throw new InvalidEnumArgumentException(),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// A complete Mod containing settings (i.e. dependent on a collection)
|
||||
// and the resulting cache.
|
||||
public class Mod
|
||||
{
|
||||
public ModSettings Settings { get; }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// The ModCache contains volatile information dependent on all current settings in a collection.
|
||||
public class ModCache
|
||||
{
|
||||
public Dictionary< Mod, (List< GamePath > Files, List< MetaManipulation > Manipulations) > Conflicts { get; private set; } = new();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ using Dalamud.Plugin;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// ModData contains all permanent information about a mod,
|
||||
// and is independent of collections or settings.
|
||||
// It only changes when the user actively changes the mod or their filesystem.
|
||||
public class ModData
|
||||
{
|
||||
public DirectoryInfo BasePath;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// Functions that do not really depend on only one component of a mod.
|
||||
public static class ModFunctions
|
||||
{
|
||||
public static bool CleanUpCollection( Dictionary< string, ModSettings > settings, IEnumerable< DirectoryInfo > modPaths )
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ namespace Penumbra.Mod
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static ModMeta? LoadFromFile( FileInfo filePath )
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Penumbra.Structs;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// Contains the settings for a given mod.
|
||||
public class ModSettings
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ using Penumbra.Structs;
|
|||
|
||||
namespace Penumbra.Mod
|
||||
{
|
||||
// Contains settings with the option selections stored by names instead of index.
|
||||
// This is meant to make them possibly more portable when we support importing collections from other users.
|
||||
// Enabled does not exist, because disabled mods would not be exported in this way.
|
||||
public class NamedModSettings
|
||||
{
|
||||
public int Priority { get; set; }
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
// A ModCollection is a named set of ModSettings to all of the users' installed mods.
|
||||
// It is meant to be local only, and thus should always contain settings for every mod, not just the enabled ones.
|
||||
// Settings to mods that are not installed anymore are kept as long as no call to CleanUnavailableSettings is made.
|
||||
// Active ModCollections build a cache of currently relevant data.
|
||||
public class ModCollection
|
||||
{
|
||||
public const string DefaultCollection = "Default";
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
// The ModCollectionCache contains all required temporary data to use a collection.
|
||||
// It will only be setup if a collection gets activated in any way.
|
||||
public class ModCollectionCache
|
||||
{
|
||||
public readonly List< Mod.Mod > AvailableMods = new();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
// The ModManager handles the basic mods installed to the mod directory,
|
||||
// as well as all saved collections.
|
||||
// It also handles manual changes to mods that require changes in all collections,
|
||||
// updating the state of a mod from the filesystem,
|
||||
// and collection swapping.
|
||||
public class ModManager
|
||||
{
|
||||
private readonly Plugin _plugin;
|
||||
|
|
@ -216,7 +221,6 @@ namespace Penumbra.Mods
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
public bool UpdateMod( ModData mod, bool recomputeMeta = false )
|
||||
{
|
||||
var oldName = mod.Meta.Name;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using Penumbra.Structs;
|
|||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
// Extracted to keep the main file a bit more clean.
|
||||
// Contains all change functions on a specific mod that also require corresponding changes to collections.
|
||||
public static class ModManagerEditExtensions
|
||||
{
|
||||
public static bool RenameMod( this ModManager manager, string newName, ModData mod )
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ namespace Penumbra.UI.Custom
|
|||
var itemWidth = ImGui.CalcItemWidth();
|
||||
ImGui.PushItemWidth( Math.Max( 0f, itemWidth - frameHeight ) );
|
||||
|
||||
labelStack.Add( ( labelMin, labelMax ) );
|
||||
LabelStack.Add( ( labelMin, labelMax ) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -111,8 +111,8 @@ namespace Penumbra.UI.Custom
|
|||
|
||||
var itemMin = ImGui.GetItemRectMin();
|
||||
var itemMax = ImGui.GetItemRectMax();
|
||||
var (currentLabelMin, currentLabelMax) = labelStack[ labelStack.Count - 1 ];
|
||||
labelStack.RemoveAt( labelStack.Count - 1 );
|
||||
var (currentLabelMin, currentLabelMax) = LabelStack[ LabelStack.Count - 1 ];
|
||||
LabelStack.RemoveAt( LabelStack.Count - 1 );
|
||||
|
||||
var halfFrame = new Vector2( frameHeight / 8, frameHeight / 2 );
|
||||
currentLabelMin.X -= itemSpacing.X;
|
||||
|
|
@ -143,6 +143,6 @@ namespace Penumbra.UI.Custom
|
|||
|
||||
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
||||
|
||||
private static readonly List< (Vector2, Vector2) > labelStack = new();
|
||||
private static readonly List< (Vector2, Vector2) > LabelStack = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -76,8 +76,13 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
var directory = _texToolsImport?.ExtractedDirectory;
|
||||
_texToolsImport = null;
|
||||
_base.ReloadMods();
|
||||
if( directory != null )
|
||||
{
|
||||
_base._menu.InstalledTab.Selector.SelectModByDir( directory.Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_base = ui;
|
||||
_modNamesLower = Array.Empty< string >();
|
||||
_modManager = Service<ModManager>.Get();
|
||||
_modManager = Service< ModManager >.Get();
|
||||
ResetModNamesLower();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue