mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
fix #11, reshuffled some UI and added a button to the main menu/lobby
This commit is contained in:
parent
15eb435929
commit
8adeab1ba5
12 changed files with 399 additions and 134 deletions
|
|
@ -12,6 +12,10 @@ namespace Penumbra
|
|||
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
public bool ShowAdvanced { get; set; } = false;
|
||||
|
||||
public bool DisableFileSystemNotifications { get; set; } = false;
|
||||
|
||||
public string CurrentCollection { get; set; } = @"D:/ffxiv/fs_mods/";
|
||||
|
||||
public List< string > ModCollections { get; set; } = new();
|
||||
|
|
|
|||
50
Penumbra/Game/GameUtils.cs
Normal file
50
Penumbra/Game/GameUtils.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Plugin;
|
||||
using Reloaded.Hooks.Definitions.X64;
|
||||
|
||||
namespace Penumbra.Game
|
||||
{
|
||||
public class GameUtils
|
||||
{
|
||||
private readonly DalamudPluginInterface _pluginInterface;
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||
|
||||
|
||||
public LoadPlayerResourcesPrototype LoadPlayerResources { get; private set; }
|
||||
public UnloadPlayerResourcesPrototype UnloadPlayerResources { get; private set; }
|
||||
|
||||
// Object addresses
|
||||
private IntPtr _playerResourceManagerAddress;
|
||||
public IntPtr PlayerResourceManagerPtr => Marshal.ReadIntPtr( _playerResourceManagerAddress );
|
||||
|
||||
public GameUtils( DalamudPluginInterface pluginInterface )
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
|
||||
var scanner = _pluginInterface.TargetModuleScanner;
|
||||
|
||||
var loadPlayerResourcesAddress =
|
||||
scanner.ScanText(
|
||||
"E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " );
|
||||
var unloadPlayerResourcesAddress =
|
||||
scanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" );
|
||||
|
||||
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
||||
|
||||
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
|
||||
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
|
||||
}
|
||||
|
||||
public unsafe void ReloadPlayerResources()
|
||||
{
|
||||
UnloadPlayerResources( PlayerResourceManagerPtr );
|
||||
LoadPlayerResources( PlayerResourceManagerPtr );
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Penumbra/Importer/ImporterState.cs
Normal file
10
Penumbra/Importer/ImporterState.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
namespace Penumbra.Importer
|
||||
{
|
||||
public enum ImporterState
|
||||
{
|
||||
None,
|
||||
WritingPackToDisk,
|
||||
ExtractingModFiles,
|
||||
Done
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Lumina.Data;
|
||||
|
||||
namespace Penumbra.Importer
|
||||
{
|
||||
public class MagicTempFileStreamManagerAndDeleterFuckery : SqPackStream, IDisposable
|
||||
{
|
||||
private readonly FileStream _fileStream;
|
||||
|
||||
public MagicTempFileStreamManagerAndDeleterFuckery( FileStream stream ) : base( stream )
|
||||
{
|
||||
_fileStream = stream;
|
||||
}
|
||||
|
||||
public new void Dispose()
|
||||
{
|
||||
var filePath = _fileStream.Name;
|
||||
|
||||
base.Dispose();
|
||||
_fileStream.Dispose();
|
||||
|
||||
File.Delete( filePath );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,13 +16,40 @@ namespace Penumbra.Importer
|
|||
{
|
||||
private readonly DirectoryInfo _outDirectory;
|
||||
|
||||
private const string TempFileName = "textools-import";
|
||||
private readonly string _resolvedTempFilePath = null;
|
||||
|
||||
public ImporterState State { get; private set; }
|
||||
|
||||
public long TotalProgress { get; private set; }
|
||||
public long CurrentProgress { get; private set; }
|
||||
|
||||
public float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if( CurrentProgress != 0 )
|
||||
{
|
||||
// ReSharper disable twice RedundantCast
|
||||
return ( float )CurrentProgress / ( float )TotalProgress;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public string CurrentModPack { get; private set; }
|
||||
|
||||
public TexToolsImport( DirectoryInfo outDirectory )
|
||||
{
|
||||
_outDirectory = outDirectory;
|
||||
_resolvedTempFilePath = Path.Combine( _outDirectory.FullName, TempFileName );
|
||||
}
|
||||
|
||||
public void ImportModPack( FileInfo modPackFile )
|
||||
{
|
||||
CurrentModPack = modPackFile.Name;
|
||||
|
||||
switch( modPackFile.Extension )
|
||||
{
|
||||
case ".ttmp":
|
||||
|
|
@ -33,6 +60,29 @@ namespace Penumbra.Importer
|
|||
ImportV2ModPack( modPackFile );
|
||||
return;
|
||||
}
|
||||
|
||||
State = ImporterState.Done;
|
||||
}
|
||||
|
||||
private void WriteZipEntryToTempFile( Stream s )
|
||||
{
|
||||
var fs = new FileStream( _resolvedTempFilePath, FileMode.Create );
|
||||
s.CopyTo( fs );
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
private SqPackStream GetMagicSqPackDeleterStream( ZipFile file, string entryName )
|
||||
{
|
||||
State = ImporterState.WritingPackToDisk;
|
||||
|
||||
// write shitty zip garbage to disk
|
||||
var entry = file.GetEntry( entryName );
|
||||
using var s = file.GetInputStream( entry );
|
||||
|
||||
WriteZipEntryToTempFile( s );
|
||||
|
||||
var fs = new FileStream( _resolvedTempFilePath, FileMode.Open );
|
||||
return new MagicTempFileStreamManagerAndDeleterFuckery( fs );
|
||||
}
|
||||
|
||||
private void ImportV1ModPack( FileInfo modPackFile )
|
||||
|
|
@ -59,8 +109,7 @@ namespace Penumbra.Importer
|
|||
};
|
||||
|
||||
// Open the mod data file from the modpack as a SqPackStream
|
||||
var mpd = extractedModPack.GetEntry( "TTMPD.mpd" );
|
||||
var modData = GetSqPackStreamFromZipEntry( extractedModPack, mpd );
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = new DirectoryInfo(
|
||||
Path.Combine( _outDirectory.FullName,
|
||||
|
|
@ -115,8 +164,7 @@ namespace Penumbra.Importer
|
|||
};
|
||||
|
||||
// Open the mod data file from the modpack as a SqPackStream
|
||||
var mpd = extractedModPack.GetEntry( "TTMPD.mpd" );
|
||||
var modData = GetSqPackStreamFromZipEntry( extractedModPack, mpd );
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = new DirectoryInfo( Path.Combine( _outDirectory.FullName,
|
||||
Path.GetFileNameWithoutExtension( modList.Name ) ) );
|
||||
|
|
@ -142,12 +190,12 @@ namespace Penumbra.Importer
|
|||
Name = modList.Name,
|
||||
Description = string.IsNullOrEmpty( modList.Description )
|
||||
? "Mod imported from TexTools mod pack"
|
||||
: modList.Description
|
||||
: modList.Description,
|
||||
Version = modList.Version
|
||||
};
|
||||
|
||||
// Open the mod data file from the modpack as a SqPackStream
|
||||
var mpd = extractedModPack.GetEntry( "TTMPD.mpd" );
|
||||
var modData = GetSqPackStreamFromZipEntry( extractedModPack, mpd );
|
||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||
|
||||
var newModFolder = new DirectoryInfo(
|
||||
Path.Combine( _outDirectory.FullName,
|
||||
|
|
@ -187,13 +235,24 @@ namespace Penumbra.Importer
|
|||
|
||||
private void ExtractSimpleModList( DirectoryInfo outDirectory, IEnumerable< SimpleMod > mods, SqPackStream dataStream )
|
||||
{
|
||||
State = ImporterState.ExtractingModFiles;
|
||||
|
||||
// haha allocation go brr
|
||||
var wtf = mods.ToList();
|
||||
|
||||
TotalProgress = wtf.LongCount();
|
||||
|
||||
// Extract each SimpleMod into the new mod folder
|
||||
foreach( var simpleMod in mods )
|
||||
foreach( var simpleMod in wtf )
|
||||
{
|
||||
if( simpleMod == null )
|
||||
{
|
||||
// do we increment here too???? can this even happen?????
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
ExtractMod( outDirectory, simpleMod, dataStream );
|
||||
CurrentProgress++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,10 +287,5 @@ namespace Penumbra.Importer
|
|||
s.CopyTo( ms );
|
||||
return encoding.GetString( ms.ToArray() );
|
||||
}
|
||||
|
||||
private static SqPackStream GetSqPackStreamFromZipEntry( ZipFile file, ZipEntry entry )
|
||||
{
|
||||
return new( GetStreamFromZipEntry( file, entry ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,10 @@ namespace Penumbra.Models
|
|||
public string Name { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Description { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string Website { get; set; }
|
||||
|
||||
public Dictionary< string, string > FileSwaps { get; } = new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace Penumbra.Mods
|
|||
public List< ModInfo > ModSettings { get; set; }
|
||||
public ResourceMod[] EnabledMods { get; set; }
|
||||
|
||||
|
||||
public ModCollection( DirectoryInfo basePath )
|
||||
{
|
||||
_basePath = basePath;
|
||||
|
|
@ -117,7 +118,7 @@ namespace Penumbra.Mods
|
|||
public void ReorderMod( ModInfo info, bool up )
|
||||
{
|
||||
// todo: certified fucked tier
|
||||
|
||||
|
||||
var prio = info.Priority;
|
||||
var swapPrio = up ? prio + 1 : prio - 1;
|
||||
var swapMeta = ModSettings.FirstOrDefault( x => x.Priority == swapPrio );
|
||||
|
|
@ -126,10 +127,10 @@ namespace Penumbra.Mods
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
info.Priority = swapPrio;
|
||||
swapMeta.Priority = prio;
|
||||
|
||||
|
||||
// reorder mods list
|
||||
ModSettings = ModSettings.OrderBy( x => x.Priority ).ToList();
|
||||
EnabledMods = GetOrderedAndEnabledModList().ToArray();
|
||||
|
|
@ -137,8 +138,7 @@ namespace Penumbra.Mods
|
|||
// save new prios
|
||||
Save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public ModInfo FindModSettings( string name )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Penumbra.Models;
|
||||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
public class ModManager
|
||||
public class ModManager : IDisposable
|
||||
{
|
||||
public readonly Dictionary< string, FileInfo > ResolvedFiles = new();
|
||||
public readonly Dictionary< string, string > SwappedFiles = new();
|
||||
|
|
@ -23,6 +24,33 @@ namespace Penumbra.Mods
|
|||
DiscoverMods( _basePath );
|
||||
}
|
||||
|
||||
// private void FileSystemWatcherOnChanged( object sender, FileSystemEventArgs e )
|
||||
// {
|
||||
// #if DEBUG
|
||||
// PluginLog.Verbose( "file changed: {FullPath}", e.FullPath );
|
||||
// #endif
|
||||
//
|
||||
// if( _plugin.ImportInProgress )
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if( _plugin.Configuration.DisableFileSystemNotifications )
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var file = e.FullPath;
|
||||
//
|
||||
// if( !ResolvedFiles.Any( x => x.Value.FullName == file ) )
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// PluginLog.Log( "a loaded file has been modified - file: {FullPath}", file );
|
||||
// _plugin.GameUtils.ReloadPlayerResources();
|
||||
// }
|
||||
|
||||
public void DiscoverMods( string basePath )
|
||||
{
|
||||
DiscoverMods( new DirectoryInfo( basePath ) );
|
||||
|
|
@ -43,7 +71,21 @@ namespace Penumbra.Mods
|
|||
|
||||
_basePath = basePath;
|
||||
|
||||
ResolvedFiles.Clear();
|
||||
// haha spaghet
|
||||
// _fileSystemWatcher?.Dispose();
|
||||
// _fileSystemWatcher = new FileSystemWatcher( _basePath.FullName )
|
||||
// {
|
||||
// NotifyFilter = NotifyFilters.LastWrite |
|
||||
// NotifyFilters.FileName |
|
||||
// NotifyFilters.DirectoryName,
|
||||
// IncludeSubdirectories = true,
|
||||
// EnableRaisingEvents = true
|
||||
// };
|
||||
//
|
||||
// _fileSystemWatcher.Changed += FileSystemWatcherOnChanged;
|
||||
// _fileSystemWatcher.Created += FileSystemWatcherOnChanged;
|
||||
// _fileSystemWatcher.Deleted += FileSystemWatcherOnChanged;
|
||||
// _fileSystemWatcher.Renamed += FileSystemWatcherOnChanged;
|
||||
|
||||
Mods = new ModCollection( basePath );
|
||||
Mods.Load();
|
||||
|
|
@ -62,7 +104,7 @@ namespace Penumbra.Mods
|
|||
foreach( var mod in Mods.GetOrderedAndEnabledModList() )
|
||||
{
|
||||
mod.FileConflicts?.Clear();
|
||||
|
||||
|
||||
// fixup path
|
||||
var baseDir = mod.ModBasePath.FullName;
|
||||
|
||||
|
|
@ -138,5 +180,10 @@ namespace Penumbra.Mods
|
|||
|
||||
return GetCandidateForGameFile( gameResourcePath )?.FullName ?? GetSwappedFilePath( gameResourcePath );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// _fileSystemWatcher?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,5 +7,6 @@
|
|||
"RepoUrl": "https://github.com/xivdev/Penumbra",
|
||||
"ApplicableVersion": "any",
|
||||
"Tags": [ "modding" ],
|
||||
"DalamudApiLevel": 69420
|
||||
"DalamudApiLevel": 69420,
|
||||
"LoadPriority": 69420
|
||||
}
|
||||
|
|
@ -1,11 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Extensions;
|
||||
using Penumbra.Game;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI;
|
||||
|
||||
|
|
@ -18,6 +13,7 @@ namespace Penumbra
|
|||
private const string CommandName = "/penumbra";
|
||||
|
||||
public DalamudPluginInterface PluginInterface { get; set; }
|
||||
|
||||
public Configuration Configuration { get; set; }
|
||||
|
||||
public ResourceLoader ResourceLoader { get; set; }
|
||||
|
|
@ -26,21 +22,26 @@ namespace Penumbra
|
|||
|
||||
public SettingsInterface SettingsInterface { get; set; }
|
||||
|
||||
public GameUtils GameUtils { get; set; }
|
||||
|
||||
public string PluginDebugTitleStr { get; private set; }
|
||||
|
||||
public bool ImportInProgress => SettingsInterface?.IsImportRunning ?? true;
|
||||
|
||||
public void Initialize( DalamudPluginInterface pluginInterface )
|
||||
{
|
||||
PluginInterface = pluginInterface;
|
||||
|
||||
|
||||
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
Configuration.Initialize( PluginInterface );
|
||||
|
||||
GameUtils = new GameUtils( PluginInterface );
|
||||
|
||||
ModManager = new ModManager();
|
||||
ModManager.DiscoverMods( Configuration.CurrentCollection );
|
||||
|
||||
ResourceLoader = new ResourceLoader( this );
|
||||
|
||||
|
||||
PluginInterface.CommandManager.AddHandler( CommandName, new CommandInfo( OnCommand )
|
||||
{
|
||||
HelpMessage = "/penumbra - toggle ui\n/penumbra reload - reload mod file lists & discover any new mods"
|
||||
|
|
@ -48,7 +49,7 @@ namespace Penumbra
|
|||
|
||||
ResourceLoader.Init();
|
||||
ResourceLoader.Enable();
|
||||
|
||||
|
||||
SettingsInterface = new SettingsInterface( this );
|
||||
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
||||
|
||||
|
|
@ -57,6 +58,8 @@ namespace Penumbra
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
ModManager?.Dispose();
|
||||
|
||||
PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw;
|
||||
|
||||
PluginInterface.CommandManager.RemoveHandler( CommandName );
|
||||
|
|
|
|||
|
|
@ -36,13 +36,6 @@ namespace Penumbra
|
|||
public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType,
|
||||
uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown );
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||
|
||||
[Function( CallingConventions.Microsoft )]
|
||||
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||
|
||||
|
||||
// Hooks
|
||||
public IHook< GetResourceSyncPrototype > GetResourceSyncHook { get; private set; }
|
||||
public IHook< GetResourceAsyncPrototype > GetResourceAsyncHook { get; private set; }
|
||||
|
|
@ -52,14 +45,6 @@ namespace Penumbra
|
|||
public ReadFilePrototype ReadFile { get; private set; }
|
||||
|
||||
|
||||
public LoadPlayerResourcesPrototype LoadPlayerResources { get; private set; }
|
||||
public UnloadPlayerResourcesPrototype UnloadPlayerResources { get; private set; }
|
||||
|
||||
// Object addresses
|
||||
private IntPtr _playerResourceManagerAddress;
|
||||
public IntPtr PlayerResourceManagerPtr => Marshal.ReadIntPtr( _playerResourceManagerAddress );
|
||||
|
||||
|
||||
public bool LogAllFiles = false;
|
||||
|
||||
|
||||
|
|
@ -91,20 +76,6 @@ namespace Penumbra
|
|||
GetResourceAsyncHook = new Hook< GetResourceAsyncPrototype >( GetResourceAsyncHandler, ( long )getResourceAsyncAddress );
|
||||
|
||||
ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress );
|
||||
|
||||
/////
|
||||
|
||||
var loadPlayerResourcesAddress =
|
||||
scanner.ScanText(
|
||||
"E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " );
|
||||
var unloadPlayerResourcesAddress =
|
||||
scanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" );
|
||||
|
||||
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
||||
|
||||
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
|
||||
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
|
||||
ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -215,12 +186,6 @@ namespace Penumbra
|
|||
return ReadFile( pFileHandler, pFileDesc, priority, isSync );
|
||||
}
|
||||
|
||||
public unsafe void ReloadPlayerResource()
|
||||
{
|
||||
UnloadPlayerResources( PlayerResourceManagerPtr );
|
||||
LoadPlayerResources( PlayerResourceManagerPtr );
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
if( IsEnabled )
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ namespace Penumbra.UI
|
|||
private int? _selectedModDeleteIndex;
|
||||
private ModInfo _selectedMod;
|
||||
|
||||
private bool _isImportRunning = false;
|
||||
public bool IsImportRunning = false;
|
||||
private TexToolsImport _texToolsImport = null!;
|
||||
|
||||
public SettingsInterface( Plugin plugin )
|
||||
{
|
||||
|
|
@ -72,6 +73,39 @@ namespace Penumbra.UI
|
|||
ImGui.EndMainMenuBar();
|
||||
}
|
||||
|
||||
if( !_plugin.PluginInterface.ClientState.Condition.Any() && !Visible )
|
||||
{
|
||||
// draw mods button on da menu :DDD
|
||||
var ss = ImGui.GetIO().DisplaySize;
|
||||
var padding = 50;
|
||||
var width = 200;
|
||||
var height = 45;
|
||||
|
||||
// magic numbers
|
||||
ImGui.SetNextWindowPos( new Vector2( ss.X - padding - width, ss.Y - padding - height ), ImGuiCond.Always );
|
||||
|
||||
if(
|
||||
ImGui.Begin(
|
||||
"Penumbra Menu Buttons",
|
||||
ImGuiWindowFlags.AlwaysAutoResize |
|
||||
ImGuiWindowFlags.NoBackground |
|
||||
ImGuiWindowFlags.NoDecoration |
|
||||
ImGuiWindowFlags.NoMove |
|
||||
ImGuiWindowFlags.NoScrollbar |
|
||||
ImGuiWindowFlags.NoResize |
|
||||
ImGuiWindowFlags.NoSavedSettings
|
||||
)
|
||||
)
|
||||
{
|
||||
if( ImGui.Button( "Manage Mods", new Vector2( width, height ) ) )
|
||||
{
|
||||
Visible = !Visible;
|
||||
}
|
||||
|
||||
ImGui.End();
|
||||
}
|
||||
}
|
||||
|
||||
if( !Visible )
|
||||
{
|
||||
return;
|
||||
|
|
@ -91,11 +125,19 @@ namespace Penumbra.UI
|
|||
ImGui.BeginTabBar( "PenumbraSettings" );
|
||||
|
||||
DrawSettingsTab();
|
||||
DrawImportTab();
|
||||
|
||||
if( !_isImportRunning )
|
||||
|
||||
if( !IsImportRunning )
|
||||
{
|
||||
DrawResourceMods();
|
||||
DrawEffectiveFileList();
|
||||
DrawModBrowser();
|
||||
|
||||
DrawInstalledMods();
|
||||
|
||||
if( _plugin.Configuration.ShowAdvanced )
|
||||
{
|
||||
DrawEffectiveFileList();
|
||||
}
|
||||
|
||||
DrawDeleteModal();
|
||||
}
|
||||
|
|
@ -105,6 +147,105 @@ namespace Penumbra.UI
|
|||
ImGui.End();
|
||||
}
|
||||
|
||||
void DrawImportTab()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( "Import Mods" );
|
||||
if( !ret )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !IsImportRunning )
|
||||
{
|
||||
if( ImGui.Button( "Import TexTools Modpacks" ) )
|
||||
{
|
||||
IsImportRunning = true;
|
||||
|
||||
Task.Run( async () =>
|
||||
{
|
||||
var picker = new OpenFileDialog
|
||||
{
|
||||
Multiselect = true,
|
||||
Filter = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*",
|
||||
CheckFileExists = true,
|
||||
Title = "Pick one or more modpacks."
|
||||
};
|
||||
|
||||
var result = await picker.ShowDialogAsync();
|
||||
|
||||
if( result == DialogResult.OK )
|
||||
{
|
||||
foreach( var fileName in picker.FileNames )
|
||||
{
|
||||
PluginLog.Log( "-> {0} START", fileName );
|
||||
|
||||
try
|
||||
{
|
||||
_texToolsImport = new TexToolsImport( new DirectoryInfo( _plugin.Configuration.CurrentCollection ) );
|
||||
_texToolsImport.ImportModPack( new FileInfo( fileName ) );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
PluginLog.LogError( ex, "Could not import one or more modpacks." );
|
||||
}
|
||||
|
||||
PluginLog.Log( "-> {0} OK!", fileName );
|
||||
}
|
||||
|
||||
_texToolsImport = null;
|
||||
ReloadMods();
|
||||
}
|
||||
|
||||
IsImportRunning = false;
|
||||
} );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Button( "Import in progress..." );
|
||||
|
||||
if( _texToolsImport != null )
|
||||
{
|
||||
switch( _texToolsImport.State )
|
||||
{
|
||||
case ImporterState.None:
|
||||
break;
|
||||
case ImporterState.WritingPackToDisk:
|
||||
ImGui.Text( "Writing modpack to disk before extracting..." );
|
||||
break;
|
||||
case ImporterState.ExtractingModFiles:
|
||||
{
|
||||
var str =
|
||||
$"{_texToolsImport.CurrentModPack} - {_texToolsImport.CurrentProgress} of {_texToolsImport.TotalProgress} files";
|
||||
|
||||
ImGui.ProgressBar( _texToolsImport.Progress, new Vector2( -1, 0 ), str );
|
||||
break;
|
||||
}
|
||||
case ImporterState.Done:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
[Conditional( "DEBUG" )]
|
||||
void DrawModBrowser()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( "Available Mods" );
|
||||
if( !ret )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.Text( "woah" );
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
void DrawSettingsTab()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( "Settings" );
|
||||
|
|
@ -113,11 +254,14 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
// FUCKKKKK
|
||||
var basePath = _plugin.Configuration.CurrentCollection;
|
||||
if( ImGui.InputText( "Root Folder", ref basePath, 255 ) )
|
||||
{
|
||||
_plugin.Configuration.CurrentCollection = basePath;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if( ImGui.Button( "Rediscover Mods" ) )
|
||||
|
|
@ -134,77 +278,34 @@ namespace Penumbra.UI
|
|||
|
||||
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 15 );
|
||||
|
||||
#if DEBUG
|
||||
|
||||
ImGui.Text( "debug shit" );
|
||||
|
||||
if( ImGui.Button( "Reload Player Resource" ) )
|
||||
var showAdvanced = _plugin.Configuration.ShowAdvanced;
|
||||
if( ImGui.Checkbox( "Show Advanced Settings", ref showAdvanced ) )
|
||||
{
|
||||
_plugin.ResourceLoader.ReloadPlayerResource();
|
||||
_plugin.Configuration.ShowAdvanced = showAdvanced;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if( _plugin.ResourceLoader != null )
|
||||
if( _plugin.Configuration.ShowAdvanced )
|
||||
{
|
||||
ImGui.Checkbox( "DEBUG Log all loaded files", ref _plugin.ResourceLoader.LogAllFiles );
|
||||
}
|
||||
|
||||
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 15 );
|
||||
#endif
|
||||
|
||||
if( !_isImportRunning )
|
||||
{
|
||||
if( ImGui.Button( "Import TexTools Modpacks" ) )
|
||||
if( _plugin.ResourceLoader != null )
|
||||
{
|
||||
_isImportRunning = true;
|
||||
ImGui.Checkbox( "Log all loaded files", ref _plugin.ResourceLoader.LogAllFiles );
|
||||
}
|
||||
|
||||
Task.Run( async () =>
|
||||
{
|
||||
var picker = new OpenFileDialog
|
||||
{
|
||||
Multiselect = true,
|
||||
Filter = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*",
|
||||
CheckFileExists = true,
|
||||
Title = "Pick one or more modpacks."
|
||||
};
|
||||
var fswatch = _plugin.Configuration.DisableFileSystemNotifications;
|
||||
if( ImGui.Checkbox( "Disable filesystem change notifications", ref fswatch ) )
|
||||
{
|
||||
_plugin.Configuration.DisableFileSystemNotifications = fswatch;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
var result = await picker.ShowDialogAsync();
|
||||
|
||||
if( result == DialogResult.OK )
|
||||
{
|
||||
try
|
||||
{
|
||||
var importer =
|
||||
new TexToolsImport( new DirectoryInfo( _plugin.Configuration.CurrentCollection ) );
|
||||
|
||||
foreach( var fileName in picker.FileNames )
|
||||
{
|
||||
PluginLog.Log( "-> {0} START", fileName );
|
||||
|
||||
importer.ImportModPack( new FileInfo( fileName ) );
|
||||
|
||||
PluginLog.Log( "-> {0} OK!", fileName );
|
||||
}
|
||||
|
||||
ReloadMods();
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
PluginLog.LogError( ex, "Could not import one or more modpacks." );
|
||||
}
|
||||
}
|
||||
|
||||
_isImportRunning = false;
|
||||
} );
|
||||
if( ImGui.Button( "Reload Player Resource" ) )
|
||||
{
|
||||
_plugin.GameUtils.ReloadPlayerResources();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Button( "Import in progress..." );
|
||||
}
|
||||
|
||||
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 15 );
|
||||
|
||||
if( ImGui.Button( "Save Settings" ) )
|
||||
if( dirty )
|
||||
{
|
||||
_plugin.Configuration.Save();
|
||||
}
|
||||
|
|
@ -385,9 +486,9 @@ namespace Penumbra.UI
|
|||
ImGui.EndPopup();
|
||||
}
|
||||
|
||||
void DrawResourceMods()
|
||||
void DrawInstalledMods()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( "Mods" );
|
||||
var ret = ImGui.BeginTabItem( "Installed Mods" );
|
||||
if( !ret )
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue