move desc to own tab, invert load order setting, normalise line endings

This commit is contained in:
Adam 2021-01-16 00:23:53 +11:00
parent fa9e4d7dcc
commit 25ac5d1999
14 changed files with 476 additions and 414 deletions

View file

@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Linq; using System.Linq;
using EmbedIO; using EmbedIO;
using EmbedIO.Routing; using EmbedIO.Routing;
@ -25,7 +24,7 @@ namespace Penumbra.API
x.FolderName, x.FolderName,
x.Mod.Meta, x.Mod.Meta,
BasePath = x.Mod.ModBasePath.FullName, BasePath = x.Mod.ModBasePath.FullName,
Files = x.Mod.ModFiles.Select( x => x.FullName ) Files = x.Mod.ModFiles.Select( fi => fi.FullName )
} ); } );
} }

View file

@ -12,16 +12,18 @@ namespace Penumbra
public bool IsEnabled { get; set; } = true; public bool IsEnabled { get; set; } = true;
public bool ShowAdvanced { get; set; } = false; public bool ShowAdvanced { get; set; }
public bool DisableFileSystemNotifications { get; set; } = false; public bool DisableFileSystemNotifications { get; set; }
public bool EnableHttpApi { get; set; } = false; public bool EnableHttpApi { get; set; }
public string CurrentCollection { get; set; } = @"D:/ffxiv/fs_mods/"; public string CurrentCollection { get; set; } = @"D:/ffxiv/fs_mods/";
public List< string > ModCollections { get; set; } = new(); public List< string > ModCollections { get; set; } = new();
public bool InvertModListOrder { get; set; }
// the below exist just to make saving less cumbersome // the below exist just to make saving less cumbersome
[NonSerialized] [NonSerialized]

View file

