Browse Source

Updated to use ReSharper

pull/46/head
Anairkoen Schno 6 years ago
parent
commit
6045e31267
64 changed files with 641 additions and 1029 deletions
  1. +0
    -24
      BSIPA.sln
  2. +12
    -0
      BSIPA.sln.DotSettings
  3. +7
    -8
      CollectDependencies/Program.cs
  4. +0
    -1
      CollectDependencies/Properties/AssemblyInfo.cs
  5. +14
    -18
      CollectDependencies/Virtualizer.cs
  6. +2
    -6
      IPA.Injector/Backups/BackupManager.cs
  7. +26
    -32
      IPA.Injector/Backups/BackupUnit.cs
  8. +8
    -8
      IPA.Injector/Bootstrapper.cs
  9. +23
    -25
      IPA.Injector/ConsoleWindow.cs
  10. +0
    -1
      IPA.Injector/IPA.Injector.csproj
  11. +34
    -31
      IPA.Injector/Injector.cs
  12. +22
    -27
      IPA.Injector/LibLoader.cs
  13. +3
    -5
      IPA.Injector/Properties/AssemblyInfo.cs
  14. +2
    -6
      IPA.Injector/Updates.cs
  15. +4
    -10
      IPA.Injector/Virtualizer.cs
  16. +0
    -21
      IPA.Injector/WtfThisDoesntNeedToExist.cs
  17. +16
    -18
      IPA.Loader/Config/ConfigProviders/JsonConfigProvider.cs
  18. +1
    -4
      IPA.Loader/Config/IConfigProvider.cs
  19. +12
    -14
      IPA.Loader/Config/IniFile.cs
  20. +28
    -35
      IPA.Loader/Config/ModPrefs.cs
  21. +4
    -6
      IPA.Loader/IPA.Loader.csproj
  22. +4
    -10
      IPA.Loader/Loader/Composite/CompositeBSPlugin.cs
  23. +7
    -16
      IPA.Loader/Loader/Composite/CompositeIPAPlugin.cs
  24. +7
    -8
      IPA.Loader/Loader/PluginComponent.cs
  25. +29
    -31
      IPA.Loader/Loader/PluginManager.cs
  26. +0
    -4
      IPA.Loader/Logging/LogPrinter.cs
  27. +2
    -5
      IPA.Loader/Logging/Logger.cs
  28. +2
    -8
      IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
  29. +12
    -16
      IPA.Loader/Logging/Printers/GZFilePrinter.cs
  30. +2
    -7
      IPA.Loader/Logging/Printers/GlobalLogFilePrinter.cs
  31. +3
    -8
      IPA.Loader/Logging/Printers/PluginLogFilePrinter.cs
  32. +3
    -8
      IPA.Loader/Logging/Printers/PluginSubLogPrinter.cs
  33. +25
    -29
      IPA.Loader/Logging/StandardLogger.cs
  34. +4
    -16
      IPA.Loader/Logging/UnityLogInterceptor.cs
  35. +3
    -5
      IPA.Loader/PluginInterfaces/BeatSaber/IBeatSaberPlugin.cs
  36. +2
    -4
      IPA.Loader/PluginInterfaces/BeatSaber/IEnhancedBeatSaberPlugin.cs
  37. +10
    -12
      IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs
  38. +2
    -7
      IPA.Loader/PluginInterfaces/IGenericEnhancedPlugin.cs
  39. +2
    -2
      IPA.Loader/PluginInterfaces/IPA/IEnhancedPlugin.cs
  40. +1
    -2
      IPA.Loader/PluginInterfaces/IPA/IPlugin.cs
  41. +0
    -147
      IPA.Loader/Updating/Backup/BackupUnit.cs
  42. +9
    -13
      IPA.Loader/Updating/Converters/ModsaberDependencyConverter.cs
  43. +2
    -4
      IPA.Loader/Updating/Converters/SemverRangeConverter.cs
  44. +2
    -7
      IPA.Loader/Updating/Converters/SemverVersionConverter.cs
  45. +10
    -15
      IPA.Loader/Updating/ModSaber/ApiEndpoint.cs
  46. +65
    -73
      IPA.Loader/Updating/ModSaber/Updater.cs
  47. +2
    -8
      IPA.Loader/Updating/SelfPlugin.cs
  48. +8
    -12
      IPA.Loader/Utilities/BeatSaber.cs
  49. +1
    -9
      IPA.Loader/Utilities/Extensions.cs
  50. +4
    -7
      IPA.Loader/Utilities/LoneFunctions.cs
  51. +6
    -10
      IPA.Loader/Utilities/Ref.cs
  52. +10
    -19
      IPA.Loader/Utilities/ReflectionUtil.cs
  53. +34
    -39
      IPA/Arguments.cs
  54. +4
    -7
      IPA/PatchContext.cs
  55. +7
    -12
      IPA/Patcher/BackupManager.cs
  56. +28
    -31
      IPA/Patcher/BackupUnit.cs
  57. +32
    -27
      IPA/Patcher/Patcher.cs
  58. +11
    -15
      IPA/Patcher/Virtualizer.cs
  59. +50
    -50
      IPA/Program.cs
  60. +2
    -3
      IPA/Properties/AssemblyInfo.cs
  61. +8
    -7
      IPA/Shortcut.cs
  62. +6
    -13
      MSBuildTasks/AssemblyRenameTask.cs
  63. +0
    -1
      MSBuildTasks/Properties/AssemblyInfo.cs
  64. +2
    -2
      appveyor.yml

+ 0
- 24
BSIPA.sln View File

