Remove some warnings about nullable.

This commit is contained in:
Ottermandias 2021-02-21 16:08:08 +01:00
parent 3f9d97f65f
commit ef2f2cff5c
26 changed files with 330 additions and 352 deletions

View file

@ -13,10 +13,10 @@ namespace Penumbra.API
public ModsController( Plugin plugin ) => _plugin = plugin;
[Route( HttpVerbs.Get, "/mods" )]
public object GetMods()
public object? GetMods()
{
var modManager = Service< ModManager >.Get();
return modManager.Mods.ModSettings.Select( x => new
return modManager.Mods?.ModSettings.Select( x => new
{
x.Enabled,
x.Priority,

View file

@ -27,7 +27,7 @@ namespace Penumbra
// the below exist just to make saving less cumbersome
[NonSerialized]
private DalamudPluginInterface _pluginInterface;
private DalamudPluginInterface? _pluginInterface;
public void Initialize( DalamudPluginInterface pluginInterface )
{
@ -36,7 +36,7 @@ namespace Penumbra
public void Save()
{
_pluginInterface.SavePluginConfig( this );
_pluginInterface?.SavePluginConfig( this );
}
}
}

View file

@ -38,12 +38,12 @@ namespace Penumbra.Hooks
uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown );
// Hooks
public IHook< GetResourceSyncPrototype > GetResourceSyncHook { get; private set; }
public IHook< GetResourceAsyncPrototype > GetResourceAsyncHook { get; private set; }
public IHook< ReadSqpackPrototype > ReadSqpackHook { get; private set; }
public IHook< GetResourceSyncPrototype >? GetResourceSyncHook { get; private set; }
public IHook< GetResourceAsyncPrototype >? GetResourceAsyncHook { get; private set; }
public IHook< ReadSqpackPrototype >? ReadSqpackHook { get; private set; }
// Unmanaged functions
public ReadFilePrototype ReadFile { get; private set; }
public ReadFilePrototype? ReadFile { get; private set; }
public bool LogAllFiles = false;
@ -57,7 +57,7 @@ namespace Penumbra.Hooks
public unsafe void Init()
{
var scanner = Plugin.PluginInterface.TargetModuleScanner;
var scanner = Plugin!.PluginInterface!.TargetModuleScanner;
var readFileAddress =
scanner.ScanText( "E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3 BA 05" );
@ -108,9 +108,24 @@ namespace Penumbra.Hooks
char* pPath,
void* pUnknown,
bool isUnknown
) => isSync
? GetResourceSyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown )
: GetResourceAsyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
)
{
if( isSync )
{
if( GetResourceSyncHook == null )
{
PluginLog.Error("[GetResourceHandler] GetResourceSync is null." );
return null;
}
return GetResourceSyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown );
}
if( GetResourceAsyncHook == null )
{
PluginLog.Error("[GetResourceHandler] GetResourceAsync is null." );
return null;
}
return GetResourceAsyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
}
private unsafe void* GetResourceHandler(
bool isSync,
@ -132,12 +147,12 @@ namespace Penumbra.Hooks
var modManager = Service< ModManager >.Get();
if( !Plugin.Configuration.IsEnabled || modManager == null )
if( !Plugin!.Configuration!.IsEnabled || modManager == null )
{
return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
}
var replacementPath = modManager.ResolveSwappedOrReplacementFilePath( gameFsPath );
var replacementPath = modManager.ResolveSwappedOrReplacementFilePath( gameFsPath! );
// path must be < 260 because statically defined array length :(
if( replacementPath == null || replacementPath.Length >= 260 )
@ -170,9 +185,9 @@ namespace Penumbra.Hooks
var isRooted = Path.IsPathRooted( gameFsPath );
if( gameFsPath == null || gameFsPath.Length >= 260 || !isRooted )
if( gameFsPath == null || gameFsPath.Length >= 260 || !isRooted || ReadFile == null)
{
return ReadSqpackHook.OriginalFunction( pFileHandler, pFileDesc, priority, isSync );
return ReadSqpackHook?.OriginalFunction( pFileHandler, pFileDesc, priority, isSync ) ?? 0;
}
#if DEBUG
@ -201,6 +216,12 @@ namespace Penumbra.Hooks
return;
}
if( ReadSqpackHook == null || GetResourceSyncHook == null || GetResourceAsyncHook == null)
{
PluginLog.Error("[GetResourceHandler] Could not activate hooks because at least one was not set." );
return;
}
ReadSqpackHook.Activate();
GetResourceSyncHook.Activate();
GetResourceAsyncHook.Activate();
@ -208,7 +229,7 @@ namespace Penumbra.Hooks
ReadSqpackHook.Enable();
GetResourceSyncHook.Enable();
GetResourceAsyncHook.Enable();
IsEnabled = true;
}
@ -219,23 +240,16 @@ namespace Penumbra.Hooks
return;
}
ReadSqpackHook.Disable();
GetResourceSyncHook.Disable();
GetResourceAsyncHook.Disable();
ReadSqpackHook?.Disable();
GetResourceSyncHook?.Disable();
GetResourceAsyncHook?.Disable();
IsEnabled = false;
}
public void Dispose()
{
if( IsEnabled )
{
Disable();
}
// ReadSqpackHook.Disable();
// GetResourceSyncHook.Disable();
// GetResourceAsyncHook.Disable();
Disable();
}
}
}

View file