@ -1,9 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -49,15 +46,15 @@ namespace Penumbra
public class HiddenForm : Form public class HiddenForm : Form
{ {
private readonly CommonDialog form; private readonly CommonDialog _form;
private readonly IWin32Window owner; private readonly IWin32Window _owner;
private readonly TaskCompletionSource< DialogResult > taskSource; private readonly TaskCompletionSource< DialogResult > _taskSource;
public HiddenForm( CommonDialog form, IWin32Window owner, TaskCompletionSource< DialogResult > taskSource ) public HiddenForm( CommonDialog form, IWin32Window owner, TaskCompletionSource< DialogResult > taskSource )
{ {
this.form = form; this._form = form;
this.owner = owner; this._owner = owner;
this.taskSource = taskSource; this._taskSource = taskSource;
Opacity = 0; Opacity = 0;
FormBorderStyle = FormBorderStyle.None; FormBorderStyle = FormBorderStyle.None;
@ -72,12 +69,12 @@ namespace Penumbra
Hide(); Hide();
try try
{ {
var result = form.ShowDialog( owner ); var result = _form.ShowDialog( _owner );
taskSource.SetResult( result ); _taskSource.SetResult( result );
} }
catch( Exception e ) catch( Exception e )
{ {
taskSource.SetException( e ); _taskSource.SetException( e );
} }
Close(); Close();

View file

@ -7,8 +7,6 @@ namespace Penumbra.Game
{ {
public class GameUtils public class GameUtils
{ {
private readonly DalamudPluginInterface _pluginInterface;
[Function( CallingConventions.Microsoft )] [Function( CallingConventions.Microsoft )]
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager ); public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
@ -25,9 +23,7 @@ namespace Penumbra.Game
public GameUtils( DalamudPluginInterface pluginInterface ) public GameUtils( DalamudPluginInterface pluginInterface )
{ {
_pluginInterface = pluginInterface; var scanner = pluginInterface.TargetModuleScanner;
var scanner = _pluginInterface.TargetModuleScanner;
var loadPlayerResourcesAddress = var loadPlayerResourcesAddress =
scanner.ScanText( scanner.ScanText(

View file

@ -17,7 +17,7 @@ namespace Penumbra.Importer
private readonly DirectoryInfo _outDirectory; private readonly DirectoryInfo _outDirectory;
private const string TempFileName = "textools-import"; private const string TempFileName = "textools-import";
private readonly string _resolvedTempFilePath = null; private readonly string _resolvedTempFilePath;
public ImporterState State { get; private set; } public ImporterState State { get; private set; }
@ -216,9 +216,9 @@ namespace Penumbra.Importer
from option in modGroup.OptionList from option in modGroup.OptionList
select option ) select option )
{ {
var OptionFolder = new DirectoryInfo(Path.Combine(newModFolder.FullName, option.Name)); var optionFolder = new DirectoryInfo( Path.Combine( newModFolder.FullName, option.Name ) );
ExtractSimpleModList(OptionFolder, option.ModsJsons, modData ); ExtractSimpleModList( optionFolder, option.ModsJsons, modData );
AddMeta(OptionFolder, newModFolder, modMeta, option.Name); AddMeta( optionFolder, newModFolder, modMeta, option.Name );
} }
File.WriteAllText( File.WriteAllText(

View file

@ -8,7 +8,6 @@ namespace Penumbra.Models
[Serializable] [Serializable]
public class GroupInformation : ISerializable public class GroupInformation : ISerializable
{ {
// This class is just used as a temp class while (de)-serializing. // This class is just used as a temp class while (de)-serializing.
// It converts the flags into lists and back. // It converts the flags into lists and back.
[Serializable] [Serializable]
@ -31,6 +30,7 @@ namespace Penumbra.Models
ret.Add( groupType[ i ] ); ret.Add( groupType[ i ] );
} }
} }
return ret; return ret;
} }
@ -55,8 +55,10 @@ namespace Penumbra.Models
if( index >= 0 ) if( index >= 0 )
flags |= ( 1u << index ); flags |= ( 1u << index );
} }
return flags; return flags;
} }
var tops = ( uint )TypesToFlags( TopTypes, info.TopTypes ); var tops = ( uint )TypesToFlags( TopTypes, info.TopTypes );
var bottoms = ( uint )TypesToFlags( BottomTypes, info.BottomTypes ); var bottoms = ( uint )TypesToFlags( BottomTypes, info.BottomTypes );
// Exclusions are the other way around. // Exclusions are the other way around.
@ -65,9 +67,9 @@ namespace Penumbra.Models
} }
public string GamePath { get; set; } public string GamePath { get; set; }
public List<string> TopTypes { get; set; } = null; public List< string > TopTypes { get; set; }
public List<string> BottomTypes { get; set; } = null; public List< string > BottomTypes { get; set; }
public List<string> GroupExclusions { get; set; } = null; public List< string > GroupExclusions { get; set; }
// Customize (De)-Serialization to ignore nulls. // Customize (De)-Serialization to ignore nulls.
public GroupDescription( SerializationInfo info, StreamingContext context ) public GroupDescription( SerializationInfo info, StreamingContext context )
@ -81,8 +83,12 @@ namespace Penumbra.Models
return null; return null;
return ret; return ret;
} }
catch (Exception) { return null; } catch( Exception )
{
return null;
} }
}
GamePath = info.GetString( "GamePath" ); GamePath = info.GetString( "GamePath" );
TopTypes = readListOrNull( "TopTypes" ); TopTypes = readListOrNull( "TopTypes" );
BottomTypes = readListOrNull( "BottomTypes" ); BottomTypes = readListOrNull( "BottomTypes" );
@ -126,20 +132,46 @@ namespace Penumbra.Models
public Dictionary< string, (string, uint, uint, ulong) > FileToGameAndGroup { get; set; } = new(); public Dictionary< string, (string, uint, uint, ulong) > FileToGameAndGroup { get; set; } = new();
public GroupInformation(){ } public GroupInformation()
{
}
public GroupInformation( SerializationInfo info, StreamingContext context ) public GroupInformation( SerializationInfo info, StreamingContext context )
{ {
try { TopTypes = (List<string>) info.GetValue( "TopTypes", TopTypes.GetType() ); } catch(Exception){ } try
try { BottomTypes = (List<string>) info.GetValue( "BottomTypes", BottomTypes.GetType() ); } catch(Exception){ } {
try { OtherGroups = (List<string>) info.GetValue( "Groups", OtherGroups.GetType() ); } catch(Exception){ } TopTypes = ( List< string > )info.GetValue( "TopTypes", TopTypes.GetType() );
}
catch( Exception )
{
}
try
{
BottomTypes = ( List< string > )info.GetValue( "BottomTypes", BottomTypes.GetType() );
}
catch( Exception )
{
}
try
{
OtherGroups = ( List< string > )info.GetValue( "Groups", OtherGroups.GetType() );
}
catch( Exception )
{
}
try try
{ {
Dictionary< string, GroupDescription > dict = new(); Dictionary< string, GroupDescription > dict = new();
dict = ( Dictionary< string, GroupDescription > )info.GetValue( "FileToGameAndGroups", dict.GetType() ); dict = ( Dictionary< string, GroupDescription > )info.GetValue( "FileToGameAndGroups", dict.GetType() );
foreach( var pair in dict ) foreach( var pair in dict )
FileToGameAndGroup.Add( pair.Key, pair.Value.ToTuple( this ) ); FileToGameAndGroup.Add( pair.Key, pair.Value.ToTuple( this ) );
} catch (Exception){ } }
catch( Exception )
{
}
} }
public virtual void GetObjectData( SerializationInfo info, StreamingContext context ) public virtual void GetObjectData( SerializationInfo info, StreamingContext context )