@ -8,8 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA", "IPA\IPA.csproj", "{1
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7} = {2A1AF16B-27F1-46E0-9A95-181516BC1CB7}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA.Tests", "IPA.Tests\IPA.Tests.csproj", "{C66092B0-5C1E-44E9-B524-E0E8E1425379}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSBuildTasks", "MSBuildTasks\MSBuildTasks.csproj", "{F08C3C7A-3221-432E-BAB8-32BCE58408C8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA.Loader", "IPA.Loader\IPA.Loader.csproj", "{5AD344F0-01A0-4CA8-92E5-9D095737744D}"
@ -79,28 +77,6 @@ Global
{14092533-98BB-40A4-9AFC-27BB75672A70}.Verbose|x64.Build.0 = Verbose|Any CPU
{14092533-98BB-40A4-9AFC-27BB75672A70}.Verbose|x86.ActiveCfg = Release|Any CPU
{14092533-98BB-40A4-9AFC-27BB75672A70}.Verbose|x86.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|x64.ActiveCfg = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|x64.Build.0 = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|x86.ActiveCfg = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Debug|x86.Build.0 = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|Any CPU.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|x64.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|x86.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|x86.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose_Release|Any CPU.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose_Release|Any CPU.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose_Release|x64.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose_Release|x86.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose_Release|x86.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|Any CPU.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|Any CPU.Build.0 = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|x64.ActiveCfg = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|x64.Build.0 = Debug|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|x86.ActiveCfg = Release|Any CPU
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Verbose|x86.Build.0 = Release|Any CPU
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Debug|x64.ActiveCfg = Debug|Any CPU


+ 12
- 0
BSIPA.sln.DotSettings View File

@ -0,0 +1,12 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BS/@EntryIndexedValue">BS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IPA/@EntryIndexedValue">IPA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatsaber/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Coroutine/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Modsaber/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Prefs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=unpatch/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Virtualize/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=waitfor/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 7
- 8
CollectDependencies/Program.cs View File

@ -3,12 +3,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CollectDependencies
{
class Program
static class Program
{
static void Main(string[] args)
{
@ -34,7 +32,7 @@ namespace CollectDependencies
return v2;
}
foreach (var line in depsfile.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
foreach (var line in depsfile.Split(new[] { Environment.NewLine }, StringSplitOptions.None))
{
var parts = line.Split('"');
var path = parts.Last();
@ -48,7 +46,7 @@ namespace CollectDependencies
var arglist = string.Join(" ", parts);
if (command == "from")
{ // an "import" type command
path = File.ReadAllText(Path.Combine(fdir, arglist));
path = File.ReadAllText(Path.Combine(fdir ?? throw new InvalidOperationException(), arglist));
}
else if (command == "prompt")
{
@ -85,16 +83,17 @@ namespace CollectDependencies
if (fname == "") continue;
var outp = Path.Combine(fdir, Path.GetFileName(fname));
var outp = Path.Combine(fdir ?? throw new InvalidOperationException(), Path.GetFileName(fname) ?? throw new InvalidOperationException());
Console.WriteLine($"Copying \"{fname}\" to \"{outp}\"");
if (File.Exists(outp)) File.Delete(outp);
if (Path.GetExtension(fname).ToLower() == ".dll")
if (Path.GetExtension(fname)?.ToLower() == ".dll")
{
// ReSharper disable once StringLiteralTypo
if (fparts.Length > 1 && fparts[1] == "virt")
{
var module = VirtualizedModule.Load(fname);
module.Virtualize(fname = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), Path.GetFileName(fname)));
module.Virtualize(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), Path.GetFileName(fname) ?? throw new InvalidOperationException()));
}
var modl = ModuleDefinition.ReadModule(fparts[0]);
foreach (var t in modl.Types)


+ 0
- 1
CollectDependencies/Properties/AssemblyInfo.cs View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following


+ 14
- 18
CollectDependencies/Virtualizer.cs View File

@ -1,18 +1,13 @@
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace CollectDependencies
{
class VirtualizedModule
{
private const string ENTRY_TYPE = "Display";
private FileInfo _File;
private ModuleDefinition _Module;
private readonly FileInfo _file;
private ModuleDefinition _module;
public static VirtualizedModule Load(string engineFile)
{
@ -21,7 +16,7 @@ namespace CollectDependencies
private VirtualizedModule(string assemblyFile)
{
_File = new FileInfo(assemblyFile);
_file = new FileInfo(assemblyFile);
LoadModules();
}
@ -29,29 +24,29 @@ namespace CollectDependencies
private void LoadModules()
{
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(_File.DirectoryName);
resolver.AddSearchDirectory(_file.DirectoryName);
var parameters = new ReaderParameters
{
AssemblyResolver = resolver,
};
_Module = ModuleDefinition.ReadModule(_File.FullName, parameters);
_module = ModuleDefinition.ReadModule(_file.FullName, parameters);
}
/// <summary>
///
/// </summary>
/// <param name="module"></param>
public void Virtualize(string targetfile)
/// <param name="targetFile"></param>
public void Virtualize(string targetFile)
{
foreach (var type in _Module.Types)
foreach (var type in _module.Types)
{
VirtualizeType(type);
}
_Module.Write(targetfile);
_module.Write(targetFile);
}
private void VirtualizeType(TypeDefinition type)
@ -105,10 +100,11 @@ namespace CollectDependencies
{
get
{
var awakeMethods = _Module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake"));
if (awakeMethods.Count() == 0) return false;
var awakeMethods = _module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake"));
var methodDefinitions = awakeMethods as MethodDefinition[] ?? awakeMethods.ToArray();
if (!methodDefinitions.Any()) return false;
return ((float)awakeMethods.Count(m => m.IsVirtual) / awakeMethods.Count()) > 0.5f;
return ((float)methodDefinitions.Count(m => m.IsVirtual) / methodDefinitions.Count()) > 0.5f;
}
}
}


+ 2
- 6
IPA.Injector/Backups/BackupManager.cs View File

@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace IPA.Injector.Backups
{
public class BackupManager
public static class BackupManager
{
public static BackupUnit FindLatestBackup(string dir)
{


+ 26
- 32
IPA.Injector/Backups/BackupUnit.cs View File

@ -1,11 +1,7 @@
using IPA.Logging;
using IPA.Utilities;
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
namespace IPA.Injector.Backups
{
@ -16,11 +12,11 @@ namespace IPA.Injector.Backups
{
public string Name { get; private set; }
private DirectoryInfo _BackupPath;
private HashSet<string> _Files = new HashSet<string>();
private FileInfo _ManifestFile;
private static string _ManifestFileName = "$manifest$.txt";
private readonly DirectoryInfo _backupPath;
private readonly HashSet<string> _files = new HashSet<string>();
private readonly FileInfo _manifestFile;
private const string ManifestFileName = "$manifest$.txt";
public BackupUnit(string dir) : this(dir, DateTime.Now.ToString("yyyy-MM-dd_h-mm-ss"))
{
}
@ -28,8 +24,8 @@ namespace IPA.Injector.Backups
private BackupUnit(string dir, string name)
{
Name = name;
_BackupPath = new DirectoryInfo(Path.Combine(dir, Name));
_ManifestFile = new FileInfo(Path.Combine(_BackupPath.FullName, _ManifestFileName));
_backupPath = new DirectoryInfo(Path.Combine(dir, Name));
_manifestFile = new FileInfo(Path.Combine(_backupPath.FullName, ManifestFileName));
}
public static BackupUnit FromDirectory(DirectoryInfo directory, string dir)
@ -37,19 +33,19 @@ namespace IPA.Injector.Backups
var unit = new BackupUnit(dir, directory.Name);
// Read Manifest
if (unit._ManifestFile.Exists)
if (unit._manifestFile.Exists)
{
string manifest = File.ReadAllText(unit._ManifestFile.FullName);
foreach (var line in manifest.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
unit._Files.Add(line);
var manifest = File.ReadAllText(unit._manifestFile.FullName);
foreach (var line in manifest.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
unit._files.Add(line);
}
else
{
foreach (var file in directory.GetFiles("*", SearchOption.AllDirectories))
{
if (file.Name == _ManifestFileName) continue;
if (file.Name == ManifestFileName) continue;
var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
unit._Files.Add(relativePath);
unit._files.Add(relativePath);
}
}
@ -63,20 +59,20 @@ namespace IPA.Injector.Backups
internal void Delete()
{
_BackupPath.Delete(true);
_backupPath.Delete(true);
}
/// <summary>
/// Adds a file to the list of changed files and backups it.
/// </summary>
/// <param name="path"></param>
/// <param name="file"></param>
public void Add(FileInfo file)
{
var relativePath = LoneFunctions.GetRelativePath(file.FullName, Environment.CurrentDirectory);
var backupPath = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath));
var backupPath = new FileInfo(Path.Combine(_backupPath.FullName, relativePath));
// Copy over
backupPath.Directory.Create();
backupPath.Directory?.Create();
if (file.Exists)
{
if (File.Exists(backupPath.FullName))
@ -89,17 +85,15 @@ namespace IPA.Injector.Backups
backupPath.Create().Close();
}
if (!_Files.Contains(relativePath))
{
if (!File.Exists(_ManifestFile.FullName))
_ManifestFile.Create().Close();
var stream = _ManifestFile.AppendText();
stream.WriteLine(relativePath);
stream.Close();
if (_files.Contains(relativePath)) return;
if (!File.Exists(_manifestFile.FullName))
_manifestFile.Create().Close();
var stream = _manifestFile.AppendText();
stream.WriteLine(relativePath);
stream.Close();
// Add to list
_Files.Add(relativePath);
}
// Add to list
_files.Add(relativePath);
}
}


+ 8
- 8
IPA.Injector/Bootstrapper.cs View File

@ -1,24 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable UnusedMember.Global
namespace IPA.Injector
{
class Bootstrapper : MonoBehaviour
internal class Bootstrapper : MonoBehaviour
{
public event Action Destroyed = delegate {};
void Awake()
public void Awake()
{
}
void Start()
public void Start()
{
Destroy(gameObject);
}
void OnDestroy()
public void OnDestroy()
{
Destroyed();
}


+ 23
- 25
IPA.Injector/ConsoleWindow.cs View File

@ -1,21 +1,19 @@
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace IPA.Injector.Windows
namespace IPA.Injector
{
// https://stackoverflow.com/a/48864902/3117125
static class WinConsole
internal static class WinConsole
{
static public void Initialize(bool alwaysCreateNewConsole = true)
public static void Initialize(bool alwaysCreateNewConsole = true)
{
bool consoleAttached = true;
if (alwaysCreateNewConsole
|| (AttachConsole(ATTACH_PARRENT) == 0
&& Marshal.GetLastWin32Error() != ERROR_ACCESS_DENIED))
|| (AttachConsole(AttachParent) == 0
&& Marshal.GetLastWin32Error() != ErrorAccessDenied))
{
consoleAttached = AllocConsole() != 0;
}
@ -34,7 +32,7 @@ namespace IPA.Injector.Windows
private static void InitializeOutStream()
{
var fs = CreateFileStream("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, FileAccess.Write);
var fs = CreateFileStream("CONOUT$", GenericWrite, FileShareWrite, FileAccess.Write);
if (fs != null)
{
var writer = new StreamWriter(fs) { AutoFlush = true };
@ -45,7 +43,7 @@ namespace IPA.Injector.Windows
private static void InitializeInStream()
{
var fs = CreateFileStream("CONIN$", GENERIC_READ, FILE_SHARE_READ, FileAccess.Read);
var fs = CreateFileStream("CONIN$", GenericRead, FileShareRead, FileAccess.Read);
if (fs != null)
{
Console.SetIn(new StreamReader(fs));
@ -55,7 +53,7 @@ namespace IPA.Injector.Windows
private static FileStream CreateFileStream(string name, uint win32DesiredAccess, uint win32ShareMode,
FileAccess dotNetFileAccess)
{
var file = new SafeFileHandle(CreateFileW(name, win32DesiredAccess, win32ShareMode, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero), true);
var file = new SafeFileHandle(CreateFileW(name, win32DesiredAccess, win32ShareMode, IntPtr.Zero, OpenExisting, FileAttributeNormal, IntPtr.Zero), true);
if (!file.IsInvalid)
{
var fs = new FileStream(file, dotNetFileAccess);
@ -77,7 +75,7 @@ namespace IPA.Injector.Windows
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern UInt32 AttachConsole(UInt32 dwProcessId);
private static extern uint AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll",
EntryPoint = "CreateFileW",
@ -86,23 +84,23 @@ namespace IPA.Injector.Windows
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr CreateFileW(
string lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
private const UInt32 GENERIC_WRITE = 0x40000000;
private const UInt32 GENERIC_READ = 0x80000000;
private const UInt32 FILE_SHARE_READ = 0x00000001;
private const UInt32 FILE_SHARE_WRITE = 0x00000002;
private const UInt32 OPEN_EXISTING = 0x00000003;
private const UInt32 FILE_ATTRIBUTE_NORMAL = 0x80;
private const UInt32 ERROR_ACCESS_DENIED = 5;
private const UInt32 ATTACH_PARRENT = 0xFFFFFFFF;
private const uint GenericWrite = 0x40000000;
private const uint GenericRead = 0x80000000;
private const uint FileShareRead = 0x00000001;
private const uint FileShareWrite = 0x00000002;
private const uint OpenExisting = 0x00000003;
private const uint FileAttributeNormal = 0x80;
private const uint ErrorAccessDenied = 5;
private const uint AttachParent = 0xFFFFFFFF;
#endregion
}

+ 0
- 1
IPA.Injector/IPA.Injector.csproj View File

@ -61,7 +61,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updates.cs" />
<Compile Include="Virtualizer.cs" />
<Compile Include="WtfThisDoesntNeedToExist.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IPA.Loader\IPA.Loader.csproj">


+ 34
- 31
IPA.Injector/Injector.cs View File

@ -1,23 +1,23 @@
using Harmony;
using IPA.Injector.Backups;
using IPA.Injector.Backups;
using IPA.Loader;
using IPA.Logging;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using UnityEngine;
using static IPA.Logging.Logger;
using MethodAttributes = Mono.Cecil.MethodAttributes;
namespace IPA.Injector
{
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public static class Injector
{
// ReSharper disable once UnusedParameter.Global
public static void Main(string[] args)
{ // entry point for doorstop
// At this point, literally nothing but mscorlib is loaded,
@ -28,7 +28,7 @@ namespace IPA.Injector
try
{
if (!Environment.GetCommandLineArgs().Contains("--no-console"))
Windows.WinConsole.Initialize();
WinConsole.Initialize();
SetupLibraryLoading();
@ -96,30 +96,30 @@ namespace IPA.Injector
else
{
var ilp = cctor.Body.GetILProcessor();
for (int i = 0; i < Math.Min(2, cctor.Body.Instructions.Count); i++)
for (var i = 0; i < Math.Min(2, cctor.Body.Instructions.Count); i++)
{
var ins = cctor.Body.Instructions[i];
if (i == 0)
switch (i)
{
if (ins.OpCode != OpCodes.Call)
{
case 0 when ins.OpCode != OpCodes.Call:
ilp.Replace(ins, ilp.Create(OpCodes.Call, cbs));
modified = true;
}
else
break;
case 0:
{
var mref = ins.Operand as MethodReference;
if (mref.FullName != cbs.FullName)
var methodRef = ins.Operand as MethodReference;
if (methodRef?.FullName != cbs.FullName)
{
ilp.Replace(ins, ilp.Create(OpCodes.Call, cbs));
modified = true;
}
break;
}
}
if (i == 1 && ins.OpCode != OpCodes.Ret)
{
ilp.Replace(ins, ilp.Create(OpCodes.Ret));
modified = true;
case 1 when ins.OpCode != OpCodes.Ret:
ilp.Replace(ins, ilp.Create(OpCodes.Ret));
modified = true;
break;
}
}
}
@ -140,11 +140,11 @@ namespace IPA.Injector
#endregion
}
private static bool bootstrapped = false;
private static bool _bootstrapped;
private static void CreateBootstrapper()
{
if (bootstrapped) return;
bootstrapped = true;
if (_bootstrapped) return;
_bootstrapped = true;
Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type)
{
@ -154,30 +154,31 @@ namespace IPA.Injector
};
// need to reinit streams singe Unity seems to redirect stdout
Windows.WinConsole.InitializeStreams();
WinConsole.InitializeStreams();
var bootstrapper = new GameObject("NonDestructiveBootstrapper").AddComponent<Bootstrapper>();
bootstrapper.Destroyed += Bootstrapper_Destroyed;
}
private static bool injected = false;
private static bool _injected;
public static void Inject()
{
if (!injected)
if (!_injected)
{
injected = true;
Windows.WinConsole.Initialize();
_injected = true;
WinConsole.Initialize();
SetupLibraryLoading();
var bootstrapper = new GameObject("Bootstrapper").AddComponent<Bootstrapper>();
bootstrapper.Destroyed += Bootstrapper_Destroyed;
}
}
private static bool loadingDone = false;
public static void SetupLibraryLoading()
private static bool _loadingDone;
private static void SetupLibraryLoading()
{
if (loadingDone) return;
loadingDone = true;
if (_loadingDone) return;
_loadingDone = true;
#region Add Library load locations
AppDomain.CurrentDomain.AssemblyResolve += LibLoader.AssemblyLibLoader;
/*try
@ -191,9 +192,11 @@ namespace IPA.Injector
#endregion
}
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetDllDirectory(string lpPathName);
*/
private static void Bootstrapper_Destroyed()
{


+ 22
- 27
IPA.Injector/LibLoader.cs View File

@ -1,20 +1,17 @@
using IPA.Logging;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using IPA.Logging;
using static IPA.Logging.Logger;
namespace IPA.Injector
{
internal class LibLoader
internal static class LibLoader
{
public static string LibraryPath => Path.Combine(Environment.CurrentDirectory, "Libs");
public static string NativeLibraryPath => Path.Combine(LibraryPath, "Native");
private static Dictionary<string, string> filenameLocations = null;
private static string LibraryPath => Path.Combine(Environment.CurrentDirectory, "Libs");
private static string NativeLibraryPath => Path.Combine(LibraryPath, "Native");
private static Dictionary<string, string> filenameLocations;
public static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
{
@ -29,20 +26,18 @@ namespace IPA.Injector
filenameLocations.Add(fn.Name, fn.FullName);
}
var testFilen = $"{asmName.Name}.{asmName.Version}.dll";
Log(Level.Debug, $"Looking for file {testFilen}");
var testFile = $"{asmName.Name}.{asmName.Version}.dll";
Log(Level.Debug, $"Looking for file {testFile}");
if (filenameLocations.TryGetValue(testFilen, out string path))
if (filenameLocations.TryGetValue(testFile, out string path))
{
Log(Level.Debug, $"Found file {testFilen} as {path}");
Log(Level.Debug, $"Found file {testFile} as {path}");
if (File.Exists(path))
{
return Assembly.LoadFrom(path);
}
else
{
Log(Level.Critical, $"but {path} no longer exists!");
}
Log(Level.Critical, $"but {path} no longer exists!");
}
Log(Level.Critical, $"No library {asmName} found");
@ -67,13 +62,13 @@ namespace IPA.Injector
// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-iterate-through-a-directory-tree
private static IEnumerable<FileInfo> TraverseTree(string root, Func<string, bool> dirValidator = null)
{
if (dirValidator == null) dirValidator = (s) => true;
if (dirValidator == null) dirValidator = s => true;
// Data structure to hold names of subfolders to be
// examined for files.
Stack<string> dirs = new Stack<string>(32);
if (!System.IO.Directory.Exists(root))
if (!Directory.Exists(root))
{
throw new ArgumentException();
}
@ -85,7 +80,7 @@ namespace IPA.Injector
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
subDirs = Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
@ -101,16 +96,16 @@ namespace IPA.Injector
//Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException)
catch (DirectoryNotFoundException)
{
//Console.WriteLine(e.Message);
continue;
}
string[] files = null;
string[] files;
try
{
files = System.IO.Directory.GetFiles(currentDir);
files = Directory.GetFiles(currentDir);
}
catch (UnauthorizedAccessException)
@ -120,7 +115,7 @@ namespace IPA.Injector
continue;
}
catch (System.IO.DirectoryNotFoundException)
catch (DirectoryNotFoundException)
{
//Console.WriteLine(e.Message);
continue;
@ -135,14 +130,14 @@ namespace IPA.Injector
// Modify this block to perform your required task.
foreach (string file in files)
{
FileInfo nextValue = null;
FileInfo nextValue;
try
{
// Perform whatever action is required in your scenario.
nextValue = new System.IO.FileInfo(file);
nextValue = new FileInfo(file);
//Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
}
catch (System.IO.FileNotFoundException)
catch (FileNotFoundException)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()


+ 3
- 5
IPA.Injector/Properties/AssemblyInfo.cs View File

@ -1,5 +1,4 @@
using IPA.Injector;
using System.Reflection;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -23,7 +22,6 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2a1af16b-27f1-46e0-9a95-181516bc1cb7")]
[assembly: InternalsVisibleTo("IPA.Loader")]
[assembly: ForceAssemblyReference(typeof(SemVer.Version))]
// Version information for an assembly consists of the following four values:
//
@ -35,5 +33,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.11.1")] // will be patched by AppVeyor
[assembly: AssemblyFileVersion("3.11.1")] // will be patched by AppVeyor
[assembly: AssemblyVersion("3.11.2")]
[assembly: AssemblyFileVersion("3.11.2")]

+ 2
- 6
IPA.Injector/Updates.cs View File

@ -1,17 +1,13 @@
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static IPA.Logging.Logger;
namespace IPA.Injector
{
class Updates
internal static class Updates
{
public const string DeleteFileName = Updating.ModsaberML.Updater._SpecialDeletionsFile;
private const string DeleteFileName = Updating.ModSaber.Updater.SpecialDeletionsFile;
public static void InstallPendingUpdates()
{
var pendingDir = Path.Combine(BeatSaber.InstallPath, "IPA", "Pending");


+ 4
- 10
IPA.Injector/Virtualizer.cs View File

@ -1,19 +1,14 @@
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IPA.Injector
{
internal class VirtualizedModule
{
private const string ENTRY_TYPE = "Display";
public FileInfo file;
public ModuleDefinition module;
private readonly FileInfo file;
private ModuleDefinition module;
public static VirtualizedModule Load(string engineFile)
{
@ -35,11 +30,10 @@ namespace IPA.Injector
/// <summary>
///
/// </summary>
/// <param name="module"></param>
public void Virtualize(AssemblyName selfName, Action beforeChangeCallback = null)
{
bool changed = false;
bool virtualize = true;
var changed = false;
var virtualize = true;
foreach (var r in module.AssemblyReferences)
{
if (r.Name == selfName.Name)


+ 0
- 21
IPA.Injector/WtfThisDoesntNeedToExist.cs View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPA.Injector
{
[AttributeUsage(AttributeTargets.Assembly)]
internal class ForceAssemblyReferenceAttribute : Attribute
{
public ForceAssemblyReferenceAttribute(Type forcedType)
{
//not sure if these two lines are required since
//the type is passed to constructor as parameter,
//thus effectively being used
Action<Type> noop = _ => { };
noop(forcedType);
}
}
}

+ 16
- 18
IPA.Loader/Config/ConfigProviders/JsonConfigProvider.cs View File

@ -1,12 +1,10 @@
using IPA.Logging;
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using IPA.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPA.Config.ConfigProviders
{
@ -17,11 +15,11 @@ namespace IPA.Config.ConfigProviders
// TODO: create a wrapper that allows empty object creation
public dynamic Dynamic => jsonObj;
public bool HasChanged { get; private set; } = false;
public bool HasChanged { get; private set; }
public DateTime LastModified => File.GetLastWriteTime(Filename + ".json");
private string _filename = null;
private string _filename;
public string Filename
{
get => _filename;
@ -37,10 +35,10 @@ namespace IPA.Config.ConfigProviders
{
Logger.config.Debug($"Loading file {Filename}.json");
var finfo = new FileInfo(Filename + ".json");
if (finfo.Exists)
var fileInfo = new FileInfo(Filename + ".json");
if (fileInfo.Exists)
{
string json = finfo.OpenText().ReadToEnd();
var json = fileInfo.OpenText().ReadToEnd();
try
{
jsonObj = JObject.Parse(json);
@ -50,7 +48,7 @@ namespace IPA.Config.ConfigProviders
Logger.config.Error($"Error parsing JSON in file {Filename}.json; resetting to empty JSON");
Logger.config.Error(e);
jsonObj = new JObject();
File.WriteAllText(finfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
File.WriteAllText(fileInfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
}
}
else
@ -68,17 +66,17 @@ namespace IPA.Config.ConfigProviders
jsonObj.CollectionChanged += JsonObj_CollectionChanged;
}
private void JsonObj_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
private void JsonObj_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
HasChanged = true;
}
private void JsonObj_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
private void JsonObj_ListChanged(object sender, ListChangedEventArgs e)
{
HasChanged = true;
}
private void JsonObj_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
private void JsonObj_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
HasChanged = true;
}
@ -92,9 +90,9 @@ namespace IPA.Config.ConfigProviders
{
Logger.config.Debug($"Saving file {Filename}.json");
var finfo = new FileInfo(Filename + ".json");
var fileInfo = new FileInfo(Filename + ".json");
File.WriteAllText(finfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
File.WriteAllText(fileInfo.FullName, JsonConvert.SerializeObject(jsonObj, Formatting.Indented));
HasChanged = false;
}


+ 1
- 4
IPA.Loader/Config/IConfigProvider.cs View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// ReSharper disable UnusedMember.Global
namespace IPA.Config
{


+ 12
- 14
IPA.Loader/Config/IniFile.cs View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@ -72,28 +70,28 @@ namespace IPA.Config
/// <summary>
/// Write Data to the INI File
/// </summary>
/// <PARAM name="Section"></PARAM>
/// <PARAM name="section"></PARAM>
/// Section name
/// <PARAM name="Key"></PARAM>
/// <PARAM name="key"></PARAM>
/// Key Name
/// <PARAM name="Value"></PARAM>
/// <PARAM name="value"></PARAM>
/// Value Name
public void IniWriteValue(string Section, string Key, string Value)
public void IniWriteValue(string section, string key, string value)
{
WritePrivateProfileString(Section, Key, Value, IniFileInfo.FullName);
WritePrivateProfileString(section, key, value, IniFileInfo.FullName);
}
/// <summary>
/// Read Data Value From the Ini File
/// </summary>
/// <PARAM name="Section"></PARAM>
/// <PARAM name="Key"></PARAM>
/// <PARAM name="section"></PARAM>
/// <PARAM name="key"></PARAM>
/// <returns></returns>
public string IniReadValue(string Section, string Key)
public string IniReadValue(string section, string key)
{
const int MAX_CHARS = 1023;
StringBuilder result = new StringBuilder(MAX_CHARS);
GetPrivateProfileString(Section, Key, "", result, MAX_CHARS, IniFileInfo.FullName);
const int maxChars = 1023;
StringBuilder result = new StringBuilder(maxChars);
GetPrivateProfileString(section, key, "", result, maxChars, IniFileInfo.FullName);
return result.ToString();
}
}


+ 28
- 35
IPA.Loader/Config/ModPrefs.cs View File

@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IPA.Config
{
@ -85,43 +84,37 @@ namespace IPA.Config
void SetBool(string section, string name, bool value);
}
/// <inheritdoc />
/// <summary>
/// Allows to get and set preferences for your mod.
/// </summary>
public class ModPrefs : IModPrefs
{
private static ModPrefs _staticInstance = null;
private static IModPrefs StaticInstace
{
get
{
if (_staticInstance == null)
_staticInstance = new ModPrefs();
return _staticInstance;
}
}
private static ModPrefs _staticInstance;
private static IModPrefs StaticInstance => _staticInstance ?? (_staticInstance = new ModPrefs());
internal static Dictionary<IBeatSaberPlugin, ModPrefs> ModPrefses { get; set; } = new Dictionary<IBeatSaberPlugin, ModPrefs>();
// ReSharper disable once IdentifierTypo
internal static Dictionary<IBeatSaberPlugin, ModPrefs> ModPrefss { get; set; } = new Dictionary<IBeatSaberPlugin, ModPrefs>();
private IniFile Instance;
private readonly IniFile _instance;
/// <summary>
/// Constructs a ModPrefs object for the provide plugin.
/// </summary>
/// <param name="plugin">the plugin to get the preferences file for</param>
public ModPrefs(IBeatSaberPlugin plugin) {
Instance = new IniFile(Path.Combine(Environment.CurrentDirectory, "UserData", "ModPrefs", $"{plugin.Name}.ini"));
ModPrefses.Add(plugin, this);
_instance = new IniFile(Path.Combine(Environment.CurrentDirectory, "UserData", "ModPrefs", $"{plugin.Name}.ini"));
ModPrefss.Add(plugin, this);
}
private ModPrefs()
{
Instance = new IniFile(Path.Combine(Environment.CurrentDirectory, "UserData", "modprefs.ini"));
_instance = new IniFile(Path.Combine(Environment.CurrentDirectory, "UserData", "modprefs.ini"));
}
string IModPrefs.GetString(string section, string name, string defaultValue, bool autoSave)
{
var value = Instance.IniReadValue(section, name);
var value = _instance.IniReadValue(section, name);
if (value != "")
return value;
else if (autoSave)
@ -138,11 +131,11 @@ namespace IPA.Config
/// <param name="autoSave">Whether or not the default value should be written if no value is found.</param>
/// <returns></returns>
public static string GetString(string section, string name, string defaultValue = "", bool autoSave = false)
=> StaticInstace.GetString(section, name, defaultValue, autoSave);
=> StaticInstance.GetString(section, name, defaultValue, autoSave);
int IModPrefs.GetInt(string section, string name, int defaultValue, bool autoSave)
{
if (int.TryParse(Instance.IniReadValue(section, name), out var value))
if (int.TryParse(_instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
(this as IModPrefs).SetInt(section, name, defaultValue);
@ -158,11 +151,11 @@ namespace IPA.Config
/// <param name="autoSave">Whether or not the default value should be written if no value is found.</param>
/// <returns></returns>
public static int GetInt(string section, string name, int defaultValue = 0, bool autoSave = false)
=> StaticInstace.GetInt(section, name, defaultValue, autoSave);
=> StaticInstance.GetInt(section, name, defaultValue, autoSave);
float IModPrefs.GetFloat(string section, string name, float defaultValue, bool autoSave)
{
if (float.TryParse(Instance.IniReadValue(section, name), out var value))
if (float.TryParse(_instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
(this as IModPrefs).SetFloat(section, name, defaultValue);
@ -178,7 +171,7 @@ namespace IPA.Config
/// <param name="autoSave">Whether or not the default value should be written if no value is found.</param>
/// <returns></returns>
public static float GetFloat(string section, string name, float defaultValue = 0f, bool autoSave = false)
=> StaticInstace.GetFloat(section, name, defaultValue, autoSave);
=> StaticInstance.GetFloat(section, name, defaultValue, autoSave);
bool IModPrefs.GetBool(string section, string name, bool defaultValue, bool autoSave)
{
@ -203,11 +196,11 @@ namespace IPA.Config
/// <param name="autoSave">Whether or not the default value should be written if no value is found.</param>
/// <returns></returns>
public static bool GetBool(string section, string name, bool defaultValue = false, bool autoSave = false)
=> StaticInstace.GetBool(section, name, defaultValue, autoSave);
=> StaticInstance.GetBool(section, name, defaultValue, autoSave);
bool IModPrefs.HasKey(string section, string name)
{
return Instance.IniReadValue(section, name) != null;
return _instance.IniReadValue(section, name) != null;
}
/// <summary>
/// Checks whether or not a key exists in the ini.
@ -215,11 +208,11 @@ namespace IPA.Config
/// <param name="section">Section of the key.</param>
/// <param name="name">Name of the key.</param>
/// <returns></returns>
public static bool HasKey(string section, string name) => StaticInstace.HasKey(section, name);
public static bool HasKey(string section, string name) => StaticInstance.HasKey(section, name);
void IModPrefs.SetFloat(string section, string name, float value)
{
Instance.IniWriteValue(section, name, value.ToString());
_instance.IniWriteValue(section, name, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// Sets a float in the ini.
@ -228,11 +221,11 @@ namespace IPA.Config
/// <param name="name">Name of the key.</param>
/// <param name="value">Value that should be written.</param>
public static void SetFloat(string section, string name, float value)
=> StaticInstace.SetFloat(section, name, value);
=> StaticInstance.SetFloat(section, name, value);
void IModPrefs.SetInt(string section, string name, int value)
{
Instance.IniWriteValue(section, name, value.ToString());
_instance.IniWriteValue(section, name, value.ToString());
}
/// <summary>
/// Sets an int in the ini.
@ -241,11 +234,11 @@ namespace IPA.Config
/// <param name="name">Name of the key.</param>
/// <param name="value">Value that should be written.</param>
public static void SetInt(string section, string name, int value)
=> StaticInstace.SetInt(section, name, value);
=> StaticInstance.SetInt(section, name, value);
void IModPrefs.SetString(string section, string name, string value)
{
Instance.IniWriteValue(section, name, value);
_instance.IniWriteValue(section, name, value);
}
/// <summary>
/// Sets a string in the ini.
@ -254,11 +247,11 @@ namespace IPA.Config
/// <param name="name">Name of the key.</param>
/// <param name="value">Value that should be written.</param>
public static void SetString(string section, string name, string value)
=> StaticInstace.SetString(section, name, value);
=> StaticInstance.SetString(section, name, value);
void IModPrefs.SetBool(string section, string name, bool value)
{
Instance.IniWriteValue(section, name, value ? "1" : "0");
_instance.IniWriteValue(section, name, value ? "1" : "0");
}
/// <summary>
/// Sets a bool in the ini.
@ -267,7 +260,7 @@ namespace IPA.Config
/// <param name="name">Name of the key.</param>
/// <param name="value">Value that should be written.</param>
public static void SetBool(string section, string name, bool value)
=> StaticInstace.SetBool(section, name, value);
=> StaticInstance.SetBool(section, name, value);
}
/// <summary>
@ -280,7 +273,7 @@ namespace IPA.Config
/// <param name="plugin">the plugin wanting the prefrences</param>
/// <returns>the ModPrefs object</returns>
public static IModPrefs GetModPrefs(this IBeatSaberPlugin plugin) {
return ModPrefs.ModPrefses.First(o => o.Key == plugin).Value;
return ModPrefs.ModPrefss.First(o => o.Key == plugin).Value;
}
}
}

+ 4
- 6
IPA.Loader/IPA.Loader.csproj View File

@ -70,7 +70,7 @@
<Compile Include="Logging\Logger.cs" />
<Compile Include="Logging\LogPrinter.cs" />
<Compile Include="Config\ModPrefs.cs" />
<Compile Include="Updating\Converters\ModsaberDependencyConverter.cs" />
<Compile Include="Updating\Converters\ModSaberDependencyConverter.cs" />
<Compile Include="Updating\Converters\SemverRangeConverter.cs" />
<Compile Include="Updating\Converters\SemverVersionConverter.cs" />
<Compile Include="Utilities\BeatSaber.cs" />
@ -86,9 +86,8 @@
<Compile Include="Loader\PluginComponent.cs" />
<Compile Include="Loader\PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updating\Backup\BackupUnit.cs" />
<Compile Include="Updating\ModsaberML\ApiEndpoint.cs" />
<Compile Include="Updating\ModsaberML\Updater.cs" />
<Compile Include="Updating\ModSaber\ApiEndpoint.cs" />
<Compile Include="Updating\ModSaber\Updater.cs" />
<Compile Include="Updating\SelfPlugin.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\LoneFunctions.cs" />
@ -107,7 +106,6 @@
<Version>1.2.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

+ 4
- 10
IPA.Loader/Loader/Composite/CompositeBSPlugin.cs View File

@ -1,9 +1,5 @@
using IPA;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IPA.Logging.Logger;
@ -11,7 +7,7 @@ namespace IPA.Loader.Composite
{
internal class CompositeBSPlugin : IBeatSaberPlugin
{
IEnumerable<IBeatSaberPlugin> plugins;
private readonly IEnumerable<IBeatSaberPlugin> plugins;
private delegate void CompositeCall(IBeatSaberPlugin plugin);
@ -83,14 +79,12 @@ namespace IPA.Loader.Composite
public string Version => throw new NotImplementedException();
public Uri UpdateUri => throw new NotImplementedException();
public ModsaberModInfo ModInfo => throw new NotImplementedException();
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedBeatSaberPlugin)
((IEnhancedBeatSaberPlugin) plugin).OnLateUpdate();
if (plugin is IEnhancedBeatSaberPlugin saberPlugin)
saberPlugin.OnLateUpdate();
});
}
}

+ 7
- 16
IPA.Loader/Loader/Composite/CompositeIPAPlugin.cs View File

@ -1,11 +1,6 @@
using System;
using IPA.Old;
using System;
using System.Collections.Generic;
using IPA;
using IPA.Old;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IPA.Logging.Logger;
namespace IPA.Loader.Composite
@ -13,7 +8,7 @@ namespace IPA.Loader.Composite
#pragma warning disable CS0618 // Type or member is obsolete
internal class CompositeIPAPlugin : IPlugin
{
IEnumerable<IPlugin> plugins;
private readonly IEnumerable<IPlugin> plugins;
private delegate void CompositeCall(IPlugin plugin);
@ -48,18 +43,14 @@ namespace IPA.Loader.Composite
Invoke(plugin => plugin.OnFixedUpdate());
}
public string Name {
get { throw new NotImplementedException(); }
}
public string Name => throw new NotImplementedException();
public string Version {
get { throw new NotImplementedException(); }
}
public string Version => throw new NotImplementedException();
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedBeatSaberPlugin)
((IEnhancedBeatSaberPlugin) plugin).OnLateUpdate();
if (plugin is IEnhancedPlugin saberPlugin)
saberPlugin.OnLateUpdate();
});
}


+ 7
- 8
IPA.Loader/Loader/PluginComponent.cs View File

@ -1,19 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using IPA.Loader.Composite;
using System;
using System.Diagnostics.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using IPA.Loader;
using IPA.Loader.Composite;
using IPA.Logging;
// ReSharper disable UnusedMember.Local
namespace IPA.Loader
{
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal class PluginComponent : MonoBehaviour
{
private CompositeBSPlugin bsPlugins;
private CompositeIPAPlugin ipaPlugins;
private bool quitting = false;
private bool quitting;
internal static PluginComponent Create()
{
@ -29,7 +28,7 @@ namespace IPA.Loader
ipaPlugins = new CompositeIPAPlugin(PluginManager.Plugins);
#pragma warning restore CS0618 // Type or member is obsolete
gameObject.AddComponent<Updating.ModsaberML.Updater>();
gameObject.AddComponent<Updating.ModSaber.Updater>();
bsPlugins.OnApplicationStart();
ipaPlugins.OnApplicationStart();


+ 29
- 31
IPA.Loader/Loader/PluginManager.cs View File

@ -1,22 +1,20 @@
using IPA;
using IPA.Config;
using IPA.Config.ConfigProviders;
using IPA.Logging;
using IPA.Old;
using IPA.Updating;
using IPA.Utilities;
using Mono.Cecil;
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using IPA.Config;
using IPA.Config.ConfigProviders;
using IPA.Logging;
using IPA.Old;
using IPA.Updating;
using IPA.Utilities;
using Mono.Cecil;
using UnityEngine;
using Logger = IPA.Logging.Logger;
namespace IPA.Loader
{
@ -35,9 +33,9 @@ namespace IPA.Loader
internal IBeatSaberPlugin Plugin { get; set; }
internal string Filename { get; set; }
/// <summary>
/// The Modsaber updating info for the mod, or null.
/// The ModSaber updating info for the mod, or null.
/// </summary>
public ModsaberModInfo ModsaberInfo { get; internal set; }
public ModsaberModInfo ModSaberInfo { get; internal set; }
}
/// <summary>
@ -51,10 +49,10 @@ namespace IPA.Loader
{
LoadPlugins();
}
return _bsPlugins.Select(p => p.Plugin);
return (_bsPlugins ?? throw new InvalidOperationException()).Select(p => p.Plugin);