@ -13,7 +13,7 @@ namespace Penumbra.Hooks
public SoundShit( Plugin plugin )
{
var scanner = plugin.PluginInterface.TargetModuleScanner;
var scanner = plugin!.PluginInterface!.TargetModuleScanner;
var fw = plugin.PluginInterface.Framework.Address.BaseAddress;

View file

@ -5,36 +5,36 @@ namespace Penumbra.Importer.Models
{
internal class OptionList
{
public string Name { get; set; }
public string Description { get; set; }
public string ImagePath { get; set; }
public List< SimpleMod > ModsJsons { get; set; }
public string GroupName { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? ImagePath { get; set; }
public List< SimpleMod >? ModsJsons { get; set; }
public string? GroupName { get; set; }
public SelectType SelectionType { get; set; }
public bool IsChecked { get; set; }
}
internal class ModGroup
{
public string GroupName { get; set; }
public string? GroupName { get; set; }
public SelectType SelectionType { get; set; }
public List< OptionList > OptionList { get; set; }
public List< OptionList >? OptionList { get; set; }
}
internal class ModPackPage
{
public int PageIndex { get; set; }
public List< ModGroup > ModGroups { get; set; }
public List< ModGroup >? ModGroups { get; set; }
}
internal class ExtendedModPack
{
public string TTMPVersion { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Version { get; set; }
public string Description { get; set; }
public List< ModPackPage > ModPackPages { get; set; }
public List< SimpleMod > SimpleModsList { get; set; }
public string? TTMPVersion { get; set; }
public string? Name { get; set; }
public string? Author { get; set; }
public string? Version { get; set; }
public string? Description { get; set; }
public List< ModPackPage >? ModPackPages { get; set; }
public List< SimpleMod >? SimpleModsList { get; set; }
}
}

View file

@ -4,22 +4,22 @@ namespace Penumbra.Importer.Models
{
internal class SimpleModPack
{
public string TTMPVersion { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Version { get; set; }
public string Description { get; set; }
public List< SimpleMod > SimpleModsList { get; set; }
public string? TTMPVersion { get; set; }
public string? Name { get; set; }
public string? Author { get; set; }
public string? Version { get; set; }
public string? Description { get; set; }
public List< SimpleMod >? SimpleModsList { get; set; }
}
internal class SimpleMod
{
public string Name { get; set; }
public string Category { get; set; }
public string FullPath { get; set; }
public string? Name { get; set; }
public string? Category { get; set; }
public string? FullPath { get; set; }
public long ModOffset { get; set; }
public long ModSize { get; set; }
public string DatFile { get; set; }
public object ModPackEntry { get; set; }
public string? DatFile { get; set; }
public object? ModPackEntry { get; set; }
}
}

View file

@ -38,7 +38,7 @@ namespace Penumbra.Importer
}
}
public string CurrentModPack { get; private set; }
public string? CurrentModPack { get; private set; }
public TexToolsImport( DirectoryInfo outDirectory )
{
@ -145,6 +145,12 @@ namespace Penumbra.Importer
{
var modList = JsonConvert.DeserializeObject< SimpleModPack >( modRaw );
if( modList?.TTMPVersion == null )
{
PluginLog.Error( "Could not extract V2 Modpack. No version given." );
return;
}
if( modList.TTMPVersion.EndsWith( "s" ) )
{
ImportSimpleV2ModPack( extractedModPack, modList );
@ -164,11 +170,11 @@ namespace Penumbra.Importer
// Create a new ModMeta from the TTMP modlist info
var modMeta = new ModMeta
{
Author = modList.Author,
Name = modList.Name,
Author = modList.Author ?? "Unknown",
Name = modList.Name ?? "New Mod",
Description = string.IsNullOrEmpty( modList.Description )
? "Mod imported from TexTools mod pack"
: modList.Description
: modList.Description!
};
// Open the mod data file from the modpack as a SqPackStream
@ -181,7 +187,7 @@ namespace Penumbra.Importer
File.WriteAllText( Path.Combine( newModFolder.FullName, "meta.json" ),
JsonConvert.SerializeObject( modMeta ) );
ExtractSimpleModList( newModFolder, modList.SimpleModsList, modData );
ExtractSimpleModList( newModFolder, modList.SimpleModsList ?? Enumerable.Empty< SimpleMod >(), modData );
}
private void ImportExtendedV2ModPack( ZipFile extractedModPack, string modRaw )
@ -193,12 +199,12 @@ namespace Penumbra.Importer
// Create a new ModMeta from the TTMP modlist info
var modMeta = new ModMeta
{
Author = modList.Author,
Name = modList.Name,
Author = modList.Author ?? "Unknown",
Name = modList.Name ?? "New Mod",
Description = string.IsNullOrEmpty( modList.Description )
? "Mod imported from TexTools mod pack"
: modList.Description,
Version = modList.Version
: modList.Description ?? "",
Version = modList.Version ?? ""
};
// Open the mod data file from the modpack as a SqPackStream
@ -222,13 +228,14 @@ namespace Penumbra.Importer
}
// Iterate through all pages
foreach( var group in modList.ModPackPages.SelectMany( page => page.ModGroups ) )
foreach( var group in modList.ModPackPages.SelectMany( page => page.ModGroups )
.Where( group => group.GroupName != null && group.OptionList != null ) )
{
var groupFolder = new DirectoryInfo( Path.Combine( newModFolder.FullName, group.GroupName.ReplaceInvalidPathSymbols() ) );
foreach( var option in group.OptionList )
var groupFolder = new DirectoryInfo( Path.Combine( newModFolder.FullName, group.GroupName!.ReplaceInvalidPathSymbols() ) );
foreach( var option in group.OptionList!.Where( option => option.Name != null && option.ModsJsons != null ) )
{
var optionFolder = new DirectoryInfo( Path.Combine( groupFolder.FullName, option.Name.ReplaceInvalidPathSymbols() ) );
ExtractSimpleModList( optionFolder, option.ModsJsons, modData );
var optionFolder = new DirectoryInfo( Path.Combine( groupFolder.FullName, option.Name!.ReplaceInvalidPathSymbols() ) );
ExtractSimpleModList( optionFolder, option.ModsJsons!, modData );
}
AddMeta( newModFolder, groupFolder, group, modMeta );
@ -242,21 +249,21 @@ namespace Penumbra.Importer
private static void AddMeta( DirectoryInfo baseFolder, DirectoryInfo groupFolder, ModGroup group, ModMeta meta )
{
var Inf = new InstallerInfo
var inf = new InstallerInfo
{
SelectionType = group.SelectionType,
GroupName = group.GroupName,
GroupName = group.GroupName!,
Options = new List< Option >()
};
foreach( var opt in group.OptionList )
foreach( var opt in group.OptionList! )
{
var option = new Option
{
OptionName = opt.Name,
OptionDesc = string.IsNullOrEmpty( opt.Description ) ? "" : opt.Description,
OptionName = opt.Name!,
OptionDesc = string.IsNullOrEmpty( opt.Description ) ? "" : opt.Description!,
OptionFiles = new Dictionary< string, HashSet< string > >()
};
var optDir = new DirectoryInfo( Path.Combine( groupFolder.FullName, opt.Name.ReplaceInvalidPathSymbols() ) );
var optDir = new DirectoryInfo( Path.Combine( groupFolder.FullName, opt.Name!.ReplaceInvalidPathSymbols() ) );
if( optDir.Exists )
{
foreach( var file in optDir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
@ -266,10 +273,10 @@ namespace Penumbra.Importer
}
}
Inf.Options.Add( option );
inf.Options.Add( option );
}
meta.Groups.Add( group.GroupName, Inf );
meta.Groups.Add( group.GroupName!, inf );
}
private void ImportMetaModPack( FileInfo file )

View file

@ -12,14 +12,14 @@ namespace Penumbra.Models
private readonly DirectoryInfo _baseDir;
private readonly int _baseDirLength;
private readonly ModMeta _mod;
private SHA256 _hasher;
private SHA256? _hasher;
private readonly Dictionary< long, List< FileInfo > > _filesBySize = new();
private ref SHA256 Sha()
private SHA256 Sha()
{
_hasher ??= SHA256.Create();
return ref _hasher;
return _hasher;
}
public Deduplicator( DirectoryInfo baseDir, ModMeta mod )

View file

@ -14,7 +14,7 @@ namespace Penumbra.Models
public string OptionName;
public string OptionDesc;
[JsonProperty( ItemConverterType = typeof( SingleOrArrayConverter< string > ) )]
[JsonProperty( ItemConverterType = typeof( Util.SingleOrArrayConverter< string > ) )]
public Dictionary< string, HashSet< string > > OptionFiles;
public bool AddFile( string filePath, string gamePath )

View file

@ -6,10 +6,13 @@ namespace Penumbra.Models
{
public class ModInfo
{
public string FolderName { get; set; }
public ModInfo( ResourceMod mod )
=> Mod = mod;
public string FolderName { get; set; } = "";
public bool Enabled { get; set; }
public int Priority { get; set; }
public Dictionary< string, int > Conf { get; set; }
public Dictionary< string, int > Conf { get; set; } = new();
[JsonIgnore]
public ResourceMod Mod { get; set; }

View file

@ -9,13 +9,13 @@ namespace Penumbra.Models
public class ModMeta
{
public uint FileVersion { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Description { get; set; }
public string Name { get; set; } = "Mod";
public string Author { get; set; } = "";
public string Description { get; set; } = "";
public string Version { get; set; }
public string Version { get; set; } = "";
public string Website { get; set; }
public string Website { get; set; } = "";
public List< string > ChangedItems { get; set; } = new();
@ -26,14 +26,12 @@ namespace Penumbra.Models
[JsonIgnore]
public bool HasGroupWithConfig { get; set; } = false;
public static ModMeta LoadFromFile( string filePath )
public static ModMeta? LoadFromFile( string filePath )
{
try
{
var meta = JsonConvert.DeserializeObject< ModMeta >( File.ReadAllText( filePath ) );
meta.HasGroupWithConfig =
meta.Groups != null
&& meta.Groups.Count > 0
meta.HasGroupWithConfig = meta.Groups.Count > 0
&& meta.Groups.Values.Any( G => G.SelectionType == SelectType.Multi || G.Options.Count > 1 );
return meta;

View file

@ -12,11 +12,12 @@ namespace Penumbra.Mods
{
private readonly DirectoryInfo _basePath;
public List< ModInfo > ModSettings { get; set; }
public ResourceMod[] EnabledMods { get; set; }
public List< ModInfo >? ModSettings { get; set; }
public ResourceMod[]? EnabledMods { get; set; }
public ModCollection( DirectoryInfo basePath ) => _basePath = basePath;
public ModCollection( DirectoryInfo basePath )
=> _basePath = basePath;
public void Load( bool invertOrder = false )
{
@ -61,20 +62,10 @@ namespace Penumbra.Mods
continue;
}
var meta = ModMeta.LoadFromFile( metaFile.FullName );
if( meta == null )
{
PluginLog.LogError( "mod meta is invalid for resource mod: {ResourceModFile}", metaFile.FullName );
continue;
}
var meta = ModMeta.LoadFromFile( metaFile.FullName ) ?? new ModMeta();
var mod = new ResourceMod
{
Meta = meta,
ModBasePath = modDir
};
var modEntry = FindOrCreateModSettings( mod );
var mod = new ResourceMod( meta, modDir );
FindOrCreateModSettings( mod );
foundMods.Add( modDir.Name );
mod.RefreshModFiles();
}
@ -142,9 +133,9 @@ namespace Penumbra.Mods
}
public ModInfo FindModSettings( string name )
public ModInfo? FindModSettings( string name )
{
var settings = ModSettings.FirstOrDefault(
var settings = ModSettings?.FirstOrDefault(
x => string.Equals( x.FolderName, name, StringComparison.InvariantCultureIgnoreCase )
);
#if DEBUG
@ -155,18 +146,17 @@ namespace Penumbra.Mods
public ModInfo AddModSettings( ResourceMod mod )
{
var entry = new ModInfo
var entry = new ModInfo(mod)
{
Priority = ModSettings.Count,
Priority = ModSettings?.Count ?? 0,
FolderName = mod.ModBasePath.Name,
Enabled = true,
Mod = mod
};
#if DEBUG
PluginLog.Information( "creating mod settings {ModName}", entry.FolderName );
#endif
ModSettings ??= new List< ModInfo >();
ModSettings.Add( entry );
return entry;
}
@ -174,19 +164,20 @@ namespace Penumbra.Mods
public ModInfo FindOrCreateModSettings( ResourceMod mod )
{
var settings = FindModSettings( mod.ModBasePath.Name );
if( settings != null )
if( settings == null )
{
settings.Mod = mod;
return settings;
return AddModSettings( mod );
}
return AddModSettings( mod );
settings.Mod = mod;
return settings;
}
public IEnumerable< ModInfo > GetOrderedAndEnabledModSettings( bool invertOrder = false )
{
var query = ModSettings
.Where( x => x.Enabled );
var query = ModSettings?
.Where( x => x.Enabled ) ?? Enumerable.Empty<ModInfo>();
if( !invertOrder )
{

View file

@ -13,11 +13,11 @@ namespace Penumbra.Mods
public readonly Dictionary< string, FileInfo > ResolvedFiles = new();
public readonly Dictionary< string, string > SwappedFiles = new();
public ModCollection Mods { get; set; }
public ModCollection? Mods { get; set; }
private DirectoryInfo? _basePath;
private DirectoryInfo _basePath;
public ModManager( Plugin plugin ) => _plugin = plugin;
public ModManager( Plugin plugin )
=> _plugin = plugin;
public void DiscoverMods()
{
@ -104,31 +104,26 @@ namespace Penumbra.Mods
ResolvedFiles.Clear();
SwappedFiles.Clear();
if( Mods == null )
{
return;
}
var registeredFiles = new Dictionary< string, string >();
foreach( var (mod, settings) in Mods.GetOrderedAndEnabledModListWithSettings( _plugin.Configuration.InvertModListOrder ) )
foreach( var (mod, settings) in Mods.GetOrderedAndEnabledModListWithSettings( _plugin!.Configuration!.InvertModListOrder ) )
{
mod.FileConflicts?.Clear();
if( settings.Conf == null )
{
settings.Conf = new Dictionary< string, int >();
Mods.Save();
}
mod.FileConflicts.Clear();
ProcessModFiles( registeredFiles, mod, settings );
ProcessSwappedFiles( registeredFiles, mod, settings );
}
_plugin.GameUtils.ReloadPlayerResources();
_plugin!.GameUtils!.ReloadPlayerResources();
}
private void ProcessSwappedFiles( Dictionary< string, string > registeredFiles, ResourceMod mod, ModInfo settings )
{
if( mod?.Meta?.FileSwaps == null )
{
return;
}
foreach( var swap in mod.Meta.FileSwaps )
{
// just assume people put not fucked paths in here lol
@ -162,7 +157,7 @@ namespace Penumbra.Mods
&& settings.Conf[ group.GroupName ] >= group.Options.Count )
{
settings.Conf[ group.GroupName ] = 0;
Mods.Save();
Mods!.Save();
setting = 0;
}
@ -240,13 +235,13 @@ namespace Penumbra.Mods
public void ChangeModPriority( ModInfo info, bool up = false )
{
Mods.ReorderMod( info, up );
Mods!.ReorderMod( info, up );
CalculateEffectiveFileList();
}
public void DeleteMod( ResourceMod mod )
public void DeleteMod( ResourceMod? mod )
{
if( mod?.ModBasePath?.Exists ?? false )
if( mod?.ModBasePath.Exists ?? false )
{
try
{
@ -261,7 +256,7 @@ namespace Penumbra.Mods
DiscoverMods();
}
public FileInfo GetCandidateForGameFile( string gameResourcePath )
public FileInfo? GetCandidateForGameFile( string gameResourcePath )
{
var val = ResolvedFiles.TryGetValue( gameResourcePath, out var candidate );
if( !val )
@ -277,10 +272,10 @@ namespace Penumbra.Mods
return candidate;
}
public string GetSwappedFilePath( string gameResourcePath )
public string? GetSwappedFilePath( string gameResourcePath )
=> SwappedFiles.TryGetValue( gameResourcePath, out var swappedPath ) ? swappedPath : null;
public string ResolveSwappedOrReplacementFilePath( string gameResourcePath )
public string? ResolveSwappedOrReplacementFilePath( string gameResourcePath )
{
gameResourcePath = gameResourcePath.ToLowerInvariant();

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Dalamud.Plugin;
using Penumbra.Models;
@ -7,6 +8,12 @@ namespace Penumbra.Mods
{
public class ResourceMod
{
public ResourceMod( ModMeta meta, DirectoryInfo dir )
{
Meta = meta;
ModBasePath = dir;
}
public ModMeta Meta { get; set; }
public DirectoryInfo ModBasePath { get; set; }
@ -17,26 +24,13 @@ namespace Penumbra.Mods
public void RefreshModFiles()
{
if( ModBasePath == null )
{
PluginLog.LogError( "no basepath has been set on {ResourceModName}", Meta.Name );
return;
}
ModFiles.Clear();
// we don't care about any _files_ in the root dir, but any folders should be a game folder/file combo
foreach( var dir in ModBasePath.EnumerateDirectories() )
foreach( var file in ModBasePath.EnumerateDirectories()
.SelectMany( dir => dir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) ) )
{
foreach( var file in dir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
{
ModFiles.Add( file );
}
ModFiles.Add( file );
}
// Only add if not in a sub-folder, otherwise it was already added.
//foreach( var pair in Meta.Groups.FileToGameAndGroup )
// if (pair.Key.IndexOfAny(new[]{'/', '\\'}) < 0)
// ModFiles.Add( new FileInfo(Path.Combine(ModBasePath.FullName, pair.Key)) );
}
public void AddConflict( string modName, string path )

View file

@ -13,24 +13,25 @@ namespace Penumbra
{
public class Plugin : IDalamudPlugin
{
public string Name => "Penumbra";
public string Name { get; }
public string PluginDebugTitleStr { get; }
public Plugin()
{
Name = "Penumbra";
PluginDebugTitleStr = $"{Name} - Debug Build";
}
private const string CommandName = "/penumbra";
public DalamudPluginInterface PluginInterface { get; set; }
public DalamudPluginInterface? PluginInterface { get; set; }
public Configuration? Configuration { get; set; }
public ResourceLoader? ResourceLoader { get; set; }
public SettingsInterface? SettingsInterface { get; set; }
public GameUtils? GameUtils { get; set; }
public SoundShit? SoundShit { get; set; }
public Configuration Configuration { get; set; }
public ResourceLoader ResourceLoader { get; set; }
public SettingsInterface SettingsInterface { get; set; }
public GameUtils GameUtils { get; set; }
public SoundShit SoundShit { get; set; }
public string PluginDebugTitleStr { get; private set; }
private WebServer _webServer;
private WebServer? _webServer;
public void Initialize( DalamudPluginInterface pluginInterface )
{
@ -61,8 +62,6 @@ namespace Penumbra
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
PluginDebugTitleStr = $"{Name} - Debug Build";
if( Configuration.EnableHttpApi )
{
CreateWebServer();
@ -97,12 +96,12 @@ namespace Penumbra
{
// ModManager?.Dispose();
PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw;
PluginInterface!.UiBuilder.OnBuildUi -= SettingsInterface!.Draw;
PluginInterface.CommandManager.RemoveHandler( CommandName );
PluginInterface.Dispose();
ResourceLoader.Dispose();
ResourceLoader?.Dispose();
ShutdownWebServer();
}
@ -117,8 +116,8 @@ namespace Penumbra
case "reload":
{
Service< ModManager >.Get().DiscoverMods();
PluginInterface.Framework.Gui.Chat.Print(
$"Reloaded Penumbra mods. You have {Service< ModManager >.Get().Mods.ModSettings.Count} mods, {Service< ModManager >.Get().Mods.EnabledMods.Length} of which are enabled."
PluginInterface!.Framework.Gui.Chat.Print(
$"Reloaded Penumbra mods. You have {Service< ModManager >.Get()?.Mods?.ModSettings?.Count ?? 0} mods, {Service< ModManager >.Get()?.Mods?.EnabledMods?.Length ?? 0} of which are enabled."
);
break;
}
@ -126,11 +125,11 @@ namespace Penumbra
{
if( args.Length > 1 )
{
RefreshActors.RedrawSpecific( PluginInterface.ClientState.Actors, string.Join( " ", args.Skip( 1 ) ) );
RefreshActors.RedrawSpecific( PluginInterface!.ClientState.Actors, string.Join( " ", args.Skip( 1 ) ) );
}
else
{
RefreshActors.RedrawAll( PluginInterface.ClientState.Actors );
RefreshActors.RedrawAll( PluginInterface!.ClientState.Actors );
}
break;
@ -140,7 +139,7 @@ namespace Penumbra
return;
}
SettingsInterface.FlipVisibility();
SettingsInterface!.FlipVisibility();
}
}
}

View file

@ -32,7 +32,7 @@ namespace Penumbra.UI
public ManageModsButton( SettingsInterface ui )
{
_base = ui;
_condition = ui._plugin.PluginInterface.ClientState.Condition;
_condition = ui._plugin!.PluginInterface!.ClientState.Condition;
}
public void Draw()

View file

@ -39,7 +39,7 @@ namespace Penumbra.UI
_menu.InstalledTab.Selector.ResetModNamesLower();
_menu.InstalledTab.Selector.ClearSelection();
// create the directory if it doesn't exist
Directory.CreateDirectory( _plugin.Configuration.CurrentCollection );
Directory.CreateDirectory( _plugin!.Configuration!.CurrentCollection );
var modManager = Service< ModManager >.Get();
modManager.DiscoverMods( _plugin.Configuration.CurrentCollection );

View file

@ -64,7 +64,7 @@ namespace Penumbra.UI
_browserTab.Draw();
InstalledTab.Draw();
if( _base._plugin.Configuration.ShowAdvanced )
if( _base._plugin!.Configuration!.ShowAdvanced )
{
EffectiveTab.Draw();
}

View file

@ -12,12 +12,12 @@ namespace Penumbra.UI
private const float TextSizePadding = 5f;
private ModManager _mods => Service< ModManager >.Get();
private (string, string)[] _fileList;
private float _maxGamePath;
private (string, string)[]? _fileList;
private float _maxGamePath;
public TabEffective( SettingsInterface ui )
{
RebuildFileList( ui._plugin.Configuration.ShowAdvanced );
RebuildFileList( ui._plugin!.Configuration!.ShowAdvanced );
}
public void RebuildFileList( bool advanced )
@ -54,7 +54,7 @@ namespace Penumbra.UI
if( ImGui.ListBoxHeader( "##effective_files", AutoFillSize ) )
{
foreach( var file in _fileList )
foreach( var file in _fileList ?? Enumerable.Empty<(string, string)>() )
{
DrawFileLine( file );
}

View file

@ -27,7 +27,7 @@ namespace Penumbra.UI
private bool _isImportRunning = false;
private bool _hasError = false;
private TexToolsImport _texToolsImport = null!;
private TexToolsImport? _texToolsImport;
private readonly SettingsInterface _base;
public TabImport( SettingsInterface ui ) => _base = ui;
@ -59,7 +59,7 @@ namespace Penumbra.UI
try
{
_texToolsImport = new TexToolsImport( new DirectoryInfo( _base._plugin.Configuration.CurrentCollection ) );
_texToolsImport = new TexToolsImport( new DirectoryInfo( _base._plugin!.Configuration!.CurrentCollection ) );
_texToolsImport.ImportModPack( new FileInfo( fileName ) );
PluginLog.Log( $"-> {fileName} OK!" );

View file

@ -11,7 +11,7 @@ namespace Penumbra.UI
// Remove the entry at idx from the list if the new string is empty, otherwise replace it.
public static void RemoveOrChange( this List< string > list, string newString, int idx )
{
if( newString?.Length == 0 )
if( newString.Length == 0 )
{
list.RemoveAt( idx );
}
@ -53,29 +53,31 @@ namespace Penumbra.UI
private const uint ColorYellow = 0xFF00C8C8;
private const uint ColorRed = 0xFF0000C8;
private bool _editMode = false;
private int _selectedGroupIndex = 0;
private InstallerInfo? _selectedGroup = null;
private int _selectedOptionIndex = 0;
private Option? _selectedOption = null;
private (string label, string name)[] _changedItemsList = null;
private float? _fileSwapOffset = null;
private string _currentGamePaths = "";
private bool _editMode = false;
private int _selectedGroupIndex = 0;
private InstallerInfo? _selectedGroup = null;
private int _selectedOptionIndex = 0;
private Option? _selectedOption = null;
private (string label, string name)[]? _changedItemsList = null;
private float? _fileSwapOffset = null;
private string _currentGamePaths = "";
private (string name, bool selected, uint color, string relName)[] _fullFilenameList = null;
private (string name, bool selected, uint color, string relName)[]? _fullFilenameList = null;
private readonly Selector _selector;
private readonly SettingsInterface _base;
private void SelectGroup( int idx )
{
// Not using the properties here because we need it to be not null forgiving in this case.
var numGroups = _selector.Mod()?.Mod.Meta.Groups.Count ?? 0;
_selectedGroupIndex = idx;
if( _selectedGroupIndex >= Meta?.Groups?.Count )
if( _selectedGroupIndex >= numGroups)
{
_selectedGroupIndex = 0;
}
if( Meta?.Groups?.Count > 0 )
if( numGroups > 0 )
{
_selectedGroup = Meta.Groups.ElementAt( _selectedGroupIndex ).Value;
}
@ -123,20 +125,21 @@ namespace Penumbra.UI
ResetState();
}
private ModInfo Mod => _selector.Mod();
private ModMeta Meta => Mod?.Mod?.Meta;
// This is only drawn when we have a mod selected, so we can forgive nulls.
private ModInfo Mod => _selector.Mod()!;
private ModMeta Meta => Mod.Mod.Meta;
private void Save()
{
var modManager = Service< ModManager >.Get();
modManager.Mods.Save();
modManager.Mods?.Save();
modManager.CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
_base._menu.EffectiveTab.RebuildFileList( _base._plugin!.Configuration!.ShowAdvanced );
}
private void DrawAboutTab()
{
if( !_editMode && ( Meta.Description?.Length ?? 0 ) == 0 )
if( !_editMode && Meta.Description.Length == 0 )
{
return;
}
@ -174,13 +177,11 @@ namespace Penumbra.UI
private void DrawChangedItemsTab()
{
if( !_editMode && ( Meta.ChangedItems?.Count ?? 0 ) == 0 )
if( !_editMode && Meta.ChangedItems.Count == 0 )
{
return;
}
Meta.ChangedItems ??= new List< string >();
var flags = _editMode
? ImGuiInputTextFlags.EnterReturnsTrue
: ImGuiInputTextFlags.ReadOnly;
@ -210,15 +211,7 @@ namespace Penumbra.UI
{
if( newItem.Length > 0 )
{
if( Meta.ChangedItems == null )
{
Meta.ChangedItems = new List< string >() { newItem };
}
else
{
Meta.ChangedItems.Add( newItem );
}
Meta.ChangedItems.Add( newItem );
_selector.SaveCurrentMod();
}
}
@ -317,7 +310,7 @@ namespace Penumbra.UI
var len = Mod.Mod.ModBasePath.FullName.Length;
_fullFilenameList = Mod.Mod.ModFiles.Select( F => ( F.FullName, false, ColorGreen, "" ) ).ToArray();
if( Meta.Groups?.Count == 0 )
if( Meta.Groups.Count == 0 )
{
return;
}
@ -369,7 +362,7 @@ namespace Penumbra.UI
if( ImGui.ListBoxHeader( LabelFileListHeader, AutoFillSize ) )
{
UpdateFilenameList();
foreach( var file in _fullFilenameList )
foreach( var file in _fullFilenameList! )
{
ImGui.PushStyleColor( ImGuiCol.Text, file.color );
ImGui.Selectable( file.name );
@ -405,7 +398,7 @@ namespace Penumbra.UI
var changed = false;
for( var i = 0; i < Mod.Mod.ModFiles.Count; ++i )
{
if( !_fullFilenameList[ i ].selected )
if( !_fullFilenameList![ i ].selected )
{
continue;
}
@ -503,7 +496,7 @@ namespace Penumbra.UI
{
void Selectable( uint colorNormal, uint colorReplace )
{
var loc = _fullFilenameList[ idx ].color;
var loc = _fullFilenameList![ idx ].color;
if( loc == colorNormal )
{
loc = colorReplace;
@ -521,7 +514,7 @@ namespace Penumbra.UI
return;
}
var fileName = _fullFilenameList[ idx ].relName;
var fileName = _fullFilenameList![ idx ].relName;
if( ( ( Option )_selectedOption ).OptionFiles.TryGetValue( fileName, out var gamePaths ) )
{
Selectable( 0, ColorGreen );

View file

@ -36,7 +36,7 @@ namespace Penumbra.UI
private bool DrawEditGroupSelector()
{
ImGui.SetNextItemWidth( OptionSelectionWidth );
if( Meta.Groups.Count == 0 )
if( Meta!.Groups.Count == 0 )
{
ImGui.Combo( LabelGroupSelect, ref _selectedGroupIndex, TextNoOptionAvailable, 1 );
return false;
@ -63,7 +63,7 @@ namespace Penumbra.UI
return false;
}
var group = ( InstallerInfo )_selectedGroup;
var group = ( InstallerInfo )_selectedGroup!;
if( ImGui.Combo( LabelOptionSelect, ref _selectedOptionIndex, group.Options.Select( O => O.OptionName ).ToArray(),
group.Options.Count ) )
{
@ -86,7 +86,7 @@ namespace Penumbra.UI
ImGui.SetNextItemWidth( -1 );
if( ImGui.ListBoxHeader( LabelFileListHeader, AutoFillSize - new Vector2( 0, 1.5f * ImGui.GetTextLineHeight() ) ) )
{
for( var i = 0; i < Mod.Mod.ModFiles.Count; ++i )
for( var i = 0; i < Mod!.Mod.ModFiles.Count; ++i )
{
DrawFileAndGamePaths( i );
}
@ -107,9 +107,9 @@ namespace Penumbra.UI
{
var groupName = group.GroupName;
if( ImGuiCustom.BeginFramedGroupEdit( ref groupName )
&& groupName != group.GroupName && !Meta.Groups.ContainsKey( groupName ) )
&& groupName != group.GroupName && !Meta!.Groups.ContainsKey( groupName ) )
{
var oldConf = Mod.Conf[ group.GroupName ];
var oldConf = Mod!.Conf[ group.GroupName ];
Meta.Groups.Remove( group.GroupName );
Mod.Conf.Remove( group.GroupName );
if( groupName.Length > 0 )
@ -142,7 +142,7 @@ namespace Penumbra.UI
private void DrawMultiSelectorEdit( InstallerInfo group )
{
var nameBoxStart = CheckMarkSize;
var flag = Mod.Conf[ group.GroupName ];
var flag = Mod!.Conf[ group.GroupName ];
var modChanged = DrawMultiSelectorEditBegin( group );
@ -194,9 +194,9 @@ namespace Penumbra.UI
{
var groupName = group.GroupName;
if( ImGui.InputText( $"##{groupName}_add", ref groupName, 64, ImGuiInputTextFlags.EnterReturnsTrue )
&& !Meta.Groups.ContainsKey( groupName ) )
&& !Meta!.Groups.ContainsKey( groupName ) )
{
var oldConf = Mod.Conf[ group.GroupName ];
var oldConf = Mod!.Conf[ group.GroupName ];
if( groupName != group.GroupName )
{
Meta.Groups.Remove( group.GroupName );
@ -218,7 +218,7 @@ namespace Penumbra.UI
private float DrawSingleSelectorEdit( InstallerInfo group )
{
var code = Mod.Conf[ group.GroupName ];
var code = Mod!.Conf[ group.GroupName ];
var selectionChanged = false;
var modChanged = false;
if( ImGuiCustom.RenameableCombo( $"##{group.GroupName}", ref code, out var newName,
@ -283,7 +283,7 @@ namespace Penumbra.UI
private void AddNewGroup( string newGroup, SelectType selectType )
{
if( Meta.Groups.ContainsKey( newGroup ) || newGroup.Length <= 0 )
if( Meta!.Groups.ContainsKey( newGroup ) || newGroup.Length <= 0 )
{
return;
}

View file

@ -48,15 +48,15 @@ namespace Penumbra.UI
_base = ui;
_selector = s;
Details = new PluginDetails( _base, _selector );
_currentWebsite = Meta?.Website;
_currentWebsite = Meta?.Website ?? "";
}
private ModInfo Mod => _selector.Mod();
private ModMeta Meta => Mod?.Mod.Meta;
private ModInfo? Mod => _selector.Mod();
private ModMeta? Meta => Mod?.Mod.Meta;
private void DrawName()
{
var name = Meta.Name;
var name = Meta!.Name;
if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 )
&& name.Length > 0 && name != Meta.Name )
{
@ -74,11 +74,11 @@ namespace Penumbra.UI
ImGui.PushStyleVar( ImGuiStyleVar.ItemSpacing, ZeroVector );
ImGui.SameLine();
var version = Meta.Version ?? "";
var version = Meta!.Version;
if( ImGuiCustom.ResizingTextInput( LabelEditVersion, ref version, 16 )
&& version != Meta.Version )
{
Meta.Version = version.Length > 0 ? version : null;
Meta.Version = version;
_selector.SaveCurrentMod();
}
@ -87,7 +87,7 @@ namespace Penumbra.UI
ImGui.PopStyleVar();
ImGui.EndGroup();
}
else if( ( Meta.Version?.Length ?? 0 ) > 0 )
else if( Meta!.Version.Length > 0 )
{
ImGui.Text( $"(Version {Meta.Version})" );
}
@ -99,11 +99,11 @@ namespace Penumbra.UI
ImGui.TextColored( GreyColor, "by" );
ImGui.SameLine();
var author = Meta.Author ?? "";
var author = Meta!.Author;
if( ImGuiCustom.InputOrText( _editMode, LabelEditAuthor, ref author, 64 )
&& author != Meta.Author )
{
Meta.Author = author.Length > 0 ? author : null;
Meta.Author = author;
_selector.SaveCurrentMod();
}
@ -117,15 +117,15 @@ namespace Penumbra.UI
{
ImGui.TextColored( GreyColor, "from" );
ImGui.SameLine();
var website = Meta.Website ?? "";
var website = Meta!.Website;
if( ImGuiCustom.ResizingTextInput( LabelEditWebsite, ref website, 512 )
&& website != Meta.Website )
{
Meta.Website = website.Length > 0 ? website : null;
Meta.Website = website;
_selector.SaveCurrentMod();
}
}
else if( ( Meta.Website?.Length ?? 0 ) > 0 )
else if( Meta!.Website.Length > 0 )
{
if( _currentWebsite != Meta.Website )
{
@ -181,14 +181,14 @@ namespace Penumbra.UI
private void DrawEnabledMark()
{
var enabled = Mod.Enabled;
var enabled = Mod!.Enabled;
if( ImGui.Checkbox( LabelModEnabled, ref enabled ) )
{
Mod.Enabled = enabled;
var modManager = Service< ModManager >.Get();
modManager.Mods.Save();
modManager.Mods!.Save();
modManager.CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
_base._menu.EffectiveTab.RebuildFileList( _base._plugin!.Configuration!.ShowAdvanced );
}
}
@ -201,7 +201,7 @@ namespace Penumbra.UI
{
if( ImGui.Button( ButtonOpenModFolder ) )
{
Process.Start( Mod.Mod.ModBasePath.FullName );
Process.Start( Mod!.Mod.ModBasePath.FullName );
}
if( ImGui.IsItemHovered() )
@ -240,11 +240,11 @@ namespace Penumbra.UI
{
if( ImGui.Button( ButtonDeduplicate ) )
{
new Deduplicator( Mod.Mod.ModBasePath, Meta ).Run();
new Deduplicator( Mod!.Mod.ModBasePath, Meta! ).Run();
_selector.SaveCurrentMod();
Mod.Mod.RefreshModFiles();
Service< ModManager >.Get().CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
_base._menu.EffectiveTab.RebuildFileList( _base._plugin!.Configuration!.ShowAdvanced );
}
if( ImGui.IsItemHovered() )
@ -285,7 +285,7 @@ namespace Penumbra.UI
ImGuiCustom.VerticalDistance( HeaderLineDistance );
DrawEnabledMark();
if( _base._plugin.Configuration.ShowAdvanced )
if( _base._plugin!.Configuration!.ShowAdvanced )
{
ImGui.SameLine();
DrawEditableMark();

View file

@ -3,6 +3,7 @@ using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using ImGuiNET;
using ImGuiScene;
using Newtonsoft.Json;
using Penumbra.Models;
using Penumbra.Mods;
@ -32,13 +33,13 @@ namespace Penumbra.UI
private static readonly string ArrowDownString = FontAwesomeIcon.ArrowDown.ToIconString();
private readonly SettingsInterface _base;
private ModCollection Mods => Service< ModManager >.Get().Mods;
private ModCollection? Mods => Service< ModManager >.Get().Mods;
private ModInfo _mod;
private int _index;
private int? _deleteIndex;
private string _modFilter = "";
private string[] _modNamesLower;
private ModInfo? _mod;
private int _index;
private int? _deleteIndex;
private string _modFilter = "";
private string[]? _modNamesLower;
public Selector( SettingsInterface ui )
@ -49,7 +50,8 @@ namespace Penumbra.UI
public void ResetModNamesLower()
{
_modNamesLower = Mods?.ModSettings?.Select( I => I.Mod.Meta.Name.ToLowerInvariant() ).ToArray() ?? new string[]{};
_modNamesLower = Mods?.ModSettings?.Where(I => I.Mod != null)
.Select( I => I.Mod!.Meta.Name.ToLowerInvariant() ).ToArray() ?? new string[]{};
}
private void DrawPriorityChangeButton( string iconString, bool up, int unavailableWhen )
@ -60,8 +62,8 @@ namespace Penumbra.UI
if( ImGui.Button( iconString, SelectorButtonSizes ) )
{
SetSelection( _index );
Service< ModManager >.Get().ChangeModPriority( _mod, up );
_modNamesLower.Swap( _index, _index + ( up ? 1 : -1 ) );
Service< ModManager >.Get().ChangeModPriority( _mod!, up );
_modNamesLower!.Swap( _index, _index + ( up ? 1 : -1 ) );
_index += up ? 1 : -1;
}
}
@ -77,7 +79,7 @@ namespace Penumbra.UI
if( ImGui.IsItemHovered() )
{
ImGui.SetTooltip(
_base._plugin.Configuration.InvertModListOrder ^ up ? TooltipMoveDown : TooltipMoveUp
_base._plugin!.Configuration!.InvertModListOrder ^ up ? TooltipMoveDown : TooltipMoveUp
);
}
}
@ -139,7 +141,7 @@ namespace Penumbra.UI
DrawPriorityChangeButton( ArrowUpString, false, 0 );
ImGui.SameLine();
DrawPriorityChangeButton( ArrowDownString, true, Mods?.ModSettings.Count - 1 ?? 0 );
DrawPriorityChangeButton( ArrowDownString, true, Mods?.ModSettings?.Count - 1 ?? 0 );
ImGui.SameLine();
DrawModTrashButton();
ImGui.SameLine();
@ -177,7 +179,7 @@ namespace Penumbra.UI
if( ImGui.Button( ButtonYesDelete ) )
{
ImGui.CloseCurrentPopup();
Service< ModManager >.Get().DeleteMod( _mod.Mod );
Service< ModManager >.Get().DeleteMod( _mod?.Mod );
ClearSelection();
_base.ReloadMods();
}
@ -210,44 +212,47 @@ namespace Penumbra.UI
// Inlay selector list
ImGui.BeginChild( LabelSelectorList, new Vector2( SelectorPanelWidth, -ImGui.GetFrameHeightWithSpacing() ), true );
for( var modIndex = 0; modIndex < Mods.ModSettings.Count; modIndex++ )
if( Mods.ModSettings != null )
{
var settings = Mods.ModSettings[ modIndex ];
var modName = settings.Mod.Meta.Name;
if( _modFilter.Length > 0 && !_modNamesLower[ modIndex ].Contains( _modFilter ) )
for( var modIndex = 0; modIndex < Mods.ModSettings.Count; modIndex++ )
{
continue;
}
var settings = Mods.ModSettings[ modIndex ];
var modName = settings.Mod.Meta.Name;
if( _modFilter.Length > 0 && !_modNamesLower![ modIndex ].Contains( _modFilter ) )
{
continue;
}
var changedColour = false;
if( !settings.Enabled )
{
ImGui.PushStyleColor( ImGuiCol.Text, DisabledModColor );
changedColour = true;
}
else if( settings.Mod.FileConflicts.Any() )
{
ImGui.PushStyleColor( ImGuiCol.Text, ConflictingModColor );
changedColour = true;
}
var changedColour = false;
if( !settings.Enabled )
{
ImGui.PushStyleColor( ImGuiCol.Text, DisabledModColor );
changedColour = true;
}
else if( settings.Mod.FileConflicts.Any() )
{
ImGui.PushStyleColor( ImGuiCol.Text, ConflictingModColor );
changedColour = true;
}
#if DEBUG
var selected = ImGui.Selectable(
$"id={modIndex} {modName}",
modIndex == _index
);
var selected = ImGui.Selectable(
$"id={modIndex} {modName}",
modIndex == _index
);
#else
var selected = ImGui.Selectable( modName, modIndex == _index );
var selected = ImGui.Selectable( modName, modIndex == _index );
#endif
if( changedColour )
{
ImGui.PopStyleColor();
}
if( changedColour )
{
ImGui.PopStyleColor();
}
if( selected )
{
SetSelection( modIndex, settings );
if( selected )
{
SetSelection( modIndex, settings );
}
}
}
@ -259,9 +264,9 @@ namespace Penumbra.UI
DrawDeleteModal();
}
public ModInfo Mod() => _mod;
public ModInfo? Mod() => _mod;
private void SetSelection( int idx, ModInfo info )
private void SetSelection( int idx, ModInfo? info )
{
_mod = info;
if( idx != _index )
@ -286,7 +291,7 @@ namespace Penumbra.UI
}
else
{
SetSelection( idx, Mods.ModSettings[ idx ] );
SetSelection( idx, Mods!.ModSettings![ idx ] );
}
}
@ -294,18 +299,8 @@ namespace Penumbra.UI
public void SelectModByName( string name )
{
for( var modIndex = 0; modIndex < Mods.ModSettings.Count; modIndex++ )
{
var mod = Mods.ModSettings[ modIndex ];
if( mod.Mod.Meta.Name != name )
{
continue;
}
SetSelection( modIndex, mod );
return;
}
var idx = Mods?.ModSettings?.FindIndex( mod => mod.Mod.Meta.Name == name ) ?? -1;
SetSelection( idx );
}
private string GetCurrentModMetaFile()
@ -316,18 +311,21 @@ namespace Penumbra.UI
var metaPath = GetCurrentModMetaFile();
if( metaPath.Length > 0 && File.Exists( metaPath ) )
{
_mod.Mod.Meta = ModMeta.LoadFromFile( metaPath ) ?? _mod.Mod.Meta;
_mod!.Mod.Meta = ModMeta.LoadFromFile( metaPath ) ?? _mod.Mod.Meta;
_base._menu.InstalledTab.ModPanel.Details.ResetState();
}
_mod.Mod.RefreshModFiles();
_mod!.Mod.RefreshModFiles();
Service< ModManager >.Get().CalculateEffectiveFileList();
_base._menu.EffectiveTab.RebuildFileList( _base._plugin.Configuration.ShowAdvanced );
_base._menu.EffectiveTab.RebuildFileList( _base._plugin!.Configuration!.ShowAdvanced );
ResetModNamesLower();
}
public string SaveCurrentMod()
{
if( _mod == null )
return "";
var metaPath = GetCurrentModMetaFile();
if( metaPath.Length > 0 )
{

View file

@ -20,13 +20,13 @@ namespace Penumbra.UI
private const string LabelReloadResource = "Reload Player Resource";
private readonly SettingsInterface _base;
private readonly Configuration _config;
private readonly Configuration _config;
private bool _configChanged;
public TabSettings( SettingsInterface ui )
{
_base = ui;
_config = _base._plugin.Configuration;
_config = _base._plugin.Configuration!;
_configChanged = false;
}
@ -64,7 +64,7 @@ namespace Penumbra.UI
{
_config.IsEnabled = enabled;
_configChanged = true;
Game.RefreshActors.RedrawAll( _base._plugin.PluginInterface.ClientState.Actors );
Game.RefreshActors.RedrawAll( _base._plugin!.PluginInterface!.ClientState.Actors );
}
}
@ -131,7 +131,7 @@ namespace Penumbra.UI
{
if( ImGui.Button( LabelReloadResource ) )
{
_base._plugin.GameUtils.ReloadPlayerResources();
_base._plugin!.GameUtils!.ReloadPlayerResources();
}
}

View file

@ -3,46 +3,32 @@ using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class SingleOrArrayConverter< T > : JsonConverter
namespace Penumbra.Util
{
public override bool CanConvert( Type objectType ) => objectType == typeof( HashSet< T > );
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
public class SingleOrArrayConverter< T > : JsonConverter
{
var token = JToken.Load( reader );
return token.Type == JTokenType.Array
? token.ToObject< HashSet< T > >()
: new HashSet< T > { token.ToObject< T >() };
}
public override bool CanConvert( Type objectType ) => objectType == typeof( HashSet< T > );
public override bool CanWrite => false;
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
throw new NotImplementedException();
}
}
public class DictSingleOrArrayConverter< T, U > : JsonConverter
{
public override bool CanConvert( Type objectType ) => objectType == typeof( Dictionary< T, HashSet< U > > );
public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
{
var token = JToken.Load( reader );
if( token.Type == JTokenType.Array )
public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer )
{
return token.ToObject< HashSet< T > >();
var token = JToken.Load( reader );
if( token.Type == JTokenType.Array )
{
return token.ToObject< HashSet< T > >() ?? new HashSet<T>();
}
var tmp = token.ToObject< T >();
return tmp != null
? new HashSet< T > { tmp }
: new HashSet< T >();
}
return new HashSet< T > { token.ToObject< T >() };
}
public override bool CanWrite => false;
public override bool CanWrite => false;
public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer )
{
throw new NotImplementedException();
public override void WriteJson( JsonWriter writer, object? value, JsonSerializer serializer )
{
throw new NotImplementedException();
}
}
}