Browse Source

Merge pull request #1 from nike4613/refactor

Complete Refactor
piracy-check
Anairkoen Schno 5 years ago
committed by GitHub
parent
commit
afa35e6ad9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 917 additions and 933 deletions
  1. +14
    -14
      BSIPA.sln
  2. +30
    -0
      IPA.Injector/Bootstrapper.cs
  3. +104
    -0
      IPA.Injector/ConsoleWindow.cs
  4. +82
    -0
      IPA.Injector/IPA.Injector.csproj
  5. +63
    -49
      IPA.Injector/Injector.cs
  6. +7
    -7
      IPA.Injector/PostBuild.msbuild
  7. +37
    -40
      IPA.Injector/Properties/AssemblyInfo.cs
  8. +97
    -0
      IPA.Loader/IPA.Loader.csproj
  9. +1
    -1
      IPA.Loader/IniFile.cs
  10. +4
    -4
      IPA.Loader/Loader/Composite/CompositeBSPlugin.cs
  11. +6
    -4
      IPA.Loader/Loader/Composite/CompositeIPAPlugin.cs
  12. +12
    -4
      IPA.Loader/Loader/PluginComponent.cs
  13. +53
    -9
      IPA.Loader/Loader/PluginManager.cs
  14. +1
    -1
      IPA.Loader/Logging/LogPrinter.cs
  15. +13
    -1
      IPA.Loader/Logging/Logger.cs
  16. +6
    -7
      IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
  17. +2
    -2
      IPA.Loader/Logging/Printers/GZFilePrinter.cs
  18. +5
    -6
      IPA.Loader/Logging/Printers/GlobalLogFilePrinter.cs
  19. +4
    -5
      IPA.Loader/Logging/Printers/PluginLogFilePrinter.cs
  20. +7
    -22
      IPA.Loader/Logging/StandardLogger.cs
  21. +33
    -0
      IPA.Loader/Logging/UnityLogInterceptor.cs
  22. +1
    -1
      IPA.Loader/ModPrefs.cs
  23. +2
    -3
      IPA.Loader/PluginInterfaces/BeatSaber/IBeatSaberPlugin.cs
  24. +1
    -1
      IPA.Loader/PluginInterfaces/BeatSaber/IEnhancedBeatSaberPlugin.cs
  25. +1
    -1
      IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs
  26. +1
    -1
      IPA.Loader/PluginInterfaces/IGenericEnhancedPlugin.cs
  27. +1
    -1
      IPA.Loader/PluginInterfaces/IPA/IEnhancedPlugin.cs
  28. +1
    -1
      IPA.Loader/PluginInterfaces/IPA/IPlugin.cs
  29. +37
    -37
      IPA.Loader/Properties/AssemblyInfo.cs
  30. +50
    -26
      IPA.Loader/Updating/Backup/BackupUnit.cs
  31. +3
    -3
      IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs
  32. +5
    -4
      IPA.Loader/Updating/ModsaberML/Updater.cs
  33. +3
    -4
      IPA.Loader/Updating/SelfPlugin.cs
  34. +1
    -1
      IPA.Loader/Utilities/Extensions.cs
  35. +1
    -1
      IPA.Loader/Utilities/LoneFunctions.cs
  36. +1
    -1
      IPA.Loader/Utilities/ReflectionUtil.cs
  37. +2
    -3
      IPA.Loader/Utilities/SteamCheck.cs
  38. +0
    -1
      IPA.Tests/IPA.Tests.csproj
  39. +0
    -27
      IPA.Tests/updater_test.json
  40. +36
    -18
      IPA/IPA.csproj
  41. +3
    -3
      IPA/PatchContext.cs
  42. +31
    -0
      IPA/Patcher/BackupManager.cs
  43. +29
    -11
      IPA/Patcher/BackupUnit.cs
  44. +8
    -7
      IPA/Patcher/Patcher.cs
  45. +115
    -64
      IPA/Program.cs
  46. +2
    -2
      IPA/Properties/AssemblyInfo.cs
  47. +1
    -1
      IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache
  48. +0
    -4
      IPA/packages.config
  49. +0
    -38
      IllusionInjector/Bootstrapper.cs
  50. +0
    -72
      IllusionInjector/ConsoleWindow.cs
  51. +0
    -132
      IllusionInjector/IllusionInjector.csproj
  52. +0
    -34
      IllusionInjector/Logging/UnityLogInterceptor.cs
  53. +0
    -1
      IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
  54. +0
    -5
      IllusionInjector/packages.config
  55. +0
    -178
      IllusionPlugin/IllusionPlugin.XML
  56. +0
    -69
      IllusionPlugin/IllusionPlugin.csproj
  57. +0
    -1
      IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache

+ 14
- 14
BSIPA.sln View File

@ -5,18 +5,18 @@ VisualStudioVersion = 15.0.27428.2043
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA", "IPA\IPA.csproj", "{14092533-98BB-40A4-9AFC-27BB75672A70}"
ProjectSection(ProjectDependencies) = postProject
{D1C61AF5-0D2D-4752-8203-1C6929025F7C} = {D1C61AF5-0D2D-4752-8203-1C6929025F7C}
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71} = {E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}
{5AD344F0-01A0-4CA8-92E5-9D095737744D} = {5AD344F0-01A0-4CA8-92E5-9D095737744D}
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7} = {2A1AF16B-27F1-46E0-9A95-181516BC1CB7}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IllusionPlugin", "IllusionPlugin\IllusionPlugin.csproj", "{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IllusionInjector", "IllusionInjector\IllusionInjector.csproj", "{D1C61AF5-0D2D-4752-8203-1C6929025F7C}"
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}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA.Injector", "IPA.Injector\IPA.Injector.csproj", "{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -27,14 +27,6 @@ Global
{14092533-98BB-40A4-9AFC-27BB75672A70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14092533-98BB-40A4-9AFC-27BB75672A70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14092533-98BB-40A4-9AFC-27BB75672A70}.Release|Any CPU.Build.0 = Release|Any CPU
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}.Release|Any CPU.Build.0 = Release|Any CPU
{D1C61AF5-0D2D-4752-8203-1C6929025F7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1C61AF5-0D2D-4752-8203-1C6929025F7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1C61AF5-0D2D-4752-8203-1C6929025F7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1C61AF5-0D2D-4752-8203-1C6929025F7C}.Release|Any CPU.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}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -43,6 +35,14 @@ Global
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F08C3C7A-3221-432E-BAB8-32BCE58408C8}.Release|Any CPU.Build.0 = Release|Any CPU
{5AD344F0-01A0-4CA8-92E5-9D095737744D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AD344F0-01A0-4CA8-92E5-9D095737744D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AD344F0-01A0-4CA8-92E5-9D095737744D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AD344F0-01A0-4CA8-92E5-9D095737744D}.Release|Any CPU.Build.0 = Release|Any CPU
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE


+ 30
- 0
IPA.Injector/Bootstrapper.cs View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace IPA.Injector
{
class Bootstrapper : MonoBehaviour
{
public event Action Destroyed = delegate {};
void Awake()
{
//if (Environment.CommandLine.Contains("--verbose"))
//{
Ipa.Injector.Windows.WinConsole.Initialize();
//}
}
void Start()
{
Destroy(gameObject);
}
void OnDestroy()
{
Destroyed();
}
}
}

+ 104
- 0
IPA.Injector/ConsoleWindow.cs View File