View file

@ -4,6 +4,7 @@ namespace Penumbra.Models
{ {
public class ModMeta public class ModMeta
{ {
public uint FileVersion { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Author { get; set; } public string Author { get; set; }
public string Description { get; set; } public string Description { get; set; }

View file

@ -21,7 +21,7 @@ namespace Penumbra.Mods
_basePath = basePath; _basePath = basePath;
} }
public void Load() public void Load( bool invertOrder = false )
{ {
// find the collection json // find the collection json
var collectionPath = Path.Combine( _basePath.FullName, "collection.json" ); var collectionPath = Path.Combine( _basePath.FullName, "collection.json" );
@ -94,7 +94,7 @@ namespace Penumbra.Mods
} }
// reorder the resourcemods list so we can just directly iterate // reorder the resourcemods list so we can just directly iterate
EnabledMods = GetOrderedAndEnabledModList().ToArray(); EnabledMods = GetOrderedAndEnabledModList( invertOrder ).ToArray();
// write the collection metadata back to disk // write the collection metadata back to disk
Save(); Save();
@ -181,22 +181,28 @@ namespace Penumbra.Mods
return AddModSettings( mod ); return AddModSettings( mod );
} }
public IEnumerable<ModInfo> GetOrderedAndEnabledModSettings() public IEnumerable<ModInfo> GetOrderedAndEnabledModSettings( bool invertOrder = false )
{ {
return ModSettings var query = ModSettings
.Where( x => x.Enabled ) .Where( x => x.Enabled );
.OrderBy( x => x.Priority );
if( !invertOrder )
{
return query.OrderBy( x => x.Priority );
} }
public IEnumerable<ResourceMod> GetOrderedAndEnabledModList() return query.OrderByDescending( x => x.Priority );
}
public IEnumerable<ResourceMod> GetOrderedAndEnabledModList( bool invertOrder = false )
{ {
return GetOrderedAndEnabledModSettings() return GetOrderedAndEnabledModSettings( invertOrder )
.Select( x => x.Mod ); .Select( x => x.Mod );
} }
public IEnumerable<(ResourceMod, ModInfo)> GetOrderedAndEnabledModListWithSettings() public IEnumerable<(ResourceMod, ModInfo)> GetOrderedAndEnabledModListWithSettings( bool invertOrder = false )
{ {
return GetOrderedAndEnabledModSettings() return GetOrderedAndEnabledModSettings( invertOrder )
.Select( x => (x.Mod, x) ); .Select( x => (x.Mod, x) );
} }
} }

View file

@ -110,7 +110,7 @@ namespace Penumbra.Mods
var registeredFiles = new Dictionary< string, string >(); var registeredFiles = new Dictionary< string, string >();
foreach( var (mod, settings) in Mods.GetOrderedAndEnabledModListWithSettings() ) foreach( var (mod, settings) in Mods.GetOrderedAndEnabledModListWithSettings( _plugin.Configuration.InvertModListOrder ) )
{ {
mod.FileConflicts?.Clear(); mod.FileConflicts?.Clear();

View file

@ -34,7 +34,7 @@ namespace Penumbra.Mods
// Only add if not in a sub-folder, otherwise it was already added. // Only add if not in a sub-folder, otherwise it was already added.
foreach( var pair in Meta.Groups.FileToGameAndGroup ) foreach( var pair in Meta.Groups.FileToGameAndGroup )
if (pair.Key.IndexOfAny(new char[]{'/', '\\'}) < 0) if (pair.Key.IndexOfAny(new[]{'/', '\\'}) < 0)
ModFiles.Add( new FileInfo(Path.Combine(ModBasePath.FullName, pair.Key)) ); ModFiles.Add( new FileInfo(Path.Combine(ModBasePath.FullName, pair.Key)) );
} }

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net472</TargetFramework> <TargetFramework>net472</TargetFramework>
<LangVersion>latest</LangVersion> <LangVersion>preview</LangVersion>
<AssemblyTitle>Penumbra</AssemblyTitle> <AssemblyTitle>Penumbra</AssemblyTitle>
<Company>absolute gangstas</Company> <Company>absolute gangstas</Company>
<Product>Penumbra</Product> <Product>Penumbra</Product>

