enable nullability checks, wip service locator

This commit is contained in:
Adam 2021-02-21 17:38:19 +11:00
parent 9cff2da484
commit eb0301f964
12 changed files with 115 additions and 41 deletions

View file

@ -2,6 +2,7 @@ using System.Linq;
using EmbedIO; using EmbedIO;
using EmbedIO.Routing; using EmbedIO.Routing;
using EmbedIO.WebApi; using EmbedIO.WebApi;
using Penumbra.Mods;
namespace Penumbra.API namespace Penumbra.API
{ {
@ -14,7 +15,8 @@ namespace Penumbra.API
[Route( HttpVerbs.Get, "/mods" )] [Route( HttpVerbs.Get, "/mods" )]
public object GetMods() public object GetMods()
{ {
return _plugin.ModManager.Mods.ModSettings.Select( x => new var modManager = Service< ModManager >.Get();
return modManager.Mods.ModSettings.Select( x => new
{ {
x.Enabled, x.Enabled,
x.Priority, x.Priority,
@ -28,7 +30,8 @@ namespace Penumbra.API
[Route( HttpVerbs.Get, "/files" )] [Route( HttpVerbs.Get, "/files" )]
public object CreateMod() public object CreateMod()
{ {
return _plugin.ModManager.ResolvedFiles.ToDictionary( var modManager = Service< ModManager >.Get();
return modManager.ResolvedFiles.ToDictionary(
o => o.Key, o => o.Key,
o => o.Value.FullName o => o.Value.FullName
); );

View file

@ -112,7 +112,7 @@ namespace Penumbra.Mods
if( settings.Conf == null ) if( settings.Conf == null )
{ {
settings.Conf = new Dictionary< string, int >(); settings.Conf = new Dictionary< string, int >();
_plugin.ModManager.Mods.Save(); Mods.Save();
} }
ProcessModFiles( registeredFiles, mod, settings ); ProcessModFiles( registeredFiles, mod, settings );
@ -162,7 +162,7 @@ namespace Penumbra.Mods
&& settings.Conf[ group.GroupName ] >= group.Options.Count ) && settings.Conf[ group.GroupName ] >= group.Options.Count )
{ {
settings.Conf[ group.GroupName ] = 0; settings.Conf[ group.GroupName ] = 0;
_plugin.ModManager.Mods.Save(); Mods.Save();
setting = 0; setting = 0;
} }

View file

@ -10,6 +10,7 @@
<AssemblyVersion>1.0.0.0</AssemblyVersion> <AssemblyVersion>1.0.0.0</AssemblyVersion>
<OutputPath>bin\$(Configuration)\</OutputPath> <OutputPath>bin\$(Configuration)\</OutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View file

@ -22,8 +22,6 @@ namespace Penumbra
public ResourceLoader ResourceLoader { get; set; } public ResourceLoader ResourceLoader { get; set; }
public ModManager ModManager { get; set; }
public SettingsInterface SettingsInterface { get; set; } public SettingsInterface SettingsInterface { get; set; }
public GameUtils GameUtils { get; set; } public GameUtils GameUtils { get; set; }
@ -41,8 +39,8 @@ namespace Penumbra
GameUtils = new GameUtils( PluginInterface ); GameUtils = new GameUtils( PluginInterface );
ModManager = new ModManager( this ); var modManager = Service< ModManager >.Set( this );
ModManager.DiscoverMods( Configuration.CurrentCollection ); modManager.DiscoverMods( Configuration.CurrentCollection );
ResourceLoader = new ResourceLoader( this ); ResourceLoader = new ResourceLoader( this );
@ -94,7 +92,7 @@ namespace Penumbra
public void Dispose() public void Dispose()
{ {
ModManager?.Dispose(); // ModManager?.Dispose();
PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw; PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw;
@ -115,9 +113,9 @@ namespace Penumbra
{ {
case "reload": case "reload":
{ {
ModManager.DiscoverMods(); Service< ModManager >.Get().DiscoverMods();
PluginInterface.Framework.Gui.Chat.Print( PluginInterface.Framework.Gui.Chat.Print(
$"Reloaded Penumbra mods. You have {ModManager.Mods.ModSettings.Count} mods, {ModManager.Mods.EnabledMods.Length} of which are enabled." $"Reloaded Penumbra mods. You have {Service< ModManager >.Get().Mods.ModSettings.Count} mods, {Service< ModManager >.Get().Mods.EnabledMods.Length} of which are enabled."
); );
break; break;
} }

View file

@ -1,8 +1,10 @@
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Dalamud.Plugin; using Dalamud.Plugin;
using Penumbra.Mods;
using Penumbra.Structs; using Penumbra.Structs;
using Penumbra.Util; using Penumbra.Util;
using Reloaded.Hooks; using Reloaded.Hooks;
@ -129,31 +131,35 @@ namespace Penumbra
PluginLog.Log( "[GetResourceHandler] {0}", gameFsPath ); PluginLog.Log( "[GetResourceHandler] {0}", gameFsPath );
} }
if( Plugin.Configuration.IsEnabled ) var modManager = Service< ModManager >.Get();
if( !Plugin.Configuration.IsEnabled || modManager == null )
{ {
var replacementPath = Plugin.ModManager.ResolveSwappedOrReplacementFilePath( gameFsPath ); return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
}
// path must be < 260 because statically defined array length :( var replacementPath = modManager.ResolveSwappedOrReplacementFilePath( gameFsPath );
if( replacementPath == null || replacementPath.Length >= 260 )
{
return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
}
var cleanPath = replacementPath.Replace( '\\', '/' ); // path must be < 260 because statically defined array length :(
var path = Encoding.ASCII.GetBytes( cleanPath ); if( replacementPath == null || replacementPath.Length >= 260 )
{
return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
}
var bPath = stackalloc byte[path.Length + 1]; var cleanPath = replacementPath.Replace( '\\', '/' );
Marshal.Copy( path, 0, new IntPtr( bPath ), path.Length ); var path = Encoding.ASCII.GetBytes( cleanPath );
pPath = ( char* )bPath;
Crc32.Init(); var bPath = stackalloc byte[path.Length + 1];
Crc32.Update( path ); Marshal.Copy( path, 0, new IntPtr( bPath ), path.Length );
*pResourceHash = Crc32.Checksum; pPath = ( char* )bPath;
Crc32.Init();
Crc32.Update( path );
*pResourceHash = Crc32.Checksum;
#if DEBUG #if DEBUG
PluginLog.Log( "[GetResourceHandler] resolved {GamePath} to {NewPath}", gameFsPath, replacementPath ); PluginLog.Log( "[GetResourceHandler] resolved {GamePath} to {NewPath}", gameFsPath, replacementPath );
#endif #endif
}
return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
} }

60
Penumbra/Service.cs Normal file
View file

@ -0,0 +1,60 @@
using System;
namespace Penumbra
{
/// <summary>
/// Basic service locator
/// </summary>
/// <typeparam name="T">The class you want to store in the service locator</typeparam>
public static class Service< T > where T : class
{
private static T? _object;
static Service()
{
}
public static void Set( T obj )
{
// ReSharper disable once JoinNullCheckWithUsage
if( obj == null )
{
throw new ArgumentNullException( $"{nameof( obj )} is null!" );
}
_object = obj;
}
public static T Set()
{
_object = Activator.CreateInstance< T >();
return _object;
}
public static T Set( params object[] args )
{
var obj = ( T? )Activator.CreateInstance( typeof( T ), args );
// ReSharper disable once JoinNullCheckWithUsage
if( obj == null )
{
throw new Exception( "what he fuc" );
}
_object = obj;
return obj;
}
public static T Get()
{
if( _object == null )
{
throw new InvalidOperationException( $"{nameof( T )} hasn't been registered!" );
}
return _object;
}
}
}

View file

@ -1,5 +1,6 @@
using System.IO; using System.IO;
using System.Numerics; using System.Numerics;
using Penumbra.Mods;
namespace Penumbra.UI namespace Penumbra.UI
{ {
@ -40,7 +41,8 @@ namespace Penumbra.UI
// create the directory if it doesn't exist // create the directory if it doesn't exist
Directory.CreateDirectory( _plugin.Configuration.CurrentCollection ); Directory.CreateDirectory( _plugin.Configuration.CurrentCollection );
_plugin.ModManager.DiscoverMods( _plugin.Configuration.CurrentCollection ); var modManager = Service< ModManager >.Get();
modManager.DiscoverMods( _plugin.Configuration.CurrentCollection );
_menu.EffectiveTab.RebuildFileList( _plugin.Configuration.ShowAdvanced ); _menu.EffectiveTab.RebuildFileList( _plugin.Configuration.ShowAdvanced );
_menu.InstalledTab.Selector.ResetModNamesLower(); _menu.InstalledTab.Selector.ResetModNamesLower();
} }

View file

@ -11,13 +11,12 @@ namespace Penumbra.UI
private const string LabelTab = "Effective File List"; private const string LabelTab = "Effective File List";
private const float TextSizePadding = 5f; private const float TextSizePadding = 5f;
private readonly ModManager _mods; private ModManager _mods => Service< ModManager >.Get();
private (string, string)[] _fileList; private (string, string)[] _fileList;
private float _maxGamePath; private float _maxGamePath;
public TabEffective( SettingsInterface ui ) public TabEffective( SettingsInterface ui )
{ {
_mods = ui._plugin.ModManager;
RebuildFileList( ui._plugin.Configuration.ShowAdvanced ); RebuildFileList( ui._plugin.Configuration.ShowAdvanced );
} }

View file

@ -1,4 +1,5 @@
using ImGuiNET; using ImGuiNET;
using Penumbra.Mods;
namespace Penumbra.UI namespace Penumbra.UI
{ {
@ -37,7 +38,7 @@ namespace Penumbra.UI
return; return;
} }
if( _base._plugin.ModManager.Mods != null ) if( Service< ModManager >.Get().Mods != null )
{ {
Selector.Draw(); Selector.Draw();
ImGui.SameLine(); ImGui.SameLine();

View file

@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ImGuiNET; using ImGuiNET;
using Penumbra.Models; using Penumbra.Models;
using Penumbra.Mods;
namespace Penumbra.UI namespace Penumbra.UI
{ {
@ -127,8 +128,9 @@ namespace Penumbra.UI
private void Save() private void Save()
{ {
_base._plugin.ModManager.Mods.Save(); var modManager = Service< ModManager >.Get();
_base._plugin.ModManager.CalculateEffectiveFileList(); modManager.Mods.Save();
modManager.CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
} }

View file

@ -4,6 +4,7 @@ using System.Numerics;
using Dalamud.Plugin; using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
using Penumbra.Models; using Penumbra.Models;
using Penumbra.Mods;
namespace Penumbra.UI namespace Penumbra.UI
{ {
@ -184,8 +185,9 @@ namespace Penumbra.UI
if( ImGui.Checkbox( LabelModEnabled, ref enabled ) ) if( ImGui.Checkbox( LabelModEnabled, ref enabled ) )
{ {
Mod.Enabled = enabled; Mod.Enabled = enabled;
_base._plugin.ModManager.Mods.Save(); var modManager = Service< ModManager >.Get();
_base._plugin.ModManager.CalculateEffectiveFileList(); modManager.Mods.Save();
modManager.CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
} }
} }
@ -241,7 +243,7 @@ namespace Penumbra.UI
new Deduplicator( Mod.Mod.ModBasePath, Meta ).Run(); new Deduplicator( Mod.Mod.ModBasePath, Meta ).Run();
_selector.SaveCurrentMod(); _selector.SaveCurrentMod();
Mod.Mod.RefreshModFiles(); Mod.Mod.RefreshModFiles();
_base._plugin.ModManager.CalculateEffectiveFileList(); Service< ModManager >.Get().CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
} }

View file

@ -32,7 +32,7 @@ namespace Penumbra.UI
private static readonly string ArrowDownString = FontAwesomeIcon.ArrowDown.ToIconString(); private static readonly string ArrowDownString = FontAwesomeIcon.ArrowDown.ToIconString();
private readonly SettingsInterface _base; private readonly SettingsInterface _base;
private ModCollection Mods => _base._plugin.ModManager.Mods; private ModCollection Mods => Service< ModManager >.Get().Mods;
private ModInfo _mod; private ModInfo _mod;
private int _index; private int _index;
@ -60,7 +60,7 @@ namespace Penumbra.UI
if( ImGui.Button( iconString, SelectorButtonSizes ) ) if( ImGui.Button( iconString, SelectorButtonSizes ) )
{ {
SetSelection( _index ); SetSelection( _index );
_base._plugin.ModManager.ChangeModPriority( _mod, up ); Service< ModManager >.Get().ChangeModPriority( _mod, up );
_modNamesLower.Swap( _index, _index + ( up ? 1 : -1 ) ); _modNamesLower.Swap( _index, _index + ( up ? 1 : -1 ) );
_index += up ? 1 : -1; _index += up ? 1 : -1;
} }
@ -177,7 +177,7 @@ namespace Penumbra.UI
if( ImGui.Button( ButtonYesDelete ) ) if( ImGui.Button( ButtonYesDelete ) )
{ {
ImGui.CloseCurrentPopup(); ImGui.CloseCurrentPopup();
_base._plugin.ModManager.DeleteMod( _mod.Mod ); Service< ModManager >.Get().DeleteMod( _mod.Mod );
ClearSelection(); ClearSelection();
_base.ReloadMods(); _base.ReloadMods();
} }
@ -321,7 +321,7 @@ namespace Penumbra.UI
} }
_mod.Mod.RefreshModFiles(); _mod.Mod.RefreshModFiles();
_base._plugin.ModManager.CalculateEffectiveFileList(); Service< ModManager >.Get().CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced ); _base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
ResetModNamesLower(); ResetModNamesLower();
} }