@ -0,0 +1,104 @@
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace Ipa.Injector.Windows
{
// https://stackoverflow.com/a/48864902/3117125
static class WinConsole
{
static public void Initialize(bool alwaysCreateNewConsole = true)
{
bool consoleAttached = true;
if (alwaysCreateNewConsole
|| (AttachConsole(ATTACH_PARRENT) == 0
&& Marshal.GetLastWin32Error() != ERROR_ACCESS_DENIED))
{
consoleAttached = AllocConsole() != 0;
}
if (consoleAttached)
{
InitializeOutStream();
InitializeInStream();
}
}
private static void InitializeOutStream()
{
var fs = CreateFileStream("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, FileAccess.Write);
if (fs != null)
{
var writer = new StreamWriter(fs) { AutoFlush = true };
Console.SetOut(writer);
Console.SetError(writer);
}
}
private static void InitializeInStream()
{
var fs = CreateFileStream("CONIN$", GENERIC_READ, FILE_SHARE_READ, FileAccess.Read);
if (fs != null)
{
Console.SetIn(new StreamReader(fs));
}
}
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);
if (!file.IsInvalid)
{
var fs = new FileStream(file, dotNetFileAccess);
return fs;
}
return null;
}
#region Win API Functions and Constants
[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int AllocConsole();
[DllImport("kernel32.dll",
EntryPoint = "AttachConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern UInt32 AttachConsole(UInt32 dwProcessId);
[DllImport("kernel32.dll",
EntryPoint = "CreateFileW",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr CreateFileW(
string lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 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;
#endregion
}
}

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

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2A1AF16B-27F1-46E0-9A95-181516BC1CB7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IPA.Injector</RootNamespace>
<AssemblyName>IPA.Injector</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\Game Library\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Bootstrapper.cs" />
<Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IPA.Loader\IPA.Loader.csproj">
<Project>{5ad344f0-01a0-4ca8-92e5-9d095737744d}</Project>
<Name>IPA.Loader</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\Libs\0Harmony.dll">
<Link>Libraries\Included\0Harmony.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\Libs\I18N.dll">
<Link>Libraries\Mono\I18N.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\Libs\I18N.West.dll">
<Link>Libraries\Mono\I18N.West.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\Libs\System.Runtime.Serialization.dll">
<Link>Libraries\Mono\System.Runtime.Serialization.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild">
<Exec Command="&quot;$(MSBuildBinPath)\MSBuild.exe&quot; &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; /property:OPath=$(OutputPath) /property:Configuration=$(Configuration) /property:SolDir=$(SolutionDir)" />
</Target>
</Project>

IllusionInjector/Injector.cs → IPA.Injector/Injector.cs View File

@ -1,49 +1,63 @@
using System;
using System.IO;
using System.Reflection;
using UnityEngine;
namespace IllusionInjector
{
public static class Injector
{
private static bool injected = false;
public static void Inject()
{
if (!injected)
{
injected = true;
AppDomain.CurrentDomain.AssemblyResolve += AssemblyLibLoader;
var bootstrapper = new GameObject("Bootstrapper").AddComponent<Bootstrapper>();
bootstrapper.Destroyed += Bootstrapper_Destroyed;
}
}
private static string libsDir;
private static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
{
if (libsDir == null)
libsDir = Path.Combine(Environment.CurrentDirectory, "Libs");
var asmName = new AssemblyName(e.Name);
//Logger.log.Debug($"Resolving library {asmName}");
var testFilen = Path.Combine(libsDir, $"{asmName.Name}.{asmName.Version}.dll");
//Logger.log.Debug($"Looking for file {testFilen}");
if (File.Exists(testFilen))
{
return Assembly.LoadFile(testFilen);
}
//Logger.log.Error($"Could not load library {asmName}");
return null;
}
private static void Bootstrapper_Destroyed()
{
PluginComponent.Create();
}
}
}
using IPA.Loader;
using IPA.Logging;
using System;
using System.IO;
using System.Reflection;
using UnityEngine;
using static IPA.Logging.Logger;
using Logger = IPA.Logging.Logger;
namespace IPA.Injector
{
public static class Injector
{
private static bool injected = false;
public static void Inject()
{
if (!injected)
{
injected = true;
AppDomain.CurrentDomain.AssemblyResolve += AssemblyLibLoader;
var bootstrapper = new GameObject("Bootstrapper").AddComponent<Bootstrapper>();
bootstrapper.Destroyed += Bootstrapper_Destroyed;
}
}
private static string libsDir;
private static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
{
if (libsDir == null)
libsDir = Path.Combine(Environment.CurrentDirectory, "Libs");
var asmName = new AssemblyName(e.Name);
Log(Level.Debug, $"Resolving library {asmName}");
var testFilen = Path.Combine(libsDir, $"{asmName.Name}.{asmName.Version}.dll");
Log(Level.Debug, $"Looking for file {testFilen}");
if (File.Exists(testFilen))
return Assembly.LoadFile(testFilen);
Log(Level.Critical, $"Could not load library {asmName}");
return null;
}
private static void Log(Level lvl, string message)
{ // multiple proxy methods to delay loading of assemblies until it's done
if (Logger.LogCreated)
AssemblyLibLoaderCallLogger(lvl, message);
else
if (((byte)lvl & (byte)StandardLogger.PrintFilter) != 0)
Console.WriteLine($"[{lvl}] {message}");
}
private static void AssemblyLibLoaderCallLogger(Level lvl, string message)
{
Logger.log.Log(lvl, message);
}
private static void Bootstrapper_Destroyed()
{
PluginComponent.Create();
}
}
}

IllusionInjector/PostBuild.msbuild → IPA.Injector/PostBuild.msbuild View File

@ -10,22 +10,22 @@
<Target Name="PostBuild">
<Message Text="Relocating" Importance="normal" />
<ItemGroup>
<SystemFiles Include="$(OPath)I18N.*" />
<SystemFiles Include="$(OPath)IllusionInjector.*" />
<SystemFiles Include="$(OPath)IllusionPlugin.*" />
<SystemFiles Include="$(OPath)RequiredMonoLibs\**\*" />
<SystemFiles Include="$(OPath)IPA.Injector.*" />
<SystemFiles Include="$(OPath)IPA.Loader.*" />
<SystemFiles Include="$(OPath)Libraries\Mono\**\*" />
<OldLibFiles Include="$(OPath)Libs\**\*" />
</ItemGroup>
<Move SourceFiles="@(SystemFiles)" DestinationFolder="$(OPath)Data\Managed" />
<RemoveDir Directories="$(OPath)RequiredMonoLibs" />
<RemoveDir Directories="$(OPath)Libraries\Mono" />
<Delete Files="@(OldLibFiles)" />
<RemoveDir Directories="$(OPath)Libs" />
<ItemGroup>
<LibFiles Include="$(OPath)**\*" Exclude="$(OPath)Data\**\*;$(OPath)Lib\**\*" />
<LibFiles Include="$(OPath)**\*" Exclude="$(OPath)Data\**\*;$(OPath)Libs\**\*" />
</ItemGroup>
<Move SourceFiles="@(LibFiles)" DestinationFolder="$(OPath)Libs\" />
<RemoveDir Directories="$(OPath)IncludedLibs" />
<RemoveDir Directories="$(OPath)Libraries\Included" />
<RemoveDir Directories="$(OPath)Libraries" />
<ItemGroup>
<ToRename Include="$(OPath)Libs\**\*.dll" />

IllusionInjector/Properties/AssemblyInfo.cs → IPA.Injector/Properties/AssemblyInfo.cs View File

@ -1,40 +1,37 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IllusionInjector")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IllusionInjector")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("400a540a-d21f-4609-966b-206059b6e73b")]
[assembly: InternalsVisibleTo("IllusionPlugin")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: NeutralResourcesLanguage("en")]
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IPA.Injector")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IPA.Injector")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// 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")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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.9.0")]
[assembly: AssemblyFileVersion("3.9.0")]

+ 97
- 0
IPA.Loader/IPA.Loader.csproj View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5AD344F0-01A0-4CA8-92E5-9D095737744D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IPA</RootNamespace>
<AssemblyName>IPA.Loader</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\..\..\..\Game Library\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UnityWebRequestModule">
<HintPath>..\..\..\..\..\..\Game Library\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\UnityEngine.UnityWebRequestModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Loader\Composite\CompositeBSPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\IBeatSaberPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\IEnhancedBeatSaberPlugin.cs" />
<Compile Include="PluginInterfaces\BeatSaber\ModsaberModInfo.cs" />
<Compile Include="PluginInterfaces\IGenericEnhancedPlugin.cs" />
<Compile Include="IniFile.cs" />
<Compile Include="PluginInterfaces\IPA\IEnhancedPlugin.cs" />
<Compile Include="PluginInterfaces\IPA\IPlugin.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="Logging\LogPrinter.cs" />
<Compile Include="ModPrefs.cs" />
<Compile Include="Utilities\ReflectionUtil.cs" />
<Compile Include="Loader\Composite\CompositeIPAPlugin.cs" />
<Compile Include="Logging\Printers\ColoredConsolePrinter.cs" />
<Compile Include="Logging\Printers\GlobalLogFilePrinter.cs" />
<Compile Include="Logging\Printers\GZFilePrinter.cs" />
<Compile Include="Logging\Printers\PluginLogFilePrinter.cs" />
<Compile Include="Logging\StandardLogger.cs" />
<Compile Include="Logging\UnityLogInterceptor.cs" />
<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\SelfPlugin.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\LoneFunctions.cs" />
<Compile Include="Utilities\SteamCheck.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Ionic.Zip">
<Version>1.9.1.8</Version>
</PackageReference>
<PackageReference Include="Mono.Cecil">
<Version>0.9.6.4</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

IllusionPlugin/IniFile.cs → IPA.Loader/IniFile.cs View File

@ -4,7 +4,7 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace IllusionPlugin
namespace IPA
{
/// <summary>
/// Create a New INI file to store or load data

IllusionInjector/BeatSaber/CompositeBSPlugin.cs → IPA.Loader/Loader/Composite/CompositeBSPlugin.cs View File

@ -1,14 +1,14 @@
using IllusionPlugin;
using IllusionPlugin.BeatSaber;
using IPA;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionInjector.Logging.Logger;
using Logger = IPA.Logging.Logger;
namespace IllusionInjector {
namespace IPA.Loader.Composite
{
public class CompositeBSPlugin : IBeatSaberPlugin
{
IEnumerable<IBeatSaberPlugin> plugins;

IllusionInjector/IPA/CompositeIPAPlugin.cs → IPA.Loader/Loader/Composite/CompositeIPAPlugin.cs View File

@ -1,13 +1,15 @@
using IllusionPlugin;
using System;
using System;
using System.Collections.Generic;
using IPA;
using IPA.Old;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionInjector.Logging.Logger;
using Logger = IPA.Logging.Logger;
namespace IllusionInjector {
namespace IPA.Loader.Composite
{
#pragma warning disable CS0618 // Type or member is obsolete
public class CompositeIPAPlugin : IPlugin
{

IllusionInjector/PluginComponent.cs → IPA.Loader/Loader/PluginComponent.cs View File

@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using IPA.Loader;
using IPA.Loader.Composite;
using IPA.Logging;
namespace IllusionInjector
namespace IPA.Loader
{
public class PluginComponent : MonoBehaviour
{
@ -14,6 +17,13 @@ namespace IllusionInjector
public static PluginComponent Create()
{
Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type)
{
var level = UnityLogInterceptor.LogTypeToLevel(type);
UnityLogInterceptor.UnityLogger.Log(level, $"{condition.Trim()}");
UnityLogInterceptor.UnityLogger.Log(level, $"{stackTrace.Trim()}");
};
return new GameObject("IPA_PluginManager").AddComponent<PluginComponent>();
}
@ -23,9 +33,7 @@ namespace IllusionInjector
bsPlugins = new CompositeBSPlugin(PluginManager.BSPlugins);
ipaPlugins = new CompositeIPAPlugin(PluginManager.Plugins);
// this has no relevance since there is a new mod updater system
//gameObject.AddComponent<ModUpdater>(); // AFTER plugins are loaded, but before most things
gameObject.AddComponent<Updating.ModsaberML.Updater>();
bsPlugins.OnApplicationStart();

IllusionInjector/PluginManager.cs → IPA.Loader/Loader/PluginManager.cs View File

@ -1,8 +1,9 @@
using IllusionInjector.Logging;
using IllusionInjector.Updating;
using IllusionInjector.Utilities;
using IllusionPlugin;
using IllusionPlugin.BeatSaber;
using IPA;
using IPA.Logging;
using IPA.Old;
using IPA.Updating;
using IPA.Utilities;
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -13,9 +14,8 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using LoggerBase = IllusionPlugin.Logging.Logger;
namespace IllusionInjector
namespace IPA.Loader
{
public static class PluginManager
{
@ -176,6 +176,50 @@ namespace IllusionInjector
try
{
#region Fix assemblies for refactor
var module = ModuleDefinition.ReadModule(file);
bool modifiedModule = false;
foreach (var @ref in module.AssemblyReferences)
{ // fix assembly references
if (@ref.Name == "IllusionPlugin" || @ref.Name == "IllusionInjector")
{
@ref.Name = "IPA.Loader";
modifiedModule = true;
}
}
if (modifiedModule)
{ // types don't need to be fixed if it's already referencing the new version
foreach (var @ref in module.GetTypeReferences())
{ // fix type references
if (@ref.FullName == "IllusionPlugin.IPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IEnhancedPlugin") @ref.Namespace = "IPA.Old"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IEnhancedBeatSaberPlugin") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.BeatSaber.ModsaberModInfo") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IniFile") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.IModPrefs") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.ModPrefs") @ref.Namespace = "IPA"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.Utils.ReflectionUtil") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.Logging.Logger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
if (@ref.FullName == "IllusionPlugin.Logging.LogPrinter") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.PluginManager") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.PluginComponent") @ref.Namespace = "IPA.Loader"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.CompositeBSPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.CompositeIPAPlugin") @ref.Namespace = "IPA.Loader.Composite"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.Logging.UnityLogInterceptor") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.Logging.StandardLogger") @ref.Namespace = "IPA.Logging"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.Updating.SelfPlugin") @ref.Namespace = "IPA.Updating"; //@ref.Name = "";
if (@ref.FullName == "IllusionInjector.Updating.Backup.BackupUnit") @ref.Namespace = "IPA.Updating.Backup"; //@ref.Name = "";
if (@ref.Namespace == "IllusionInjector.Utilities") @ref.Namespace = "IPA.Utilities"; //@ref.Name = "";
if (@ref.Namespace == "IllusionInjector.Logging.Printers") @ref.Namespace = "IPA.Logging.Printers"; //@ref.Name = "";
if (@ref.Namespace == "IllusionInjector.Updating.ModsaberML") @ref.Namespace = "IPA.Updating.ModsaberML"; //@ref.Name = "";
}
module.Write(file);
}
#endregion
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type t in assembly.GetTypes())
@ -191,13 +235,13 @@ namespace IllusionInjector
var initArgs = new List<object>();
var initParams = init.GetParameters();
LoggerBase modLogger = null;
Logger modLogger = null;
IModPrefs modPrefs = null;
foreach (var param in initParams)
{
var ptype = param.ParameterType;
if (ptype.IsAssignableFrom(typeof(LoggerBase))) {
if (ptype.IsAssignableFrom(typeof(Logger))) {
if (modLogger == null) modLogger = new StandardLogger(bsPlugin.Name);
initArgs.Add(modLogger);
}

IllusionPlugin/Logging/LogPrinter.cs → IPA.Loader/Logging/LogPrinter.cs View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.Logging
namespace IPA.Logging
{
/// <summary>
/// The log printer's base class.

IllusionPlugin/Logging/Logger.cs → IPA.Loader/Logging/Logger.cs View File

@ -4,13 +4,25 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.Logging
namespace IPA.Logging
{
/// <summary>
/// The logger base class. Provides the format for console logs.
/// </summary>
public abstract class Logger
{
private static Logger _log;
internal static Logger log
{
get
{
if (_log == null)
_log = new StandardLogger("IPA");
return _log;
}
}
internal static bool LogCreated => _log != null;
/// <summary>
/// The standard format for log messages.
/// </summary>

IllusionInjector/Logging/Printers/ColoredConsolePrinter.cs → IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs View File

@ -4,25 +4,24 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IllusionPlugin.Logging;
using LoggerBase = IllusionPlugin.Logging.Logger;
using IPA.Logging;
namespace IllusionInjector.Logging.Printers
namespace IPA.Logging.Printers
{
public class ColoredConsolePrinter : LogPrinter
{
LoggerBase.LogLevel filter = LoggerBase.LogLevel.All;
public override LoggerBase.LogLevel Filter { get => filter; set => filter = value; }
Logger.LogLevel filter = Logger.LogLevel.All;
public override Logger.LogLevel Filter { get => filter; set => filter = value; }
ConsoleColor color = Console.ForegroundColor;
public ConsoleColor Color { get => color; set => color = value; }
public override void Print(LoggerBase.Level level, DateTime time, string logName, string message)
public override void Print(Logger.Level level, DateTime time, string logName, string message)
{
if (((byte)level & (byte)StandardLogger.PrintFilter) == 0) return;
Console.ForegroundColor = color;
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
Console.WriteLine(string.Format(LoggerBase.LogFormat, line, logName, time, level.ToString().ToUpper()));
Console.WriteLine(string.Format(Logger.LogFormat, line, logName, time, level.ToString().ToUpper()));
Console.ResetColor();
}
}

IllusionInjector/Logging/Printers/GZFilePrinter.cs → IPA.Loader/Logging/Printers/GZFilePrinter.cs View File

@ -1,4 +1,4 @@
using IllusionPlugin.Logging;
using IPA.Logging;
using Ionic.Zlib;
using System;
using System.Collections.Generic;
@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Logging.Printers
namespace IPA.Logging.Printers
{
public abstract class GZFilePrinter : LogPrinter
{

IllusionInjector/Logging/Printers/GlobalLogFilePrinter.cs → IPA.Loader/Logging/Printers/GlobalLogFilePrinter.cs View File

@ -4,19 +4,18 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IllusionPlugin.Logging;
using LoggerBase = IllusionPlugin.Logging.Logger;
using IPA.Logging;
namespace IllusionInjector.Logging.Printers
namespace IPA.Logging.Printers
{
class GlobalLogFilePrinter : GZFilePrinter
{
public override LoggerBase.LogLevel Filter { get; set; } = LoggerBase.LogLevel.All;
public override Logger.LogLevel Filter { get; set; } = Logger.LogLevel.All;
public override void Print(IllusionPlugin.Logging.Logger.Level level, DateTime time, string logName, string message)
public override void Print(IPA.Logging.Logger.Level level, DateTime time, string logName, string message)
{
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
fileWriter.WriteLine(string.Format(LoggerBase.LogFormat, line, logName, time, level.ToString().ToUpper()));
fileWriter.WriteLine(string.Format(Logger.LogFormat, line, logName, time, level.ToString().ToUpper()));
}
protected override FileInfo GetFileInfo()

IllusionInjector/Logging/Printers/PluginLogFilePrinter.cs → IPA.Loader/Logging/Printers/PluginLogFilePrinter.cs View File

@ -1,17 +1,16 @@
using IllusionPlugin.Logging;
using IPA.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LoggerBase = IllusionPlugin.Logging.Logger;
namespace IllusionInjector.Logging.Printers
namespace IPA.Logging.Printers
{
class PluginLogFilePrinter : GZFilePrinter
{
public override LoggerBase.LogLevel Filter { get; set; } = LoggerBase.LogLevel.All;
public override Logger.LogLevel Filter { get; set; } = Logger.LogLevel.All;
private string name;
@ -28,7 +27,7 @@ namespace IllusionInjector.Logging.Printers
this.name = name;
}
public override void Print(IllusionPlugin.Logging.Logger.Level level, DateTime time, string logName, string message)
public override void Print(IPA.Logging.Logger.Level level, DateTime time, string logName, string message)
{
foreach (var line in message.Split(new string[] { "\n", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
fileWriter.WriteLine(string.Format("[{3} @ {2:HH:mm:ss}] {0}", line, logName, time, level.ToString().ToUpper()));

IllusionInjector/Logging/StandardLogger.cs → IPA.Loader/Logging/StandardLogger.cs View File

@ -1,6 +1,4 @@
using IllusionInjector.Logging.Printers;
using IllusionPlugin;
using IllusionPlugin.Logging;
using IPA.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -9,24 +7,12 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using LoggerBase = IllusionPlugin.Logging.Logger;
using IPA;
using LoggerBase = IPA.Logging.Logger;
using IPA.Logging.Printers;
namespace IllusionInjector.Logging
namespace IPA.Logging
{
internal static class Logger
{
private static LoggerBase _log;
internal static LoggerBase log
{
get
{
if (_log == null)
_log = new StandardLogger("IPA");
return _log;
}
}
}
public class StandardLogger : LoggerBase
{
private static readonly IReadOnlyList<LogPrinter> defaultPrinters = new List<LogPrinter>()
@ -60,15 +46,14 @@ namespace IllusionInjector.Logging
};
private string logName;
private static LogLevel showFilter = LogLevel.InfoUp;
private static bool showSourceClass = true;
public static LogLevel PrintFilter { get => showFilter; set => showFilter = value; }
public static LogLevel PrintFilter { get; set; } = LogLevel.InfoUp;
private List<LogPrinter> printers = new List<LogPrinter>(defaultPrinters);
static StandardLogger()
{
if (ModPrefs.GetBool("IPA", "PrintDebug", false, true))
showFilter = LogLevel.All;
PrintFilter = LogLevel.All;
showSourceClass = ModPrefs.GetBool("IPA", "DebugShowCallSource", false, true);
}

+ 33
- 0
IPA.Loader/Logging/UnityLogInterceptor.cs View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace IPA.Logging
{
internal class UnityLogInterceptor
{
public static Logger UnityLogger = new StandardLogger("UnityEngine");
public static Logger.Level LogTypeToLevel(LogType type)
{
switch (type)
{
case LogType.Assert:
return Logger.Level.Debug;
case LogType.Error:
return Logger.Level.Error;
case LogType.Exception:
return Logger.Level.Critical;
case LogType.Log:
return Logger.Level.Info;
case LogType.Warning:
return Logger.Level.Warning;
default:
return Logger.Level.Info;
}
}
}
}

IllusionPlugin/ModPrefs.cs → IPA.Loader/ModPrefs.cs View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
namespace IllusionPlugin
namespace IPA
{
/// <summary>
/// Allows to get and set preferences for your mod.

IllusionPlugin/BeatSaber/IBeatSaberPlugin.cs → IPA.Loader/PluginInterfaces/BeatSaber/IBeatSaberPlugin.cs View File

@ -1,10 +1,9 @@
using IllusionPlugin.BeatSaber;
using System;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;
namespace IllusionPlugin
namespace IPA
{
/// <summary>
/// Interface for Beat Saber plugins. Every class that implements this will be loaded if the DLL is placed at

IllusionPlugin/BeatSaber/IEnhancedBeatSaberPlugin.cs → IPA.Loader/PluginInterfaces/BeatSaber/IEnhancedBeatSaberPlugin.cs View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace IllusionPlugin
namespace IPA
{
/// <summary>
/// An enhanced version of a standard BeatSaber plugin.

IllusionPlugin/BeatSaber/ModsaberModInfo.cs → IPA.Loader/PluginInterfaces/BeatSaber/ModsaberModInfo.cs View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin.BeatSaber
namespace IPA
{
/// <summary>
/// A class to provide information about a mod on ModSaber.ML

IllusionPlugin/IGenericEnhancedPlugin.cs → IPA.Loader/PluginInterfaces/IGenericEnhancedPlugin.cs View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionPlugin
namespace IPA
{
/// <summary>
/// A generic interface for the modification for enhanced plugins.

IllusionPlugin/IPA/IEnhancedPlugin.cs → IPA.Loader/PluginInterfaces/IPA/IEnhancedPlugin.cs View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace IllusionPlugin
namespace IPA.Old
{
/// <summary>
/// An enhanced version of the standard IPA plugin.

IllusionPlugin/IPA/IPlugin.cs → IPA.Loader/PluginInterfaces/IPA/IPlugin.cs View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace IllusionPlugin
namespace IPA.Old
{
/// <summary>
/// Interface for generic Illusion unity plugins. Every class that implements this will be loaded if the DLL is placed at

IllusionPlugin/Properties/AssemblyInfo.cs → IPA.Loader/Properties/AssemblyInfo.cs View File

@ -1,37 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IllusionPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IllusionPlugin")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e8cea89d-6c2f-4729-94b3-f355f7db19e5")]
[assembly: InternalsVisibleTo("IllusionInjector")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("IPA.Loader")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("IPA.Loader")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5ad344f0-01a0-4ca8-92e5-9d095737744d")]
[assembly: InternalsVisibleTo("IPA.Injector")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

IllusionInjector/Updating/Backup/BackupUnit.cs → IPA.Loader/Updating/Backup/BackupUnit.cs View File

@ -1,4 +1,5 @@
using IllusionInjector.Utilities;
using IPA.Logging;
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
@ -6,7 +7,7 @@ using System.IO;
using System.Linq;
using System.Text;
namespace IllusionInjector.Updating.Backup
namespace IPA.Updating.Backup
{
/// <summary>
/// A unit for backup. WIP.
@ -17,26 +18,39 @@ namespace IllusionInjector.Updating.Backup
private DirectoryInfo _BackupPath;
private List<string> _Files = new List<string>();
public BackupUnit(string backupPath) : this(backupPath, DateTime.Now.ToString("yyyy-MM-dd_h-mm-ss"))
private FileInfo _ManifestFile;
private static string _ManifestFileName = "$manifest$.txt";
public BackupUnit(string path) : this(path, DateTime.Now.ToString("yyyy-MM-dd_h-mm-ss"))
{
}
public BackupUnit(string backupPath, string name)
internal BackupUnit(string path, string name)
{
Name = name;
_BackupPath = new DirectoryInfo(Path.Combine(backupPath, Name));
_BackupPath.Create();
_BackupPath = new DirectoryInfo(Path.Combine(path, Name));
_ManifestFile = new FileInfo(Path.Combine(_BackupPath.FullName, _ManifestFileName));
}
public static BackupUnit FromDirectory(DirectoryInfo directory, string backupPath)
{
var unit = new BackupUnit(backupPath, directory.Name);
// Parse directory
foreach(var file in directory.GetFiles("*", SearchOption.AllDirectories)) {
var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
unit._Files.Add(relativePath);
// Read Manifest
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);
}
else
{
foreach (var file in directory.GetFiles("*", SearchOption.AllDirectories))
{
if (file.Name == _ManifestFileName) continue;
var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
unit._Files.Add(relativePath);
}
}
return unit;
@ -60,25 +74,31 @@ namespace IllusionInjector.Updating.Backup
{
var relativePath = LoneFunctions.GetRelativePath(Environment.CurrentDirectory, file.FullName);
var backupPath = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath));
if(_Files.Contains(relativePath))
if (_Files.Contains(relativePath))
{
Console.WriteLine("Skipping backup of {0}", relativePath);
Logger.log.Debug($"Skipping backup of {relativePath}");
return;
}
// Copy over
backupPath.Directory.Create();
if (file.Exists)
{
file.CopyTo(backupPath.FullName, true);
} else
file.CopyTo(backupPath.FullName);
}
else
{
// Make empty file
backupPath.Create().Close();
}
if (!File.Exists(_ManifestFile.FullName))
_ManifestFile.Create().Close();
var stream = _ManifestFile.AppendText();
stream.WriteLine(relativePath);
stream.Close();
// Add to list
_Files.Add(relativePath);
}
@ -88,9 +108,9 @@ namespace IllusionInjector.Updating.Backup
/// </summary>
public void Restore()
{
foreach(var relativePath in _Files)
foreach (var relativePath in _Files)
{
//Console.WriteLine("Restoring {0}", relativePath);
Logger.log.Debug($"Restoring {relativePath}");
// Original version
var backupFile = new FileInfo(Path.Combine(_BackupPath.FullName, relativePath));
var target = new FileInfo(Path.Combine(Environment.CurrentDirectory, relativePath));
@ -99,22 +119,26 @@ namespace IllusionInjector.Updating.Backup
{
if (backupFile.Length > 0)
{
//Console.WriteLine(" {0} => {1}", backupFile.FullName, target.FullName);
Logger.log.Debug($" {backupFile.FullName} => {target.FullName}");
target.Directory.Create();
backupFile.CopyTo(target.FullName, true);
} else
}
else
{
//Console.WriteLine(" x {0}", target.FullName);
if(target.Exists)
Logger.log.Debug($" x {target.FullName}");
if (target.Exists)
{
target.Delete();
}
}
} else {
//Console.Error.WriteLine("Backup not found!");
}
else
{
Logger.log.Error("Backup not found!");
}
}
}
}
}

IllusionInjector/Updating/ModsaberML/ApiEndpoint.cs → IPA.Loader/Updating/ModsaberML/ApiEndpoint.cs View File

@ -1,5 +1,5 @@
using IllusionInjector.Logging;
using IllusionInjector.Utilities;
using IPA.Logging;
using IPA.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
@ -9,7 +9,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Updating.ModsaberML
namespace IPA.Updating.ModsaberML
{
class ApiEndpoint
{

IllusionInjector/Updating/ModsaberML/Updater.cs → IPA.Loader/Updating/ModsaberML/Updater.cs View File

@ -1,5 +1,5 @@
using IllusionInjector.Updating.Backup;
using IllusionInjector.Utilities;
using IPA.Utilities;
using IPA.Loader;
using Ionic.Zip;
using Newtonsoft.Json;
using System;
@ -15,9 +15,10 @@ using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Logger = IllusionInjector.Logging.Logger;
using Logger = IPA.Logging.Logger;
using IPA.Updating.Backup;
namespace IllusionInjector.Updating.ModsaberML
namespace IPA.Updating.ModsaberML
{
class Updater : MonoBehaviour
{

IllusionInjector/Updating/SelfPlugin.cs → IPA.Loader/Updating/SelfPlugin.cs View File

@ -1,5 +1,4 @@
using IllusionPlugin;
using IllusionPlugin.BeatSaber;
using IPA;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,12 +6,12 @@ using System.Text;
using System.Threading.Tasks;
using UnityEngine.SceneManagement;
namespace IllusionInjector.Updating
namespace IPA.Updating
{
internal class SelfPlugin : IBeatSaberPlugin
{
internal const string IPA_Name = "Beat Saber IPA";
internal const string IPA_Version = "3.8.9";
internal const string IPA_Version = "3.9.0";
public string Name => IPA_Name;

IllusionInjector/Utilities/Extensions.cs → IPA.Loader/Utilities/Extensions.cs View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class Extensions
{

IllusionInjector/Utilities/LoneFunctions.cs → IPA.Loader/Utilities/LoneFunctions.cs View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class LoneFunctions
{

IllusionPlugin/Utils/ReflectionUtil.cs → IPA.Loader/Utilities/ReflectionUtil.cs View File

@ -2,7 +2,7 @@
using System.Reflection;
using UnityEngine;
namespace IllusionPlugin.Utils
namespace IPA.Utilities
{
/// <summary>
/// A utility class providing reflection helper methods.

IllusionInjector/Utilities/SteamCheck.cs → IPA.Loader/Utilities/SteamCheck.cs View File

@ -1,11 +1,10 @@
using IllusionInjector.Logging;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IllusionInjector.Utilities
namespace IPA.Utilities
{
public static class SteamCheck
{

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

@ -67,7 +67,6 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="updater_test.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IPA\IPA.csproj">


+ 0
- 27
IPA.Tests/updater_test.json View File

@ -1,27 +0,0 @@
{
"name": "bsipa-test-plugin",
"version": "0.0.1",
"approved": true,
"title": "BSIPA Test Plugin",
"description": "",
"type": "mod",
"published": "2018-08-02T03:12:18.805Z",
"gameVersion": "0.11.2",
"gameVersionID": "5b626bb15d243a0008b8886e",
"oldVersions": [],
"dependsOn": [],
"conflictsWith": [],
"files": {
"steam": {
"hash": "a94e7eea2f656b2830a86000ee222b6cb06f8da5",
"files": {
"Plugins/": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"Plugins/RandomSong.dll": "64ee1ecfeda73c550004bdb5123c7ac47a45e428"
},
"url": "https://www.modsaber.ml/cdn/randomsong/1.0.0-default.zip"
}
},
"weight": 7,
"author": "danike",
"authorID": "5b62723f288b110008291cb9"
}

+ 36
- 18
IPA/IPA.csproj View File

@ -13,6 +13,21 @@
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -39,23 +54,10 @@
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>IPA.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
@ -77,7 +79,6 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
@ -85,6 +86,23 @@
<ItemGroup>
<Folder Include="IPA\Fallback\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil">
<Version>0.9.6.4</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@ -96,7 +114,7 @@
<Target Name="AfterBuild">
<Message Text="Packing..." Importance="normal" />
<ItemGroup>
<Dlls Include="$(SolutionDir)IllusionInjector\$(OutDir)**\*" />
<Dlls Include="$(SolutionDir)IPA.Injector\$(OutDir)**\*" />
</ItemGroup>
<Copy SourceFiles="@(Dlls)" DestinationFolder="$(OutputPath)IPA\%(RecursiveDir)" />
</Target>


+ 3
- 3
IPA/PatchContext.cs View File

@ -38,8 +38,8 @@ namespace IPA
Executable = exe
};
context.ProjectRoot = new FileInfo(context.Executable).Directory.FullName;
context.IPARoot = Path.Combine(context.ProjectRoot, "IPA");
context.IPA = Assembly.GetExecutingAssembly().Location ?? Path.Combine(context.ProjectRoot, "IPA.exe");
context.IPARoot = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "IPA");
context.IPA = Assembly.GetExecutingAssembly()?.Location ?? Path.Combine(context.ProjectRoot, "IPA.exe");
context.DataPathSrc = Path.Combine(context.IPARoot, "Data");
context.LibsPathSrc = Path.Combine(context.IPARoot, "Libs");
context.PluginsFolder = Path.Combine(context.ProjectRoot, "Plugins");
@ -49,7 +49,7 @@ namespace IPA
context.ManagedPath = Path.Combine(context.DataPathDst, "Managed");
context.EngineFile = Path.Combine(context.ManagedPath, "UnityEngine.CoreModule.dll");
context.AssemblyFile = Path.Combine(context.ManagedPath, "Assembly-CSharp.dll");
context.BackupPath = Path.Combine(Path.Combine(context.IPARoot, "Backups"), context.ProjectName);
context.BackupPath = Path.Combine(context.IPARoot, "Backups", context.ProjectName);
string shortcutName = $"{context.ProjectName} (Patch & Launch)";
context.ShortcutPath = Path.Combine(context.ProjectRoot, shortcutName) + ".lnk";


+ 31
- 0
IPA/Patcher/BackupManager.cs View File

@ -11,6 +11,7 @@ namespace IPA.Patcher
{
public static BackupUnit FindLatestBackup(PatchContext context)
{
new DirectoryInfo(context.BackupPath).Create();
return new DirectoryInfo(context.BackupPath)
.GetDirectories()
.OrderByDescending(p => p.Name)
@ -30,10 +31,40 @@ namespace IPA.Patcher
{
backup.Restore();
backup.Delete();
DeleteEmptyDirs(context.ProjectRoot);
return true;
}
return false;
}
public static void DeleteEmptyDirs(string dir)
{
if (string.IsNullOrEmpty(dir))
throw new ArgumentException(
"Starting directory is a null reference or an empty string",
"dir");
try
{
foreach (var d in Directory.EnumerateDirectories(dir))
{
DeleteEmptyDirs(d);
}
var entries = Directory.EnumerateFileSystemEntries(dir);
if (!entries.Any())
{
try
{
Directory.Delete(dir);
}
catch (UnauthorizedAccessException) { }
catch (DirectoryNotFoundException) { }
}
}
catch (UnauthorizedAccessException) { }
}
}
}

+ 29
- 11
IPA/Patcher/BackupUnit.cs View File

@ -13,13 +13,13 @@ namespace IPA.Patcher
public class BackupUnit
{
public string Name { get; private set; }
private DirectoryInfo _BackupPath;
private PatchContext _Context;
private List<string> _Files = new List<string>();
private FileInfo _ManifestFile;
private static string _ManifestFileName = "$manifest$.txt";
public BackupUnit(PatchContext context) : this(context, DateTime.Now.ToString("yyyy-MM-dd_h-mm-ss"))
{
}
@ -29,16 +29,28 @@ namespace IPA.Patcher
Name = name;
_Context = context;
_BackupPath = new DirectoryInfo(Path.Combine(_Context.BackupPath, Name));
_ManifestFile = new FileInfo(Path.Combine(_BackupPath.FullName, _ManifestFileName));
}
public static BackupUnit FromDirectory(DirectoryInfo directory, PatchContext context)
{
var unit = new BackupUnit(context, directory.Name);
// Parse directory
foreach(var file in directory.GetFiles("*", SearchOption.AllDirectories)) {
var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
unit._Files.Add(relativePath);
// Read Manifest
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);
}
else
{
foreach (var file in directory.GetFiles("*", SearchOption.AllDirectories))
{
if (file.Name == _ManifestFileName) continue;
var relativePath = file.FullName.Substring(directory.FullName.Length + 1);
unit._Files.Add(relativePath);
}
}
return unit;
@ -74,19 +86,25 @@ namespace IPA.Patcher
Console.WriteLine("Skipping backup of {0}", relativePath);
return;
}
// Copy over
backupPath.Directory.Create();
if (file.Exists)
{
file.CopyTo(backupPath.FullName);
} else
}
else
{
// Make empty file
backupPath.Create().Close();
}
if (!File.Exists(_ManifestFile.FullName))
_ManifestFile.Create().Close();
var stream = _ManifestFile.AppendText();
stream.WriteLine(relativePath);
stream.Close();
// Add to list
_Files.Add(relativePath);
}


+ 8
- 7
IPA/Patcher/Patcher.cs View File

@ -51,8 +51,9 @@ namespace IPA.Patcher
{
var IIdata = new PatchData { IsPatched = false, Version = null };
foreach (var @ref in _Module.AssemblyReferences) {
if (@ref.Name == "IllusionInjector") IIdata = new PatchData { IsPatched = true, Version = new Version(0,0,0,0) };
if (@ref.Name == "IllusionPlugin") return new PatchData { IsPatched = true, Version = @ref.Version };
if (@ref.Name == "IllusionInjector") IIdata = new PatchData { IsPatched = true, Version = new Version(0, 0, 0, 0) };
if (@ref.Name == "IllusionPlugin") IIdata = new PatchData { IsPatched = true, Version = new Version(0, 0, 0, 0) };
if (@ref.Name == "IPA.Injector") return new PatchData { IsPatched = true, Version = @ref.Version };
}
return IIdata;
}
@ -61,9 +62,8 @@ namespace IPA.Patcher
public void Patch(Version v)
{
// First, let's add the reference
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1,0,0,0));
var versionNameReference = new AssemblyNameReference("IllusionPlugin", v);
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
var nameReference = new AssemblyNameReference("IPA.Injector", Program.Version);
var injectorPath = Path.Combine(_File.DirectoryName, "IPA.Injector.dll");
var injector = ModuleDefinition.ReadModule(injectorPath);
for (int i = 0; i < _Module.AssemblyReferences.Count; i++)
@ -72,10 +72,11 @@ namespace IPA.Patcher
_Module.AssemblyReferences.RemoveAt(i--);
if (_Module.AssemblyReferences[i].Name == "IllusionPlugin")
_Module.AssemblyReferences.RemoveAt(i--);
if (_Module.AssemblyReferences[i].Name == "IPA.Injector")
_Module.AssemblyReferences.RemoveAt(i--);
}
_Module.AssemblyReferences.Add(nameReference);
_Module.AssemblyReferences.Add(versionNameReference);
int patched = 0;
foreach(var type in FindEntryTypes())
@ -100,7 +101,7 @@ namespace IPA.Patcher
var targetMethod = targetType.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic);
if (targetMethod != null)
{
var methodReference = _Module.Import(injector.GetType("IllusionInjector.Injector").Methods.First(m => m.Name == "Inject"));
var methodReference = _Module.Import(injector.GetType("IPA.Injector.Injector").Methods.First(m => m.Name == "Inject"));
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
return true;
}


+ 115
- 64
IPA/Program.cs View File

@ -11,23 +11,26 @@ using System.Text.RegularExpressions;
using System.Windows.Forms;
using IPA.ArgParsing;
namespace IPA {
public class Program {
public enum Architecture {
namespace IPA
{
public class Program
{
public enum Architecture
{
x86,
x64,
Unknown
}
private static Version Version => Assembly.GetEntryAssembly().GetName().Version;
public static Version Version => Assembly.GetEntryAssembly().GetName().Version;
public static ArgumentFlag ArgHelp = new ArgumentFlag("--help", "-h") { DocString = "prints this message" };
public static ArgumentFlag ArgWaitFor = new ArgumentFlag("--waitfor", "-w") { DocString = "waits for the specified PID to exit", ValueString = "PID" };
public static ArgumentFlag ArgForce = new ArgumentFlag("--force", "-f") { DocString = "forces the operation to go through" };
public static ArgumentFlag ArgRevert = new ArgumentFlag("--revert", "-r") { DocString = "reverts the IPA installation" };
public static ArgumentFlag ArgNoWait = new ArgumentFlag("--nowait", "-n") { DocString = "doesn't wait for user input after the operation" };
public static ArgumentFlag ArgStart = new ArgumentFlag("--start", "-s") { DocString = "uses value as arguments to start the game after the patch/unpatch", ValueString = "ARGUMENTS" };
public static ArgumentFlag ArgLaunch = new ArgumentFlag("--launch", "-l") { DocString = "uses positional parameters as arguments to start the game after patch/unpatch" };
public static ArgumentFlag ArgHelp = new ArgumentFlag("--help", "-h") { DocString = "prints this message" };
public static ArgumentFlag ArgWaitFor = new ArgumentFlag("--waitfor", "-w") { DocString = "waits for the specified PID to exit", ValueString = "PID" };
public static ArgumentFlag ArgForce = new ArgumentFlag("--force", "-f") { DocString = "forces the operation to go through" };
public static ArgumentFlag ArgRevert = new ArgumentFlag("--revert", "-r") { DocString = "reverts the IPA installation" };
public static ArgumentFlag ArgNoWait = new ArgumentFlag("--nowait", "-n") { DocString = "doesn't wait for user input after the operation" };
public static ArgumentFlag ArgStart = new ArgumentFlag("--start", "-s") { DocString = "uses value as arguments to start the game after the patch/unpatch", ValueString = "ARGUMENTS" };
public static ArgumentFlag ArgLaunch = new ArgumentFlag("--launch", "-l") { DocString = "uses positional parameters as arguments to start the game after patch/unpatch" };
static void Main(string[] args)
{
@ -57,7 +60,7 @@ namespace IPA {
}
PatchContext context;
var argExeName = Arguments.CmdLine.PositionalArgs.FirstOrDefault(s => s.EndsWith(".exe"));
if (argExeName == null)
context = PatchContext.Create(new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles()
@ -65,7 +68,7 @@ namespace IPA {
.FullName);
else
context = PatchContext.Create(argExeName);
// Sanitizing
Validate(context);
@ -77,7 +80,8 @@ namespace IPA {
StartIfNeedBe(context);
}
}
catch (Exception e) {
catch (Exception e)
{
Fail(e.Message);
}
@ -95,32 +99,40 @@ namespace IPA {
}
}
private static void Validate(PatchContext c) {
if (!Directory.Exists(c.DataPathDst) || !File.Exists(c.EngineFile)) {
private static void Validate(PatchContext c)
{
if (!Directory.Exists(c.DataPathDst) || !File.Exists(c.EngineFile))
{
Fail("Game does not seem to be a Unity project. Could not find the libraries to patch.");
Console.WriteLine($"DataPath: {c.DataPathDst}");
Console.WriteLine($"EngineFile: {c.EngineFile}");
}
}
private static void Install(PatchContext context) {
try {
private static void Install(PatchContext context)
{
try
{
var backup = new BackupUnit(context);
#region Patch Version Check
var patchedModule = PatchedModule.Load(context.EngineFile);
#if DEBUG
var isCurrentNewer = Version.CompareTo(patchedModule.Data.Version) >= 0;
#else
var isCurrentNewer = Version.CompareTo(patchedModule.Data.Version) > 0;
#endif
Console.WriteLine($"Current: {Version} Patched: {patchedModule.Data.Version}");
if (isCurrentNewer) {
if (isCurrentNewer)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(
$"Preparing for update, {(patchedModule.Data.Version == null ? "UnPatched" : patchedModule.Data.Version.ToString())} => {Version}");
Console.WriteLine("--- Starting ---");
Revert(context);
Console.ResetColor();
#region File Copying
Console.ForegroundColor = ConsoleColor.Magenta;
@ -146,7 +158,8 @@ namespace IPA {
#endregion
}
else {
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Files up to date @ Version {Version}!");
Console.ResetColor();
@ -156,7 +169,8 @@ namespace IPA {
#region Create Plugin Folder
if (!Directory.Exists(context.PluginsFolder)) {
if (!Directory.Exists(context.PluginsFolder))
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Creating plugins folder... ");
Directory.CreateDirectory(context.PluginsFolder);
@ -167,7 +181,8 @@ namespace IPA {
#region Patching
if (!patchedModule.Data.IsPatched || isCurrentNewer) {
if (!patchedModule.Data.IsPatched || isCurrentNewer)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Patching UnityEngine.dll with Version {Application.ProductVersion}... ");
backup.Add(context.EngineFile);
@ -180,9 +195,11 @@ namespace IPA {
#region Virtualizing
if (File.Exists(context.AssemblyFile)) {
if (File.Exists(context.AssemblyFile))
{
var virtualizedModule = VirtualizedModule.Load(context.AssemblyFile);
if (!virtualizedModule.IsVirtualized) {
if (!virtualizedModule.IsVirtualized)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Virtualizing Assembly-Csharp.dll... ");
backup.Add(context.AssemblyFile);
@ -195,10 +212,10 @@ namespace IPA {
#endregion
#region Creating shortcut
if(!File.Exists(context.ShortcutPath))
if (!File.Exists(context.ShortcutPath))
{
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("Creating shortcut to IPA ({0})... ", context.IPA);
Console.WriteLine("Creating shortcut to IPA ({0})... ", context.IPA);
try
{
Shortcut.Create(
@ -210,7 +227,8 @@ namespace IPA {
hotkey: "",
iconPath: context.Executable
);
} catch (Exception)
}
catch (Exception)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine("Failed to create shortcut, but game was patched!");
@ -227,19 +245,23 @@ namespace IPA {
Console.ResetColor();
}
private static void Revert(PatchContext context) {
private static void Revert(PatchContext context)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("Restoring backup... ");
if (BackupManager.Restore(context)) {
if (BackupManager.Restore(context))
{
Console.WriteLine("Done!");
}
else {
else
{
Console.WriteLine("Already vanilla or you removed your backups!");
}
if (File.Exists(context.ShortcutPath)) {
if (File.Exists(context.ShortcutPath))
{
Console.WriteLine("Deleting shortcut...");
File.Delete(context.ShortcutPath);
}
@ -250,7 +272,8 @@ namespace IPA {
Console.ResetColor();
}
private static void StartIfNeedBe(PatchContext context) {
private static void StartIfNeedBe(PatchContext context)
{
if (ArgStart.HasValue)
{
Process.Start(context.Executable, ArgStart.Value);
@ -269,42 +292,51 @@ namespace IPA {
}
public static IEnumerable<FileInfo> NativePluginInterceptor(FileInfo from, FileInfo to,
DirectoryInfo nativePluginFolder, bool isFlat, Architecture preferredArchitecture) {
if (to.FullName.StartsWith(nativePluginFolder.FullName)) {
DirectoryInfo nativePluginFolder, bool isFlat, Architecture preferredArchitecture)
{
if (to.FullName.StartsWith(nativePluginFolder.FullName))
{
var relevantBit = to.FullName.Substring(nativePluginFolder.FullName.Length + 1);
// Goes into the plugin folder!
bool isFileFlat = !relevantBit.StartsWith("x86");
if (isFlat && !isFileFlat) {
if (isFlat && !isFileFlat)
{
// Flatten structure
bool is64Bit = relevantBit.StartsWith("x86_64");
if (!is64Bit && preferredArchitecture == Architecture.x86) {
if (!is64Bit && preferredArchitecture == Architecture.x86)
{
// 32 bit
yield return new FileInfo(Path.Combine(nativePluginFolder.FullName,
relevantBit.Substring("x86".Length + 1)));
}
else if (is64Bit && (preferredArchitecture == Architecture.x64 ||
preferredArchitecture == Architecture.Unknown)) {
preferredArchitecture == Architecture.Unknown))
{
// 64 bit
yield return new FileInfo(Path.Combine(nativePluginFolder.FullName,
relevantBit.Substring("x86_64".Length + 1)));
}
else {
else
{
// Throw away
yield break;
}
}
else if (!isFlat && isFileFlat) {
else if (!isFlat && isFileFlat)
{
// Deepen structure
yield return new FileInfo(Path.Combine(Path.Combine(nativePluginFolder.FullName, "x86"),
relevantBit));
yield return new FileInfo(Path.Combine(Path.Combine(nativePluginFolder.FullName, "x86_64"),
relevantBit));
}
else {
else
{
yield return to;
}
}
else {
else
{
yield return to;
}
}
@ -317,20 +349,26 @@ namespace IPA {
Console.SetCursorPosition(0, tpos);
}
private static IEnumerable<FileInfo> PassThroughInterceptor(FileInfo from, FileInfo to) {
private static IEnumerable<FileInfo> PassThroughInterceptor(FileInfo from, FileInfo to)
{
yield return to;
}
public static void CopyAll(DirectoryInfo source, DirectoryInfo target, bool aggressive, BackupUnit backup,
Func<FileInfo, FileInfo, IEnumerable<FileInfo>> interceptor = null) {
if (interceptor == null) {
Func<FileInfo, FileInfo, IEnumerable<FileInfo>> interceptor = null)
{
if (interceptor == null)
{
interceptor = PassThroughInterceptor;
}
// Copy each file into the new directory.
foreach (FileInfo fi in source.GetFiles()) {
foreach (var targetFile in interceptor(fi, new FileInfo(Path.Combine(target.FullName, fi.Name)))) {
if (!targetFile.Exists || targetFile.LastWriteTimeUtc < fi.LastWriteTimeUtc || aggressive) {
foreach (FileInfo fi in source.GetFiles())
{
foreach (var targetFile in interceptor(fi, new FileInfo(Path.Combine(target.FullName, fi.Name))))
{
if (!targetFile.Exists || targetFile.LastWriteTimeUtc < fi.LastWriteTimeUtc || aggressive)
{
targetFile.Directory.Create();
Console.CursorTop--;
@ -343,22 +381,25 @@ namespace IPA {
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) {
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = new DirectoryInfo(Path.Combine(target.FullName, diSourceSubDir.Name));
CopyAll(diSourceSubDir, nextTargetSubDir, aggressive, backup, interceptor);
}
}
static void Fail(string message) {
Console.Error.Write("ERROR: " + message);
static void Fail(string message)
{
Console.Error.WriteLine("ERROR: " + message);
WaitForEnd();
Environment.Exit(1);
}
public static string Args(params string[] args) {
public static string Args(params string[] args)
{
return string.Join(" ", args.Select(EncodeParameterArgument).ToArray());
}
@ -368,7 +409,8 @@ namespace IPA {
/// <param name="original">The value that should be received by the program</param>
/// <returns>The value which needs to be passed to the program for the original value
/// to come through</returns>
public static string EncodeParameterArgument(string original) {
public static string EncodeParameterArgument(string original)
{
if (string.IsNullOrEmpty(original))
return original;
string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0");
@ -376,10 +418,13 @@ namespace IPA {
return value;
}
public static Architecture DetectArchitecture(string assembly) {
using (var reader = new BinaryReader(File.OpenRead(assembly))) {
public static Architecture DetectArchitecture(string assembly)
{
using (var reader = new BinaryReader(File.OpenRead(assembly)))
{
var header = reader.ReadUInt16();
if (header == 0x5a4d) {
if (header == 0x5a4d)
{
reader.BaseStream.Seek(60, SeekOrigin.Begin); // this location contains the offset for the PE header
var peOffset = reader.ReadUInt32();
@ -395,16 +440,19 @@ namespace IPA {
else
return Architecture.Unknown;
}
else {
else
{
// Not a supported binary
return Architecture.Unknown;
}
}
}
public abstract class Keyboard {
public abstract class Keyboard
{
[Flags]
private enum KeyStates {
private enum KeyStates
{
None = 0,
Down = 1,
Toggled = 2
@ -413,10 +461,11 @@ namespace IPA {
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern short GetKeyState(int keyCode);
private static KeyStates GetKeyState(Keys key) {
private static KeyStates GetKeyState(Keys key)
{
KeyStates state = KeyStates.None;
short retVal = GetKeyState((int) key);
short retVal = GetKeyState((int)key);
//If the high-order bit is 1, the key is down
//otherwise, it is up.
@ -430,11 +479,13 @@ namespace IPA {
return state;
}
public static bool IsKeyDown(Keys key) {
public static bool IsKeyDown(Keys key)
{
return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
}
public static bool IsKeyToggled(Keys key) {
public static bool IsKeyToggled(Keys key)
{
return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
}
}


+ 2
- 2
IPA/Properties/AssemblyInfo.cs View File

@ -32,5 +32,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.8.9.*")]
[assembly: AssemblyFileVersion("3.8.9")]
[assembly: AssemblyVersion("3.9.0")]
[assembly: AssemblyFileVersion("3.9.0")]

+ 1
- 1
IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache View File

@ -1 +1 @@
854dcf24535098612cfeca06e87fe2b163332578
1d38dd5b9139545c6bc300c735ca121563a74d20

+ 0
- 4
IPA/packages.config View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net462" />
</packages>

+ 0
- 38
IllusionInjector/Bootstrapper.cs View File

@ -1,38 +0,0 @@
using IllusionInjector.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace IllusionInjector
{
class Bootstrapper : MonoBehaviour
{
public event Action Destroyed = delegate {};
void Awake()
{
//if (Environment.CommandLine.Contains("--verbose"))
//{
Windows.GuiConsole.CreateConsole();
//}
Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type)
{
var level = UnityLogInterceptor.LogTypeToLevel(type);
UnityLogInterceptor.Unitylogger.Log(level, $"{condition.Trim()}");
UnityLogInterceptor.Unitylogger.Log(level, $"{stackTrace.Trim()}");
};
}
void Start()
{
Destroy(gameObject);
}
void OnDestroy()
{
Destroyed();
}
}
}

+ 0
- 72
IllusionInjector/ConsoleWindow.cs View File

@ -1,72 +0,0 @@
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace Windows
{
class GuiConsole
{
public static void CreateConsole()
{
if (hasConsole)
return;
if (oldOut == IntPtr.Zero)
oldOut = GetStdHandle( -11 );
if (! AllocConsole())
throw new Exception("AllocConsole() failed");
conOut = CreateFile( "CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero );
if (! SetStdHandle(-11, conOut))
throw new Exception("SetStdHandle() failed");
StreamToConsole();
hasConsole = true;
}
public static void ReleaseConsole()
{
if (! hasConsole)
return;
if (! CloseHandle(conOut))
throw new Exception("CloseHandle() failed");
conOut = IntPtr.Zero;
if (! FreeConsole())
throw new Exception("FreeConsole() failed");
if (! SetStdHandle(-11, oldOut))
throw new Exception("SetStdHandle() failed");
StreamToConsole();
hasConsole = false;
}
private static void StreamToConsole()
{
Stream cstm = Console.OpenStandardOutput();
StreamWriter cstw = new StreamWriter( cstm, Encoding.Default );
cstw.AutoFlush = true;
Console.SetOut( cstw );
Console.SetError( cstw );
}
private static bool hasConsole = false;
private static IntPtr conOut;
private static IntPtr oldOut;
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool AllocConsole();
[DllImport("kernel32.dll", SetLastError=false)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", SetLastError=true)]
private static extern IntPtr GetStdHandle( int nStdHandle );
[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput);
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern IntPtr CreateFile(
string fileName,
int desiredAccess,
int shareMode,
IntPtr securityAttributes,
int creationDisposition,
int flagsAndAttributes,
IntPtr templateFile );
[DllImport("kernel32.dll", ExactSpelling=true, SetLastError=true)]
private static extern bool CloseHandle(IntPtr handle);
}
}

+ 0
- 132
IllusionInjector/IllusionInjector.csproj View File

@ -1,132 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D1C61AF5-0D2D-4752-8203-1C6929025F7C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IllusionInjector</RootNamespace>
<AssemblyName>IllusionInjector</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
<Reference Include="I18N">
<HintPath>..\Libs\I18N.dll</HintPath>
</Reference>
<Reference Include="I18N.West">
<HintPath>..\Libs\I18N.West.dll</HintPath>
</Reference>
<Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL">
<HintPath>..\packages\Ionic.Zip.1.9.1.8\lib\Ionic.Zip.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine">
<HintPath>..\Libs\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\Libs\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UnityWebRequestModule">
<HintPath>..\..\..\..\..\..\Game Library\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\UnityEngine.UnityWebRequestModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Bootstrapper.cs" />
<Compile Include="BeatSaber\CompositeBSPlugin.cs" />
<Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" />
<Compile Include="IPA\CompositeIPAPlugin.cs" />
<Compile Include="Logging\Printers\ColoredConsolePrinter.cs" />
<Compile Include="Logging\Printers\GlobalLogFilePrinter.cs" />
<Compile Include="Logging\Printers\GZFilePrinter.cs" />
<Compile Include="Logging\Printers\PluginLogFilePrinter.cs" />
<Compile Include="Logging\StandardLogger.cs" />
<Compile Include="Logging\UnityLogInterceptor.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PluginComponent.cs" />
<Compile Include="Updating\Backup\BackupUnit.cs" />
<Compile Include="Updating\ModsaberML\ApiEndpoint.cs" />
<Compile Include="Updating\ModsaberML\Updater.cs" />
<Compile Include="Updating\SelfPlugin.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\LoneFunctions.cs" />
<Compile Include="Utilities\SteamCheck.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IllusionPlugin\IllusionPlugin.csproj">
<Project>{e2848bfb-5432-42f4-8ae0-d2ec0cdf2f71}</Project>
<Name>IllusionPlugin</Name>
</ProjectReference>
<ProjectReference Include="..\MSBuildTasks\MSBuildTasks.csproj">
<Project>{f08c3c7a-3221-432e-bab8-32bce58408c8}</Project>
<Name>MSBuildTasks</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="..\Libs\0Harmony.dll">
<Link>IncludedLibs\0Harmony.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\Libs\System.Runtime.Serialization.dll">
<Link>RequiredMonoLibs\System.Runtime.Serialization.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<Target Name="AfterBuild">
<Exec Command="&quot;$(MSBuildBinPath)\MSBuild.exe&quot; &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; /property:OPath=$(OutputPath) /property:Configuration=$(Configuration) /property:SolDir=$(SolutionDir)" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 0
- 34
IllusionInjector/Logging/UnityLogInterceptor.cs View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using LoggerBase = IllusionPlugin.Logging.Logger;
namespace IllusionInjector.Logging
{
public class UnityLogInterceptor
{
public static LoggerBase Unitylogger = new StandardLogger("UnityEngine");
public static LoggerBase.Level LogTypeToLevel(LogType type)
{
switch (type)
{
case LogType.Assert:
return LoggerBase.Level.Debug;
case LogType.Error:
return LoggerBase.Level.Error;
case LogType.Exception:
return LoggerBase.Level.Critical;
case LogType.Log:
return LoggerBase.Level.Info;
case LogType.Warning:
return LoggerBase.Level.Warning;
default:
return LoggerBase.Level.Info;
}
}
}
}

+ 0
- 1
IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache View File

@ -1 +0,0 @@
dae758b90b096a39aa928b136ec952d8ed591e5d

+ 0
- 5
IllusionInjector/packages.config View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Ionic.Zip" version="1.9.1.8" targetFramework="net46" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net46" />
</packages>

+ 0
- 178
IllusionPlugin/IllusionPlugin.XML View File

@ -1,178 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>IllusionPlugin</name>
</assembly>
<members>
<member name="P:IllusionPlugin.IEnhancedPlugin.Filter">
<summary>
Gets a list of executables this plugin should be excuted on (without the file ending)
</summary>
<example>{ "PlayClub", "PlayClubStudio" }</example>
</member>
<member name="T:IllusionPlugin.IniFile">
<summary>
Create a New INI file to store or load data
</summary>
</member>
<member name="M:IllusionPlugin.IniFile.#ctor(System.String)">
<summary>
INIFile Constructor.
</summary>
<PARAM name="INIPath"></PARAM>
</member>
<member name="M:IllusionPlugin.IniFile.IniWriteValue(System.String,System.String,System.String)">
<summary>
Write Data to the INI File
</summary>
<PARAM name="Section"></PARAM>
Section name
<PARAM name="Key"></PARAM>
Key Name
<PARAM name="Value"></PARAM>
Value Name
</member>
<member name="M:IllusionPlugin.IniFile.IniReadValue(System.String,System.String)">
<summary>
Read Data Value From the Ini File
</summary>
<PARAM name="Section"></PARAM>
<PARAM name="Key"></PARAM>
<PARAM name="Path"></PARAM>
<returns></returns>
</member>
<member name="T:IllusionPlugin.IPlugin">
<summary>
Interface for generic Illusion unity plugins. Every class that implements this will be loaded if the DLL is placed at
data/Managed/Plugins.
</summary>
</member>
<member name="P:IllusionPlugin.IPlugin.Name">
<summary>
Gets the name of the plugin.
</summary>
</member>
<member name="P:IllusionPlugin.IPlugin.Version">
<summary>
Gets the version of the plugin.
</summary>
</member>
<member name="M:IllusionPlugin.IPlugin.OnApplicationStart">
<summary>
Gets invoked when the application is started.
</summary>
</member>
<member name="M:IllusionPlugin.IPlugin.OnApplicationQuit">
<summary>
Gets invoked when the application is closed.
</summary>
</member>
<member name="M:IllusionPlugin.IPlugin.OnLevelWasLoaded(System.Int32)">
<summary>
Gets invoked whenever a level is loaded.
</summary>
<param name="level"></param>
</member>
<member name="M:IllusionPlugin.IPlugin.OnLevelWasInitialized(System.Int32)">
<summary>
Gets invoked after the first update cycle after a level was loaded.
</summary>
<param name="level"></param>
</member>
<member name="M:IllusionPlugin.IPlugin.OnUpdate">
<summary>
Gets invoked on every graphic update.
</summary>
</member>
<member name="M:IllusionPlugin.IPlugin.OnFixedUpdate">
<summary>
Gets invoked on ever physics update.
</summary>
</member>
<member name="T:IllusionPlugin.ModPrefs">
<summary>
Allows to get and set preferences for your mod.
</summary>
</member>
<member name="M:IllusionPlugin.ModPrefs.GetString(System.String,System.String,System.String,System.Boolean)">
<summary>
Gets a string from the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="defaultValue">Value that should be used when no value is found.</param>
<param name="autoSave">Whether or not the default value should be written if no value is found.</param>
<returns></returns>
</member>
<member name="M:IllusionPlugin.ModPrefs.GetInt(System.String,System.String,System.Int32,System.Boolean)">
<summary>
Gets an int from the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="defaultValue">Value that should be used when no value is found.</param>
<param name="autoSave">Whether or not the default value should be written if no value is found.</param>
<returns></returns>
</member>
<member name="M:IllusionPlugin.ModPrefs.GetFloat(System.String,System.String,System.Single,System.Boolean)">
<summary>
Gets a float from the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="defaultValue">Value that should be used when no value is found.</param>
<param name="autoSave">Whether or not the default value should be written if no value is found.</param>
<returns></returns>
</member>
<member name="M:IllusionPlugin.ModPrefs.GetBool(System.String,System.String,System.Boolean,System.Boolean)">
<summary>
Gets a bool from the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="defaultValue">Value that should be used when no value is found.</param>
<param name="autoSave">Whether or not the default value should be written if no value is found.</param>
<returns></returns>
</member>
<member name="M:IllusionPlugin.ModPrefs.HasKey(System.String,System.String)">
<summary>
Checks whether or not a key exists in the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<returns></returns>
</member>
<member name="M:IllusionPlugin.ModPrefs.SetFloat(System.String,System.String,System.Single)">
<summary>
Sets a float in the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="value">Value that should be written.</param>
</member>
<member name="M:IllusionPlugin.ModPrefs.SetInt(System.String,System.String,System.Int32)">
<summary>
Sets an int in the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="value">Value that should be written.</param>
</member>
<member name="M:IllusionPlugin.ModPrefs.SetString(System.String,System.String,System.String)">
<summary>
Sets a string in the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="value">Value that should be written.</param>
</member>
<member name="M:IllusionPlugin.ModPrefs.SetBool(System.String,System.String,System.Boolean)">
<summary>
Sets a bool in the ini.
</summary>
<param name="section">Section of the key.</param>
<param name="name">Name of the key.</param>
<param name="value">Value that should be written.</param>
</member>
</members>
</doc>

+ 0
- 69
IllusionPlugin/IllusionPlugin.csproj View File

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IllusionPlugin</RootNamespace>
<AssemblyName>IllusionPlugin</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\IllusionPlugin.XML</DocumentationFile>
<Prefer32Bit>false</Prefer32Bit>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\Libs\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BeatSaber\IEnhancedBeatSaberPlugin.cs" />
<Compile Include="BeatSaber\ModsaberModInfo.cs" />
<Compile Include="IniFile.cs" />
<Compile Include="BeatSaber\IBeatSaberPlugin.cs" />
<Compile Include="IPA\IEnhancedPlugin.cs" />
<Compile Include="IGenericEnhancedPlugin.cs" />
<Compile Include="IPA\IPlugin.cs" />
<Compile Include="Logging\LogPrinter.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="ModPrefs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils\ReflectionUtil.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 0
- 1
IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache View File

@ -1 +0,0 @@
77d5fd2376e4df56c59ee712f4f804807c24fc6f

Loading…
Cancel
Save