View file

@ -1,7 +1,6 @@
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Plugin; using Dalamud.Plugin;
using EmbedIO; using EmbedIO;
using EmbedIO.Actions;
using EmbedIO.WebApi; using EmbedIO.WebApi;
using Penumbra.API; using Penumbra.API;
using Penumbra.Game; using Penumbra.Game;

View file

@ -18,8 +18,8 @@ namespace Penumbra.UI
{ {
private readonly Plugin _plugin; private readonly Plugin _plugin;
public bool Visible = false; public bool Visible;
public bool ShowDebugBar = false; public bool ShowDebugBar;
private static readonly Vector2 AutoFillSize = new Vector2( -1, -1 ); private static readonly Vector2 AutoFillSize = new Vector2( -1, -1 );
private static readonly Vector2 ModListSize = new Vector2( 200, -1 ); private static readonly Vector2 ModListSize = new Vector2( 200, -1 );
@ -33,7 +33,7 @@ namespace Penumbra.UI
private int? _selectedModDeleteIndex; private int? _selectedModDeleteIndex;
private ModInfo _selectedMod; private ModInfo _selectedMod;
public bool IsImportRunning = false; private bool _isImportRunning;
private TexToolsImport _texToolsImport = null!; private TexToolsImport _texToolsImport = null!;
public SettingsInterface( Plugin plugin ) public SettingsInterface( Plugin plugin )
@ -129,7 +129,7 @@ namespace Penumbra.UI
DrawImportTab(); DrawImportTab();
if( !IsImportRunning ) if( !_isImportRunning )
{ {
DrawModBrowser(); DrawModBrowser();
@ -156,11 +156,11 @@ namespace Penumbra.UI
return; return;
} }
if( !IsImportRunning ) if( !_isImportRunning )
{ {
if( ImGui.Button( "Import TexTools Modpacks" ) ) if( ImGui.Button( "Import TexTools Modpacks" ) )
{ {
IsImportRunning = true; _isImportRunning = true;
Task.Run( async () => Task.Run( async () =>
{ {
@ -197,7 +197,7 @@ namespace Penumbra.UI
ReloadMods(); ReloadMods();
} }
IsImportRunning = false; _isImportRunning = false;
} ); } );
} }
} }
@ -279,7 +279,18 @@ namespace Penumbra.UI
Process.Start( _plugin.Configuration.CurrentCollection ); Process.Start( _plugin.Configuration.CurrentCollection );
} }
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 15 ); ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 20 );
var invertOrder = _plugin.Configuration.InvertModListOrder;
if( ImGui.Checkbox( "Invert mod load order (mods are loaded bottom up)", ref invertOrder ) )
{
_plugin.Configuration.InvertModListOrder = invertOrder;
dirty = true;
ReloadMods();
}
ImGui.SetCursorPosY( ImGui.GetCursorPosY() + 20 );
var showAdvanced = _plugin.Configuration.ShowAdvanced; var showAdvanced = _plugin.Configuration.ShowAdvanced;
if( ImGui.Checkbox( "Show Advanced Settings", ref showAdvanced ) ) if( ImGui.Checkbox( "Show Advanced Settings", ref showAdvanced ) )
@ -405,7 +416,13 @@ namespace Penumbra.UI
ImGui.PopFont(); ImGui.PopFont();
if( ImGui.IsItemHovered() ) if( ImGui.IsItemHovered() )
ImGui.SetTooltip( "Move the selected mod up in priority" ); {
ImGui.SetTooltip(
_plugin.Configuration.InvertModListOrder
? "Move the selected mod down in priority"
: "Move the selected mod up in priority"
);
}
ImGui.PushFont( UiBuilder.IconFont ); ImGui.PushFont( UiBuilder.IconFont );
@ -430,7 +447,13 @@ namespace Penumbra.UI
ImGui.PopFont(); ImGui.PopFont();
if( ImGui.IsItemHovered() ) if( ImGui.IsItemHovered() )
ImGui.SetTooltip( "Move the selected mod down in priority" ); {
ImGui.SetTooltip(
_plugin.Configuration.InvertModListOrder
? "Move the selected mod up in priority"
: "Move the selected mod down in priority"
);
}
ImGui.PushFont( UiBuilder.IconFont ); ImGui.PushFont( UiBuilder.IconFont );
@ -508,8 +531,11 @@ namespace Penumbra.UI
// Website button with On-Hover address if valid http(s), otherwise text. // Website button with On-Hover address if valid http(s), otherwise text.
private void DrawWebsiteText() private void DrawWebsiteText()
{ {
if ((_selectedMod.Mod.Meta.Website?.Length ?? 0) > 0) if( ( _selectedMod.Mod.Meta.Website?.Length ?? 0 ) <= 0 )
{ {
return;
}
var validUrl = Uri.TryCreate( _selectedMod.Mod.Meta.Website, UriKind.Absolute, out Uri uriResult ) var validUrl = Uri.TryCreate( _selectedMod.Mod.Meta.Website, UriKind.Absolute, out Uri uriResult )
&& ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp ); && ( uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp );
ImGui.SameLine(); ImGui.SameLine();
@ -519,6 +545,7 @@ namespace Penumbra.UI
{ {
Process.Start( _selectedMod.Mod.Meta.Website ); Process.Start( _selectedMod.Mod.Meta.Website );
} }
if( ImGui.IsItemHovered() ) if( ImGui.IsItemHovered() )
{ {
ImGui.BeginTooltip(); ImGui.BeginTooltip();
@ -533,7 +560,6 @@ namespace Penumbra.UI
ImGui.Text( _selectedMod.Mod.Meta.Website ); ImGui.Text( _selectedMod.Mod.Meta.Website );
} }
} }
}
// Create Mod-Handling buttons. // Create Mod-Handling buttons.
private void DrawEditButtons() private void DrawEditButtons()
@ -668,9 +694,14 @@ namespace Penumbra.UI
DrawGroupSelectors(); DrawGroupSelectors();
ImGui.TextWrapped( _selectedMod.Mod.Meta.Description ?? "" );
ImGui.BeginTabBar( "PenumbraPluginDetails" ); ImGui.BeginTabBar( "PenumbraPluginDetails" );
if( _selectedMod.Mod.Meta.Description?.Length > 0 && ImGui.BeginTabItem( "About" ) )
{
ImGui.TextWrapped( _selectedMod.Mod.Meta.Description );
ImGui.EndTabItem();
}
if( ( _selectedMod.Mod.Meta.ChangedItems?.Count ?? 0 ) > 0 ) if( ( _selectedMod.Mod.Meta.ChangedItems?.Count ?? 0 ) > 0 )
{ {
if( ImGui.BeginTabItem( "Changed Items" ) ) if( ImGui.BeginTabItem( "Changed Items" ) )
@ -713,6 +744,7 @@ namespace Penumbra.UI
ImGui.EndTabItem(); ImGui.EndTabItem();
} }
} }
if( _selectedMod.Mod.FileConflicts.Any() ) if( _selectedMod.Mod.FileConflicts.Any() )
{ {
if( ImGui.BeginTabItem( "File Conflicts" ) ) if( ImGui.BeginTabItem( "File Conflicts" ) )

View file

@ -1,7 +1,5 @@
using System; using System.Linq;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Penumbra.Extensions;
namespace Penumbra.Util namespace Penumbra.Util
{ {
@ -10,14 +8,14 @@ namespace Penumbra.Util
/// </summary> /// </summary>
public class Crc32 public class Crc32
{ {
private const uint POLY = 0xedb88320; private const uint Poly = 0xedb88320;
private static readonly uint[] CrcArray = private static readonly uint[] CrcArray =
Enumerable.Range( 0, 256 ).Select( i => Enumerable.Range( 0, 256 ).Select( i =>
{ {
var k = ( uint )i; var k = ( uint )i;
for( var j = 0; j < 8; j++ ) for( var j = 0; j < 8; j++ )
k = ( k & 1 ) != 0 ? ( k >> 1 ) ^ POLY : k >> 1; k = ( k & 1 ) != 0 ? ( k >> 1 ) ^ Poly : k >> 1;
return k; return k;
} ).ToArray(); } ).ToArray();