Browse Source

removed `Launcher` from remote`

pull/46/head
artman41 6 years ago
parent
commit
ae26ee5d62
30 changed files with 1596 additions and 2225 deletions
  1. +39
    -39
      IPA.Tests/ProgramTest.cs
  2. +45
    -45
      IPA.sln
  3. +96
    -96
      IPA/IPA.csproj
  4. +58
    -58
      IPA/PatchContext.cs
  5. +103
    -103
      IPA/Patcher/Patcher.cs
  6. +387
    -387
      IPA/Program.cs
  7. +36
    -36
      IPA/Properties/AssemblyInfo.cs
  8. +1
    -1
      IPA/obj/Debug/IPA.csproj.CoreCompileInputs.cache
  9. +134
    -134
      IllusionInjector/CompositePlugin.cs
  10. +68
    -68
      IllusionInjector/IllusionInjector.csproj
  11. +96
    -96
      IllusionInjector/PluginComponent.cs
  12. +154
    -154
      IllusionInjector/PluginManager.cs
  13. +1
    -1
      IllusionInjector/obj/Debug/IllusionInjector.csproj.CoreCompileInputs.cache
  14. +50
    -50
      IllusionPlugin/IPlugin.cs
  15. +59
    -59
      IllusionPlugin/IllusionPlugin.csproj
  16. +101
    -101
      IllusionPlugin/IniFile.cs
  17. +167
    -167
      IllusionPlugin/ModPrefs.cs
  18. +1
    -1
      IllusionPlugin/obj/Debug/IllusionPlugin.csproj.CoreCompileInputs.cache
  19. +0
    -91
      Launcher/Launcher.csproj
  20. +0
    -100
      Launcher/Program.cs
  21. +0
    -36
      Launcher/Properties/AssemblyInfo.cs
  22. +0
    -63
      Launcher/Properties/Resources.Designer.cs
  23. +0
    -117
      Launcher/Properties/Resources.resx
  24. +0
    -26
      Launcher/Properties/Settings.Designer.cs
  25. +0
    -7
      Launcher/Properties/Settings.settings
  26. +0
    -63
      Launcher/Resources.Designer.cs
  27. +0
    -121
      Launcher/Resources.resx
  28. +0
    -1
      Launcher/obj/Debug/Launcher.csproj.CoreCompileInputs.cache
  29. +0
    -4
      Launcher/packages.config
  30. BIN
      Launcher/syringe.ico

+ 39
- 39
IPA.Tests/ProgramTest.cs View File

@ -1,39 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace IPA.Tests
{
public class ProgramTest
{
[Theory]
// Unrelated path
[InlineData("test/from.dll", "test/to.dll", "native", false, new string[] { "test/to.dll" })]
// Flat -> Not-Flat
[InlineData("native/from.dll", "native/to.dll", "native", false, new string[] { "native/x86/to.dll", "native/x86_64/to.dll" })]
// Flat -> Flat
[InlineData("native/from.dll", "native/to.dll", "native", true, new string[] { "native/to.dll" })]
// Not-Flat -> Flat
[InlineData("native/x86/from.dll", "native/x86/to.dll", "native", true, new string[] { })]
[InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", true, new string[] { "native/to.dll" })]
// Not-flat -> Not-Flat
[InlineData("native/x86/from.dll", "native/x86/to.dll", "native", false, new string[] { "native/x86/to.dll" })]
[InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", false, new string[] { "native/x86_64/to.dll" })]
public void CopiesCorrectly(string from, string to, string nativeFolder, bool isFlat, string[] expected)
{
var outcome = Program.NativePluginInterceptor(new FileInfo(from), new FileInfo(to), new DirectoryInfo(nativeFolder), isFlat, Program.Architecture.Unknown).Select(f => f.FullName).ToList();
var expectedPaths = expected.Select(e => new FileInfo(e)).Select(f => f.FullName).ToList();
Assert.Equal(expectedPaths, outcome);
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace IPA.Tests
{
public class ProgramTest
{
[Theory]
// Unrelated path
[InlineData("test/from.dll", "test/to.dll", "native", false, new string[] { "test/to.dll" })]
// Flat -> Not-Flat
[InlineData("native/from.dll", "native/to.dll", "native", false, new string[] { "native/x86/to.dll", "native/x86_64/to.dll" })]
// Flat -> Flat
[InlineData("native/from.dll", "native/to.dll", "native", true, new string[] { "native/to.dll" })]
// Not-Flat -> Flat
[InlineData("native/x86/from.dll", "native/x86/to.dll", "native", true, new string[] { })]
[InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", true, new string[] { "native/to.dll" })]
// Not-flat -> Not-Flat
[InlineData("native/x86/from.dll", "native/x86/to.dll", "native", false, new string[] { "native/x86/to.dll" })]
[InlineData("native/x86_64/from.dll", "native/x86_64/to.dll", "native", false, new string[] { "native/x86_64/to.dll" })]
public void CopiesCorrectly(string from, string to, string nativeFolder, bool isFlat, string[] expected)
{
var outcome = Program.NativePluginInterceptor(new FileInfo(from), new FileInfo(to), new DirectoryInfo(nativeFolder), isFlat, Program.Architecture.Unknown).Select(f => f.FullName).ToList();
var expectedPaths = expected.Select(e => new FileInfo(e)).Select(f => f.FullName).ToList();
Assert.Equal(expectedPaths, outcome);
}
}
}

+ 45
- 45
IPA.sln View File

@ -1,45 +1,45 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA", "IPA\IPA.csproj", "{14092533-98BB-40A4-9AFC-27BB75672A70}"
ProjectSection(ProjectDependencies) = postProject
{D1390268-F68B-4A55-B50D-EAD25756C8EF} = {D1390268-F68B-4A55-B50D-EAD25756C8EF}
{D1C61AF5-0D2D-4752-8203-1C6929025F7C} = {D1C61AF5-0D2D-4752-8203-1C6929025F7C}
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71} = {E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{14092533-98BB-40A4-9AFC-27BB75672A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPA", "IPA\IPA.csproj", "{14092533-98BB-40A4-9AFC-27BB75672A70}"
ProjectSection(ProjectDependencies) = postProject
{D1390268-F68B-4A55-B50D-EAD25756C8EF} = {D1390268-F68B-4A55-B50D-EAD25756C8EF}
{D1C61AF5-0D2D-4752-8203-1C6929025F7C} = {D1C61AF5-0D2D-4752-8203-1C6929025F7C}
{E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71} = {E2848BFB-5432-42F4-8AE0-D2EC0CDF2F71}
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{14092533-98BB-40A4-9AFC-27BB75672A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
{C66092B0-5C1E-44E9-B524-E0E8E1425379}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

+ 96
- 96
IPA/IPA.csproj View File

@ -1,97 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.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>{14092533-98BB-40A4-9AFC-27BB75672A70}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IPA</RootNamespace>
<AssemblyName>IPA</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</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\net35\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\net35\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\net35\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\net35\Mono.Cecil.Rocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PatchContext.cs" />
<Compile Include="Patcher\BackupManager.cs" />
<Compile Include="Patcher\BackupUnit.cs" />
<Compile Include="Patcher\Patcher.cs" />
<Compile Include="Patcher\Virtualizer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Shortcut.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="IPA\Fallback\" />
</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>
-->
<Target Name="AfterBuild">
<Message Text="Packing..." Importance="normal" />
<ItemGroup>
<Dlls Include="$(SolutionDir)IllusionInjector\$(OutDir)**\*" />
</ItemGroup>
<Copy SourceFiles="@(Dlls)" DestinationFolder="$(OutputPath)IPA\Data\Managed" />
</Target>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.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>{14092533-98BB-40A4-9AFC-27BB75672A70}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IPA</RootNamespace>
<AssemblyName>IPA</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</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\net35\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\net35\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\net35\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\net35\Mono.Cecil.Rocks.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PatchContext.cs" />
<Compile Include="Patcher\BackupManager.cs" />
<Compile Include="Patcher\BackupUnit.cs" />
<Compile Include="Patcher\Patcher.cs" />
<Compile Include="Patcher\Virtualizer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Shortcut.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<ItemGroup>
<Folder Include="IPA\Fallback\" />
</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>
-->
<Target Name="AfterBuild">
<Message Text="Packing..." Importance="normal" />
<ItemGroup>
<Dlls Include="$(SolutionDir)IllusionInjector\$(OutDir)**\*" />
</ItemGroup>
<Copy SourceFiles="@(Dlls)" DestinationFolder="$(OutputPath)IPA\Data\Managed" />
</Target>
</Project>

+ 58
- 58
IPA/PatchContext.cs View File

@ -1,58 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IPA
{
public class PatchContext
{
/// <summary>
/// Gets the filename of the executable.
/// </summary>
public string Executable { get; private set; }
public string DataPathSrc { get; private set; }
public string PluginsFolder { get; private set; }
public string ProjectName { get; private set; }
public string DataPathDst { get; private set; }
public string ManagedPath { get; private set; }
public string EngineFile { get; private set; }
public string AssemblyFile { get; private set; }
public string[] Args { get; private set; }
public string ProjectRoot { get; private set; }
public string IPARoot { get; private set; }
public string ShortcutPath { get; private set; }
public string IPA { get; private set; }
public string BackupPath { get; private set; }
private PatchContext() { }
public static PatchContext Create(String[] args)
{
var context = new PatchContext();
context.Args = args;
context.Executable = args[0];
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.DataPathSrc = Path.Combine(context.IPARoot, "Data");
context.PluginsFolder = Path.Combine(context.ProjectRoot, "Plugins");
context.ProjectName = Path.GetFileNameWithoutExtension(context.Executable);
context.DataPathDst = Path.Combine(context.ProjectRoot, context.ProjectName + "_Data");
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);
string shortcutName = $"{context.ProjectName} (Patch & Launch)";
context.ShortcutPath = Path.Combine(context.ProjectRoot, shortcutName) + ".lnk";
Directory.CreateDirectory(context.BackupPath);
return context;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IPA
{
public class PatchContext
{
/// <summary>
/// Gets the filename of the executable.
/// </summary>
public string Executable { get; private set; }
public string DataPathSrc { get; private set; }
public string PluginsFolder { get; private set; }
public string ProjectName { get; private set; }
public string DataPathDst { get; private set; }
public string ManagedPath { get; private set; }
public string EngineFile { get; private set; }
public string AssemblyFile { get; private set; }
public string[] Args { get; private set; }
public string ProjectRoot { get; private set; }
public string IPARoot { get; private set; }
public string ShortcutPath { get; private set; }
public string IPA { get; private set; }
public string BackupPath { get; private set; }
private PatchContext() { }
public static PatchContext Create(String[] args)
{
var context = new PatchContext();
context.Args = args;
context.Executable = args[0];
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.DataPathSrc = Path.Combine(context.IPARoot, "Data");
context.PluginsFolder = Path.Combine(context.ProjectRoot, "Plugins");
context.ProjectName = Path.GetFileNameWithoutExtension(context.Executable);
context.DataPathDst = Path.Combine(context.ProjectRoot, context.ProjectName + "_Data");
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);
string shortcutName = $"{context.ProjectName} (Patch & Launch)";
context.ShortcutPath = Path.Combine(context.ProjectRoot, shortcutName) + ".lnk";
Directory.CreateDirectory(context.BackupPath);
return context;
}
}
}

+ 103
- 103
IPA/Patcher/Patcher.cs View File

@ -1,103 +1,103 @@
using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace IPA.Patcher
{
class PatchedModule
{
private static readonly string[] ENTRY_TYPES = { "Input", "Display" };
private FileInfo _File;
private ModuleDefinition _Module;
internal struct PatchData {
public bool IsPatched;
public Version Version;
}
public static PatchedModule Load(string engineFile)
{
return new PatchedModule(engineFile);
}
private PatchedModule(string engineFile)
{
_File = new FileInfo(engineFile);
LoadModules();
}
private void LoadModules()
{
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(_File.DirectoryName);
var parameters = new ReaderParameters
{
AssemblyResolver = resolver,
};
_Module = ModuleDefinition.ReadModule(_File.FullName, parameters);
}
public PatchData Data
{
get
{
foreach (var @ref in _Module.AssemblyReferences) {
if (@ref.Name == "IllusionInjector") return new PatchData { IsPatched = true, Version = @ref.Version};
}
return new PatchData { IsPatched = false, Version = null};
}
}
public void Patch(Version v)
{
// First, let's add the reference
var nameReference = new AssemblyNameReference("IllusionInjector", v);
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
var injector = ModuleDefinition.ReadModule(injectorPath);
_Module.AssemblyReferences.Add(nameReference);
int patched = 0;
foreach(var type in FindEntryTypes())
{
if(PatchType(type, injector))
{
patched++;
}
}
if(patched > 0)
{
_Module.Write(_File.FullName);
} else
{
throw new Exception("Could not find any entry type!");
}
}
private bool PatchType(TypeDefinition targetType, ModuleDefinition injector)
{
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"));
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
return true;
}
return false;
}
private IEnumerable<TypeDefinition> FindEntryTypes()
{
return _Module.GetTypes().Where(m => ENTRY_TYPES.Contains(m.Name));
}
}
}
using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace IPA.Patcher
{
class PatchedModule
{
private static readonly string[] ENTRY_TYPES = { "Input", "Display" };
private FileInfo _File;
private ModuleDefinition _Module;
internal struct PatchData {
public bool IsPatched;
public Version Version;
}
public static PatchedModule Load(string engineFile)
{
return new PatchedModule(engineFile);
}
private PatchedModule(string engineFile)
{
_File = new FileInfo(engineFile);
LoadModules();
}
private void LoadModules()
{
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(_File.DirectoryName);
var parameters = new ReaderParameters
{
AssemblyResolver = resolver,
};
_Module = ModuleDefinition.ReadModule(_File.FullName, parameters);
}
public PatchData Data
{
get
{
foreach (var @ref in _Module.AssemblyReferences) {
if (@ref.Name == "IllusionInjector") return new PatchData { IsPatched = true, Version = @ref.Version};
}
return new PatchData { IsPatched = false, Version = null};
}
}
public void Patch(Version v)
{
// First, let's add the reference
var nameReference = new AssemblyNameReference("IllusionInjector", v);
var injectorPath = Path.Combine(_File.DirectoryName, "IllusionInjector.dll");
var injector = ModuleDefinition.ReadModule(injectorPath);
_Module.AssemblyReferences.Add(nameReference);
int patched = 0;
foreach(var type in FindEntryTypes())
{
if(PatchType(type, injector))
{
patched++;
}
}
if(patched > 0)
{
_Module.Write(_File.FullName);
} else
{
throw new Exception("Could not find any entry type!");
}
}
private bool PatchType(TypeDefinition targetType, ModuleDefinition injector)
{
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"));
targetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference));
return true;
}
return false;
}
private IEnumerable<TypeDefinition> FindEntryTypes()
{
return _Module.GetTypes().Where(m => ENTRY_TYPES.Contains(m.Name));
}
}
}

+ 387
- 387
IPA/Program.cs View File

@ -1,388 +1,388 @@
using IPA.Patcher;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace IPA {
public class Program {
public enum Architecture {
x86,
x64,
Unknown
}
private static Version Version => new Version(Application.ProductVersion);
static void Main(string[] args) {
PatchContext context;
if (args.Length < 1 || !args[0].EndsWith(".exe")) {
//Fail("Drag an (executable) file on the exe!");
context = PatchContext.Create(new[] {
new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles()
.First(o => o.FullName.EndsWith(".exe"))
.FullName
});
}
else {
context = PatchContext.Create(args);
}
try {
bool isRevert = args.Contains("--revert") || Keyboard.IsKeyDown(Keys.LMenu);
// Sanitizing
Validate(context);
if (isRevert) {
Revert(context);
}
else {
Install(context);
StartIfNeedBe(context);
}
}
catch (Exception e) {
Fail(e.Message);
}
}
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 {
var backup = new BackupUnit(context);
#region Patch Version Check
var patchedModule = PatchedModule.Load(context.EngineFile);
var isCurrentNewer = Version.CompareTo(patchedModule.Data.Version) > 0;
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, new[] {"newVersion"});
Console.ResetColor();
#region File Copying
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("Updating files... ");
var nativePluginFolder = Path.Combine(context.DataPathDst, "Plugins");
bool isFlat = Directory.Exists(nativePluginFolder) &&
Directory.GetFiles(nativePluginFolder).Any(f => f.EndsWith(".dll"));
bool force = !BackupManager.HasBackup(context) || context.Args.Contains("-f") ||
context.Args.Contains("--force");
var architecture = DetectArchitecture(context.Executable);
Console.WriteLine("Architecture: {0}", architecture);
CopyAll(new DirectoryInfo(context.DataPathSrc), new DirectoryInfo(context.DataPathDst), force,
backup,
(from, to) => NativePluginInterceptor(from, to, new DirectoryInfo(nativePluginFolder), isFlat,
architecture));
Console.WriteLine("Successfully updated files!");
#endregion
}
else {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Files up to date @ Version {Version}!");
Console.ResetColor();
}
#endregion
#region Create Plugin Folder
if (!Directory.Exists(context.PluginsFolder)) {
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Creating plugins folder... ");
Directory.CreateDirectory(context.PluginsFolder);
Console.ResetColor();
}
#endregion
#region Patching
if (!patchedModule.Data.IsPatched || isCurrentNewer) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Patching UnityEngine.dll with Version {Application.ProductVersion}... ");
backup.Add(context.EngineFile);
patchedModule.Patch(Version);
Console.WriteLine("Done!");
Console.ResetColor();
}
#endregion
#region Virtualizing
if (File.Exists(context.AssemblyFile)) {
var virtualizedModule = VirtualizedModule.Load(context.AssemblyFile);
if (!virtualizedModule.IsVirtualized) {
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Virtualizing Assembly-Csharp.dll... ");
backup.Add(context.AssemblyFile);
virtualizedModule.Virtualize();
Console.WriteLine("Done!");
Console.ResetColor();
}
}
#endregion
#region Creating shortcut
/*if(!File.Exists(context.ShortcutPath))
{
Console.Write("Creating shortcut to IPA ({0})... ", context.IPA);
try
{
Shortcut.Create(
fileName: context.ShortcutPath,
targetPath: context.IPA,
arguments: Args(context.Executable, "--launch"),
workingDirectory: context.ProjectRoot,
description: "Launches the game and makes sure it's in a patched state",
hotkey: "",
iconPath: context.Executable
);
Console.WriteLine("Created");
} catch (Exception e)
{
Console.Error.WriteLine("Failed to create shortcut, but game was patched!");
}
}*/
#endregion
}
catch (Exception e) {
Fail("Oops! This should not have happened.\n\n" + e);
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Finished!");
Console.ResetColor();
Console.ReadLine();
}
private static void Revert(PatchContext context, string[] args = null) {
Console.ForegroundColor = ConsoleColor.Cyan;
bool isNewVersion = (args != null && args.Contains("newVersion"));
Console.Write("Restoring backup... ");
if (BackupManager.Restore(context)) {
Console.WriteLine("Done!");
}
else {
Console.WriteLine("Already vanilla!");
}
if (File.Exists(context.ShortcutPath)) {
Console.WriteLine("Deleting shortcut...");
File.Delete(context.ShortcutPath);
}
Console.WriteLine("");
Console.WriteLine("--- Done reverting ---");
if (!Environment.CommandLine.Contains("--nowait") && !isNewVersion) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
Console.ResetColor();
}
private static void StartIfNeedBe(PatchContext context) {
var argList = context.Args.ToList();
bool launch = argList.Remove("--launch");
argList.RemoveAt(0);
if (launch) {
Process.Start(context.Executable, Args(argList.ToArray()));
}
}
public static IEnumerable<FileInfo> NativePluginInterceptor(FileInfo from, FileInfo to,
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) {
// Flatten structure
bool is64Bit = relevantBit.StartsWith("x86_64");
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)) {
// 64 bit
yield return new FileInfo(Path.Combine(nativePluginFolder.FullName,
relevantBit.Substring("x86_64".Length + 1)));
}
else {
// Throw away
yield break;
}
}
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 {
yield return to;
}
}
else {
yield return 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) {
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) {
targetFile.Directory.Create();
Console.WriteLine(@"Copying {0}", targetFile.FullName);
backup.Add(targetFile);
fi.CopyTo(targetFile.FullName, true);
}
}
}
// Copy each subdirectory using recursion.
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);
if (!Environment.CommandLine.Contains("--nowait")) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
Environment.Exit(1);
}
public static string Args(params string[] args) {
return string.Join(" ", args.Select(EncodeParameterArgument).ToArray());
}
/// <summary>
/// Encodes an argument for passing into a program
/// </summary>
/// <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) {
if (string.IsNullOrEmpty(original))
return original;
string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0");
value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"");
return value;
}
public static Architecture DetectArchitecture(string assembly) {
using (var reader = new BinaryReader(File.OpenRead(assembly))) {
var header = reader.ReadUInt16();
if (header == 0x5a4d) {
reader.BaseStream.Seek(60, SeekOrigin.Begin); // this location contains the offset for the PE header
var peOffset = reader.ReadUInt32();
reader.BaseStream.Seek(peOffset + 4, SeekOrigin.Begin);
var machine = reader.ReadUInt16();
if (machine == 0x8664) // IMAGE_FILE_MACHINE_AMD64
return Architecture.x64;
else if (machine == 0x014c) // IMAGE_FILE_MACHINE_I386
return Architecture.x86;
else if (machine == 0x0200) // IMAGE_FILE_MACHINE_IA64
return Architecture.x64;
else
return Architecture.Unknown;
}
else {
// Not a supported binary
return Architecture.Unknown;
}
}
}
public abstract class Keyboard {
[Flags]
private enum KeyStates {
None = 0,
Down = 1,
Toggled = 2
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern short GetKeyState(int keyCode);
private static KeyStates GetKeyState(Keys key) {
KeyStates state = KeyStates.None;
short retVal = GetKeyState((int) key);
//If the high-order bit is 1, the key is down
//otherwise, it is up.
if ((retVal & 0x8000) == 0x8000)
state |= KeyStates.Down;
//If the low-order bit is 1, the key is toggled.
if ((retVal & 1) == 1)
state |= KeyStates.Toggled;
return state;
}
public static bool IsKeyDown(Keys key) {
return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
}
public static bool IsKeyToggled(Keys key) {
return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
}
}
}
using IPA.Patcher;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace IPA {
public class Program {
public enum Architecture {
x86,
x64,
Unknown
}
private static Version Version => new Version(Application.ProductVersion);
static void Main(string[] args) {
PatchContext context;
if (args.Length < 1 || !args[0].EndsWith(".exe")) {
//Fail("Drag an (executable) file on the exe!");
context = PatchContext.Create(new[] {
new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles()
.First(o => o.FullName.EndsWith(".exe"))
.FullName
});
}
else {
context = PatchContext.Create(args);
}
try {
bool isRevert = args.Contains("--revert") || Keyboard.IsKeyDown(Keys.LMenu);
// Sanitizing
Validate(context);
if (isRevert) {
Revert(context);
}
else {
Install(context);
StartIfNeedBe(context);
}
}
catch (Exception e) {
Fail(e.Message);
}
}
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 {
var backup = new BackupUnit(context);
#region Patch Version Check
var patchedModule = PatchedModule.Load(context.EngineFile);
var isCurrentNewer = Version.CompareTo(patchedModule.Data.Version) > 0;
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, new[] {"newVersion"});
Console.ResetColor();
#region File Copying
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine("Updating files... ");
var nativePluginFolder = Path.Combine(context.DataPathDst, "Plugins");
bool isFlat = Directory.Exists(nativePluginFolder) &&
Directory.GetFiles(nativePluginFolder).Any(f => f.EndsWith(".dll"));
bool force = !BackupManager.HasBackup(context) || context.Args.Contains("-f") ||
context.Args.Contains("--force");
var architecture = DetectArchitecture(context.Executable);
Console.WriteLine("Architecture: {0}", architecture);
CopyAll(new DirectoryInfo(context.DataPathSrc), new DirectoryInfo(context.DataPathDst), force,
backup,
(from, to) => NativePluginInterceptor(from, to, new DirectoryInfo(nativePluginFolder), isFlat,
architecture));
Console.WriteLine("Successfully updated files!");
#endregion
}
else {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Files up to date @ Version {Version}!");
Console.ResetColor();
}
#endregion
#region Create Plugin Folder
if (!Directory.Exists(context.PluginsFolder)) {
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Creating plugins folder... ");
Directory.CreateDirectory(context.PluginsFolder);
Console.ResetColor();
}
#endregion
#region Patching
if (!patchedModule.Data.IsPatched || isCurrentNewer) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Patching UnityEngine.dll with Version {Application.ProductVersion}... ");
backup.Add(context.EngineFile);
patchedModule.Patch(Version);
Console.WriteLine("Done!");
Console.ResetColor();
}
#endregion
#region Virtualizing
if (File.Exists(context.AssemblyFile)) {
var virtualizedModule = VirtualizedModule.Load(context.AssemblyFile);
if (!virtualizedModule.IsVirtualized) {
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Virtualizing Assembly-Csharp.dll... ");
backup.Add(context.AssemblyFile);
virtualizedModule.Virtualize();
Console.WriteLine("Done!");
Console.ResetColor();
}
}
#endregion
#region Creating shortcut
/*if(!File.Exists(context.ShortcutPath))
{
Console.Write("Creating shortcut to IPA ({0})... ", context.IPA);
try
{
Shortcut.Create(
fileName: context.ShortcutPath,
targetPath: context.IPA,
arguments: Args(context.Executable, "--launch"),
workingDirectory: context.ProjectRoot,
description: "Launches the game and makes sure it's in a patched state",
hotkey: "",
iconPath: context.Executable
);
Console.WriteLine("Created");
} catch (Exception e)
{
Console.Error.WriteLine("Failed to create shortcut, but game was patched!");
}
}*/
#endregion
}
catch (Exception e) {
Fail("Oops! This should not have happened.\n\n" + e);
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Finished!");
Console.ResetColor();
Console.ReadLine();
}
private static void Revert(PatchContext context, string[] args = null) {
Console.ForegroundColor = ConsoleColor.Cyan;
bool isNewVersion = (args != null && args.Contains("newVersion"));
Console.Write("Restoring backup... ");
if (BackupManager.Restore(context)) {
Console.WriteLine("Done!");
}
else {
Console.WriteLine("Already vanilla!");
}
if (File.Exists(context.ShortcutPath)) {
Console.WriteLine("Deleting shortcut...");
File.Delete(context.ShortcutPath);
}
Console.WriteLine("");
Console.WriteLine("--- Done reverting ---");
if (!Environment.CommandLine.Contains("--nowait") && !isNewVersion) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
Console.ResetColor();
}
private static void StartIfNeedBe(PatchContext context) {
var argList = context.Args.ToList();
bool launch = argList.Remove("--launch");
argList.RemoveAt(0);
if (launch) {
Process.Start(context.Executable, Args(argList.ToArray()));
}
}
public static IEnumerable<FileInfo> NativePluginInterceptor(FileInfo from, FileInfo to,
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) {
// Flatten structure
bool is64Bit = relevantBit.StartsWith("x86_64");
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)) {
// 64 bit
yield return new FileInfo(Path.Combine(nativePluginFolder.FullName,
relevantBit.Substring("x86_64".Length + 1)));
}
else {
// Throw away
yield break;
}
}
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 {
yield return to;
}
}
else {
yield return 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) {
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) {
targetFile.Directory.Create();
Console.WriteLine(@"Copying {0}", targetFile.FullName);
backup.Add(targetFile);
fi.CopyTo(targetFile.FullName, true);
}
}
}
// Copy each subdirectory using recursion.
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);
if (!Environment.CommandLine.Contains("--nowait")) {
Console.WriteLine("\n\n[Press any key to quit]");
Console.ReadKey();
}
Environment.Exit(1);
}
public static string Args(params string[] args) {
return string.Join(" ", args.Select(EncodeParameterArgument).ToArray());
}
/// <summary>
/// Encodes an argument for passing into a program
/// </summary>
/// <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) {
if (string.IsNullOrEmpty(original))
return original;
string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0");
value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"");
return value;
}
public static Architecture DetectArchitecture(string assembly) {
using (var reader = new BinaryReader(File.OpenRead(assembly))) {
var header = reader.ReadUInt16();
if (header == 0x5a4d) {
reader.BaseStream.Seek(60, SeekOrigin.Begin); // this location contains the offset for the PE header
var peOffset = reader.ReadUInt32();
reader.BaseStream.Seek(peOffset + 4, SeekOrigin.Begin);
var machine = reader.ReadUInt16();
if (machine == 0x8664) // IMAGE_FILE_MACHINE_AMD64
return Architecture.x64;
else if (machine == 0x014c) // IMAGE_FILE_MACHINE_I386
return Architecture.x86;
else if (machine == 0x0200) // IMAGE_FILE_MACHINE_IA64
return Architecture.x64;
else
return Architecture.Unknown;
}
else {
// Not a supported binary
return Architecture.Unknown;
}
}
}
public abstract class Keyboard {
[Flags]
private enum KeyStates {
None = 0,
Down = 1,
Toggled = 2
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern short GetKeyState(int keyCode);
private static KeyStates GetKeyState(Keys key) {
KeyStates state = KeyStates.None;
short retVal = GetKeyState((int) key);
//If the high-order bit is 1, the key is down
//otherwise, it is up.
if ((retVal & 0x8000) == 0x8000)
state |= KeyStates.Down;
//If the low-order bit is 1, the key is toggled.
if ((retVal & 1) == 1)
state |= KeyStates.Toggled;
return state;
}
public static bool IsKeyDown(Keys key) {
return KeyStates.Down == (GetKeyState(key) & KeyStates.Down);
}
public static bool IsKeyToggled(Keys key) {
return KeyStates.Toggled == (GetKeyState(key) & KeyStates.Toggled);
}
}
}
}

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

@ -1,36 +1,36 @@
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("Illusion Plugin Architecture")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Illusion Plugin Architecture")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[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("14092533-98bb-40a4-9afc-27bb75672a70")]
// 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.7")]
[assembly: AssemblyFileVersion("3.7")]
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("Illusion Plugin Architecture")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Illusion Plugin Architecture")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[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("14092533-98bb-40a4-9afc-27bb75672a70")]
// 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.7")]
[assembly: AssemblyFileVersion("3.7")]

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

@ -1 +1 @@
f7c20aca6b99cd3b62d50a05d9bdca1eb41dca2a
65c33cfc23e8dcfc89c7fd78e8cd8344a2518294

+ 134
- 134
IllusionInjector/CompositePlugin.cs View File

@ -1,135 +1,135 @@
using IllusionPlugin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionPlugin.Logger;
namespace IllusionInjector {
public class CompositePlugin : IPlugin {
IEnumerable<IPlugin> plugins;
private delegate void CompositeCall(IPlugin plugin);
private Logger debugLogger => PluginManager.debugLogger;
public CompositePlugin(IEnumerable<IPlugin> plugins) {
this.plugins = plugins;
}
public void OnApplicationStart() {
Invoke(plugin => plugin.OnApplicationStart());
}
public void OnApplicationQuit() {
Invoke(plugin => plugin.OnApplicationQuit());
}
public void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnSceneLoaded(scene, sceneMode);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnSceneUnloaded(Scene scene) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnSceneUnloaded(scene);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnActiveSceneChanged(prevScene, nextScene);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
private void Invoke(CompositeCall callback) {
foreach (var plugin in plugins) {
try {
callback(plugin);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnUpdate() {
Invoke(plugin => plugin.OnUpdate());
}
public void OnFixedUpdate() {
Invoke(plugin => plugin.OnFixedUpdate());
}
[Obsolete("Use OnSceneLoaded instead")]
public void OnLevelWasLoaded(int level)
{
foreach (var plugin in plugins)
{
try
{
plugin.OnLevelWasLoaded(level);
}
catch (Exception ex)
{
Console.WriteLine("{0}: {1}", plugin.Name, ex);
}
}
}
[Obsolete("Use OnSceneLoaded instead")]
public void OnLevelWasInitialized(int level)
{
foreach (var plugin in plugins)
{
try
{
plugin.OnLevelWasInitialized(level);
}
catch (Exception ex)
{
Console.WriteLine("{0}: {1}", plugin.Name, ex);
}
}
}
public string Name {
get { throw new NotImplementedException(); }
}
public string Version {
get { throw new NotImplementedException(); }
}
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedPlugin)
((IEnhancedPlugin) plugin).OnLateUpdate();
});
}
}
using IllusionPlugin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
using Logger = IllusionPlugin.Logger;
namespace IllusionInjector {
public class CompositePlugin : IPlugin {
IEnumerable<IPlugin> plugins;
private delegate void CompositeCall(IPlugin plugin);
private Logger debugLogger => PluginManager.debugLogger;
public CompositePlugin(IEnumerable<IPlugin> plugins) {
this.plugins = plugins;
}
public void OnApplicationStart() {
Invoke(plugin => plugin.OnApplicationStart());
}
public void OnApplicationQuit() {
Invoke(plugin => plugin.OnApplicationQuit());
}
public void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnSceneLoaded(scene, sceneMode);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnSceneUnloaded(Scene scene) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnSceneUnloaded(scene);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
foreach (var plugin1 in plugins.Where(o => o is IPluginNew)) {
var plugin = (IPluginNew) plugin1;
try {
plugin.OnActiveSceneChanged(prevScene, nextScene);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
private void Invoke(CompositeCall callback) {
foreach (var plugin in plugins) {
try {
callback(plugin);
}
catch (Exception ex) {
debugLogger.Exception($"{plugin.Name}: {ex}");
}
}
}
public void OnUpdate() {
Invoke(plugin => plugin.OnUpdate());
}
public void OnFixedUpdate() {
Invoke(plugin => plugin.OnFixedUpdate());
}
[Obsolete("Use OnSceneLoaded instead")]
public void OnLevelWasLoaded(int level)
{
foreach (var plugin in plugins)
{
try
{
plugin.OnLevelWasLoaded(level);
}
catch (Exception ex)
{
Console.WriteLine("{0}: {1}", plugin.Name, ex);
}
}
}
[Obsolete("Use OnSceneLoaded instead")]
public void OnLevelWasInitialized(int level)
{
foreach (var plugin in plugins)
{
try
{
plugin.OnLevelWasInitialized(level);
}
catch (Exception ex)
{
Console.WriteLine("{0}: {1}", plugin.Name, ex);
}
}
}
public string Name {
get { throw new NotImplementedException(); }
}
public string Version {
get { throw new NotImplementedException(); }
}
public void OnLateUpdate() {
Invoke(plugin => {
if (plugin is IEnhancedPlugin)
((IEnhancedPlugin) plugin).OnLateUpdate();
});
}
}
}

+ 68
- 68
IllusionInjector/IllusionInjector.csproj View File

@ -1,69 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.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>v3.5</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>
</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>
</PropertyGroup>
<ItemGroup>
<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>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Bootstrapper.cs" />
<Compile Include="CompositePlugin.cs" />
<Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PluginComponent.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IllusionPlugin\IllusionPlugin.csproj">
<Project>{e2848bfb-5432-42f4-8ae0-d2ec0cdf2f71}</Project>
<Name>IllusionPlugin</Name>
</ProjectReference>
</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>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.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>v3.5</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>
</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>
</PropertyGroup>
<ItemGroup>
<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>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Bootstrapper.cs" />
<Compile Include="CompositePlugin.cs" />
<Compile Include="ConsoleWindow.cs" />
<Compile Include="Injector.cs" />
<Compile Include="PluginManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PluginComponent.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IllusionPlugin\IllusionPlugin.csproj">
<Project>{e2848bfb-5432-42f4-8ae0-d2ec0cdf2f71}</Project>
<Name>IllusionPlugin</Name>
</ProjectReference>
</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>

+ 96
- 96
IllusionInjector/PluginComponent.cs View File

@ -1,96 +1,96 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace IllusionInjector
{
public class PluginComponent : MonoBehaviour
{
private CompositePlugin plugins;
private bool freshlyLoaded = false;
private bool quitting = false;
public static PluginComponent Create()
{
return new GameObject("IPA_PluginManager").AddComponent<PluginComponent>();
}
void Awake()
{
DontDestroyOnLoad(gameObject);
plugins = new CompositePlugin(PluginManager.Plugins);
plugins.OnApplicationStart();
SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
void Start()
{
OnLevelWasLoaded(Application.loadedLevel);
}
void Update()
{
if (freshlyLoaded)
{
freshlyLoaded = false;
plugins.OnLevelWasInitialized(Application.loadedLevel);
}
plugins.OnUpdate();
}
void LateUpdate()
{
plugins.OnLateUpdate();
}
void FixedUpdate()
{
plugins.OnFixedUpdate();
}
void OnDestroy()
{
if (!quitting)
{
Create();
}
}
void OnApplicationQuit()
{
SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
plugins.OnApplicationQuit();
quitting = true;
}
void OnLevelWasLoaded(int level)
{
plugins.OnLevelWasLoaded(level);
freshlyLoaded = true;
}
void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
{
plugins.OnSceneLoaded(scene, sceneMode);
}
private void OnSceneUnloaded(Scene scene) {
plugins.OnSceneUnloaded(scene);
}
private void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
plugins.OnActiveSceneChanged(prevScene, nextScene);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace IllusionInjector
{
public class PluginComponent : MonoBehaviour
{
private CompositePlugin plugins;
private bool freshlyLoaded = false;
private bool quitting = false;
public static PluginComponent Create()
{
return new GameObject("IPA_PluginManager").AddComponent<PluginComponent>();
}
void Awake()
{
DontDestroyOnLoad(gameObject);
plugins = new CompositePlugin(PluginManager.Plugins);
plugins.OnApplicationStart();
SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
void Start()
{
OnLevelWasLoaded(Application.loadedLevel);
}
void Update()
{
if (freshlyLoaded)
{
freshlyLoaded = false;
plugins.OnLevelWasInitialized(Application.loadedLevel);
}
plugins.OnUpdate();
}
void LateUpdate()
{
plugins.OnLateUpdate();
}
void FixedUpdate()
{
plugins.OnFixedUpdate();
}
void OnDestroy()
{
if (!quitting)
{
Create();
}
}
void OnApplicationQuit()
{
SceneManager.activeSceneChanged += OnActiveSceneChanged;
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
plugins.OnApplicationQuit();
quitting = true;
}
void OnLevelWasLoaded(int level)
{
plugins.OnLevelWasLoaded(level);
freshlyLoaded = true;
}
void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
{
plugins.OnSceneLoaded(scene, sceneMode);
}
private void OnSceneUnloaded(Scene scene) {
plugins.OnSceneUnloaded(scene);
}
private void OnActiveSceneChanged(Scene prevScene, Scene nextScene) {
plugins.OnActiveSceneChanged(prevScene, nextScene);
}
}
}

+ 154
- 154
IllusionInjector/PluginManager.cs View File

@ -1,154 +1,154 @@
using IllusionPlugin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace IllusionInjector
{
public static class PluginManager
{
private static List<IPlugin> _Plugins = null;
internal static readonly Logger debugLogger = new Logger("IllusionInjector");
/// <summary>
/// Gets the list of loaded plugins and loads them if necessary.
/// </summary>
public static IEnumerable<IPlugin> Plugins
{
get
{
if(_Plugins == null)
{
LoadPlugins();
}
return _Plugins;
}
}
private static void LoadPlugins()
{
string pluginDirectory = Path.Combine(Environment.CurrentDirectory, "Plugins");
// Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL,
// so we need to resort to P/Invoke
string exeName = Path.GetFileNameWithoutExtension(AppInfo.StartupPath);
debugLogger.Log(exeName);
_Plugins = new List<IPlugin>();
if (!Directory.Exists(pluginDirectory)) return;
if (!Directory.Exists(Path.Combine(pluginDirectory, ".cache")))
{
Directory.CreateDirectory(Path.Combine(pluginDirectory, ".cache"));
}
else
{
foreach (string plugin in Directory.GetFiles(Path.Combine(pluginDirectory, ".cache"), "*"))
{
File.Delete(plugin);
}
}
//Copy plugins to .cache
string[] originalPlugins = Directory.GetFiles(pluginDirectory, "*.dll");
foreach (string s in originalPlugins)
{
string pluginCopy = pluginDirectory + "\\.cache" + s.Substring(s.LastIndexOf('\\'));
File.Copy(Path.Combine(pluginDirectory, s), pluginCopy);
}
//Load copied plugins
string copiedPluginsDirectory = pluginDirectory + "\\.cache";
string[] copiedPlugins = Directory.GetFiles(copiedPluginsDirectory, "*.dll");
foreach (string s in copiedPlugins)
{
_Plugins.AddRange(LoadPluginsFromFile(s, exeName));
}
// DEBUG
debugLogger.Log($"Running on Unity {UnityEngine.Application.unityVersion}");
debugLogger.Log("-----------------------------");
debugLogger.Log($"Loading plugins from {pluginDirectory} and found {_Plugins.Count}");
debugLogger.Log("-----------------------------");
foreach (var plugin in _Plugins)
{
debugLogger.Log($"{plugin.Name}: {plugin.Version}");
if (!(plugin is IPluginNew)) {
debugLogger.Warning($"{plugin.Name} uses a Deprecated Interface! This may cause errors!");
}
}
debugLogger.Log("-----------------------------");
}
private static IEnumerable<IPlugin> LoadPluginsFromFile(string file, string exeName)
{
List<IPlugin> plugins = new List<IPlugin>();
if (!File.Exists(file) || !file.EndsWith(".dll", true, null))
return plugins;
try
{
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type t in assembly.GetTypes())
{
if (t.GetInterface("IPlugin") != null)
{
try
{
IPlugin pluginInstance = Activator.CreateInstance(t) as IPlugin;
string[] filter = null;
if (pluginInstance is IEnhancedPlugin)
{
filter = ((IEnhancedPlugin)pluginInstance).Filter;
}
if(filter == null || filter.Contains(exeName, StringComparer.OrdinalIgnoreCase))
plugins.Add(pluginInstance);
}
catch (Exception e)
{
debugLogger.Exception($"Could not load plugin {t.FullName} in {Path.GetFileName(file)}! {e}");
}
}
}
}
catch (Exception e)
{
debugLogger.Error($"Could not load {Path.GetFileName(file)}! {e}");
}
return plugins;
}
public class AppInfo
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
public static string StartupPath
{
get
{
StringBuilder stringBuilder = new StringBuilder(260);
GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
return stringBuilder.ToString();
}
}
}
}
}
using IllusionPlugin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace IllusionInjector
{
public static class PluginManager
{
private static List<IPlugin> _Plugins = null;
internal static readonly Logger debugLogger = new Logger("IllusionInjector");
/// <summary>
/// Gets the list of loaded plugins and loads them if necessary.
/// </summary>
public static IEnumerable<IPlugin> Plugins
{
get
{
if(_Plugins == null)
{
LoadPlugins();
}
return _Plugins;
}
}
private static void LoadPlugins()
{
string pluginDirectory = Path.Combine(Environment.CurrentDirectory, "Plugins");
// Process.GetCurrentProcess().MainModule crashes the game and Assembly.GetEntryAssembly() is NULL,
// so we need to resort to P/Invoke
string exeName = Path.GetFileNameWithoutExtension(AppInfo.StartupPath);
debugLogger.Log(exeName);
_Plugins = new List<IPlugin>();
if (!Directory.Exists(pluginDirectory)) return;
if (!Directory.Exists(Path.Combine(pluginDirectory, ".cache")))
{
Directory.CreateDirectory(Path.Combine(pluginDirectory, ".cache"));
}
else
{
foreach (string plugin in Directory.GetFiles(Path.Combine(pluginDirectory, ".cache"), "*"))
{
File.Delete(plugin);
}
}
//Copy plugins to .cache
string[] originalPlugins = Directory.GetFiles(pluginDirectory, "*.dll");
foreach (string s in originalPlugins)
{
string pluginCopy = pluginDirectory + "\\.cache" + s.Substring(s.LastIndexOf('\\'));
File.Copy(Path.Combine(pluginDirectory, s), pluginCopy);
}
//Load copied plugins
string copiedPluginsDirectory = pluginDirectory + "\\.cache";
string[] copiedPlugins = Directory.GetFiles(copiedPluginsDirectory, "*.dll");
foreach (string s in copiedPlugins)
{
_Plugins.AddRange(LoadPluginsFromFile(s, exeName));
}
// DEBUG
debugLogger.Log($"Running on Unity {UnityEngine.Application.unityVersion}");
debugLogger.Log("-----------------------------");
debugLogger.Log($"Loading plugins from {pluginDirectory} and found {_Plugins.Count}");
debugLogger.Log("-----------------------------");
foreach (var plugin in _Plugins)
{
debugLogger.Log($"{plugin.Name}: {plugin.Version}");
if (!(plugin is IPluginNew)) {
debugLogger.Warning($"{plugin.Name} uses a Deprecated Interface! This may cause errors!");
}
}
debugLogger.Log("-----------------------------");
}
private static IEnumerable<IPlugin> LoadPluginsFromFile(string file, string exeName)
{
List<IPlugin> plugins = new List<IPlugin>();
if (!File.Exists(file) || !file.EndsWith(".dll", true, null))
return plugins;
try
{
Assembly assembly = Assembly.LoadFrom(file);
foreach (Type t in assembly.GetTypes())
{
if (t.GetInterface("IPlugin") != null)
{
try
{
IPlugin pluginInstance = Activator.CreateInstance(t) as IPlugin;
string[] filter = null;
if (pluginInstance is IEnhancedPlugin)
{
filter = ((IEnhancedPlugin)pluginInstance).Filter;
}
if(filter == null || filter.Contains(exeName, StringComparer.OrdinalIgnoreCase))
plugins.Add(pluginInstance);
}
catch (Exception e)
{
debugLogger.Exception($"Could not load plugin {t.FullName} in {Path.GetFileName(file)}! {e}");
}
}
}
}
catch (Exception e)
{
debugLogger.Error($"Could not load {Path.GetFileName(file)}! {e}");
}
return plugins;
}
public class AppInfo
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int GetModuleFileName(HandleRef hModule, StringBuilder buffer, int length);
private static HandleRef NullHandleRef = new HandleRef(null, IntPtr.Zero);
public static string StartupPath
{
get
{
StringBuilder stringBuilder = new StringBuilder(260);
GetModuleFileName(NullHandleRef, stringBuilder, stringBuilder.Capacity);
return stringBuilder.ToString();
}
}
}
}
}

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

@ -1 +1 @@
207669803f9c3f5ead7136a41944fdaa372fd294
c4f9eceab04df8633c0ae4f922a37f459ec45217

+ 50
- 50
IllusionPlugin/IPlugin.cs View File

@ -1,50 +1,50 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;
namespace IllusionPlugin
{
/// <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>
public interface IPlugin
{
/// <summary>
/// Gets the name of the plugin.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the version of the plugin.
/// </summary>
string Version { get; }
/// <summary>
/// Gets invoked when the application is started.
/// </summary>
void OnApplicationStart();
/// <summary>
/// Gets invoked when the application is closed.
/// </summary>
void OnApplicationQuit();
/// <summary>
/// Gets invoked on every graphic update.
/// </summary>
void OnUpdate();
/// <summary>
/// Gets invoked on ever physics update.
/// </summary>
void OnFixedUpdate();
[Obsolete("Use OnSceneLoaded instead")]
void OnLevelWasLoaded(int level);
[Obsolete("Use OnSceneLoaded instead")]
void OnLevelWasInitialized(int level);
}
}
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;
namespace IllusionPlugin
{
/// <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>
public interface IPlugin
{
/// <summary>
/// Gets the name of the plugin.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the version of the plugin.
/// </summary>
string Version { get; }
/// <summary>
/// Gets invoked when the application is started.
/// </summary>
void OnApplicationStart();
/// <summary>
/// Gets invoked when the application is closed.
/// </summary>
void OnApplicationQuit();
/// <summary>
/// Gets invoked on every graphic update.
/// </summary>
void OnUpdate();
/// <summary>
/// Gets invoked on ever physics update.
/// </summary>
void OnFixedUpdate();
[Obsolete("Use OnSceneLoaded instead")]
void OnLevelWasLoaded(int level);
[Obsolete("Use OnSceneLoaded instead")]
void OnLevelWasInitialized(int level);
}
}

+ 59
- 59
IllusionPlugin/IllusionPlugin.csproj View File

@ -1,60 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.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>v3.5</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>
</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>
</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>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="IEnhancedPlugin.cs" />
<Compile Include="IniFile.cs" />
<Compile Include="IPlugin.cs" />
<Compile Include="IPluginNew.cs" />
<Compile Include="Logger.cs" />
<Compile Include="ModPrefs.cs" />
<Compile Include="Properties\AssemblyInfo.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>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.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>v3.5</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>
</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>
</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>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="IEnhancedPlugin.cs" />
<Compile Include="IniFile.cs" />
<Compile Include="IPlugin.cs" />
<Compile Include="IPluginNew.cs" />
<Compile Include="Logger.cs" />
<Compile Include="ModPrefs.cs" />
<Compile Include="Properties\AssemblyInfo.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>

+ 101
- 101
IllusionPlugin/IniFile.cs View File

@ -1,101 +1,101 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace IllusionPlugin
{
/// <summary>
/// Create a New INI file to store or load data
/// </summary>
internal class IniFile
{
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int GetPrivateProfileString(
string lpSection,
string lpKey,
string lpDefault,
StringBuilder lpReturnString,
int nSize,
string lpFileName);
[DllImport("KERNEL32.DLL", EntryPoint = "WritePrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int WritePrivateProfileString(
string lpSection,
string lpKey,
string lpValue,
string lpFileName);
/*private string _path = "";
public string Path
{
get
{
return _path;
}
set
{
if (!File.Exists(value))
File.WriteAllText(value, "", Encoding.Unicode);
_path = value;
}
}*/
private FileInfo _iniFileInfo;
public FileInfo IniFileInfo {
get => _iniFileInfo;
set {
_iniFileInfo = value;
if (_iniFileInfo.Exists) return;
_iniFileInfo.Directory?.Create();
_iniFileInfo.Create();
}
}
/// <summary>
/// INIFile Constructor.
/// </summary>
/// <PARAM name="INIPath"></PARAM>
public IniFile(string iniPath)
{
IniFileInfo = new FileInfo(iniPath);
//this.Path = INIPath;
}
/// <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
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, IniFileInfo.FullName);
}
/// <summary>
/// Read Data Value From the Ini File
/// </summary>
/// <PARAM name="Section"></PARAM>
/// <PARAM name="Key"></PARAM>
/// <PARAM name="Path"></PARAM>
/// <returns></returns>
public string IniReadValue(string Section, string Key)
{
const int MAX_CHARS = 1023;
StringBuilder result = new StringBuilder(MAX_CHARS);
GetPrivateProfileString(Section, Key, "", result, MAX_CHARS, IniFileInfo.FullName);
return result.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace IllusionPlugin
{
/// <summary>
/// Create a New INI file to store or load data
/// </summary>
internal class IniFile
{
[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int GetPrivateProfileString(
string lpSection,
string lpKey,
string lpDefault,
StringBuilder lpReturnString,
int nSize,
string lpFileName);
[DllImport("KERNEL32.DLL", EntryPoint = "WritePrivateProfileStringW",
SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern int WritePrivateProfileString(
string lpSection,
string lpKey,
string lpValue,
string lpFileName);
/*private string _path = "";
public string Path
{
get
{
return _path;
}
set
{
if (!File.Exists(value))
File.WriteAllText(value, "", Encoding.Unicode);
_path = value;
}
}*/
private FileInfo _iniFileInfo;
public FileInfo IniFileInfo {
get => _iniFileInfo;
set {
_iniFileInfo = value;
if (_iniFileInfo.Exists) return;
_iniFileInfo.Directory?.Create();
_iniFileInfo.Create();
}
}
/// <summary>
/// INIFile Constructor.
/// </summary>
/// <PARAM name="INIPath"></PARAM>
public IniFile(string iniPath)
{
IniFileInfo = new FileInfo(iniPath);
//this.Path = INIPath;
}
/// <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
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, IniFileInfo.FullName);
}
/// <summary>
/// Read Data Value From the Ini File
/// </summary>
/// <PARAM name="Section"></PARAM>
/// <PARAM name="Key"></PARAM>
/// <PARAM name="Path"></PARAM>
/// <returns></returns>
public string IniReadValue(string Section, string Key)
{
const int MAX_CHARS = 1023;
StringBuilder result = new StringBuilder(MAX_CHARS);
GetPrivateProfileString(Section, Key, "", result, MAX_CHARS, IniFileInfo.FullName);
return result.ToString();
}
}
}

+ 167
- 167
IllusionPlugin/ModPrefs.cs View File

@ -1,167 +1,167 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IllusionPlugin
{
/// <summary>
/// Allows to get and set preferences for your mod.
/// </summary>
public class ModPrefs {
internal static Dictionary<IPlugin, ModPrefs> ModPrefses { get; set; } = new Dictionary<IPlugin, ModPrefs>();
private IniFile Instance;
public ModPrefs(IPlugin plugin) {
Instance = new IniFile(Path.Combine(Environment.CurrentDirectory, $"UserData/ModPrefs/{plugin.Name}.ini"));
ModPrefses.Add(plugin, this);
}
/// <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>
public string GetString(string section, string name, string defaultValue = "", bool autoSave = false)
{
var value = Instance.IniReadValue(section, name);
if (value != "")
return value;
else if (autoSave)
SetString(section, name, defaultValue);
return defaultValue;
}
/// <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>
public int GetInt(string section, string name, int defaultValue = 0, bool autoSave = false)
{
if (int.TryParse(Instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
SetInt(section, name, defaultValue);
return defaultValue;
}
/// <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>
public float GetFloat(string section, string name, float defaultValue = 0f, bool autoSave = false)
{
if (float.TryParse(Instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
SetFloat(section, name, defaultValue);
return defaultValue;
}
/// <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>
public bool GetBool(string section, string name, bool defaultValue = false, bool autoSave = false)
{
string sVal = GetString(section, name, null);
if (sVal == "1" || sVal == "0")
{
return sVal == "1";
} else if (autoSave)
{
SetBool(section, name, defaultValue);
}
return defaultValue;
}
/// <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>
public bool HasKey(string section, string name)
{
return Instance.IniReadValue(section, name) != null;
}
/// <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>
public void SetFloat(string section, string name, float value)
{
Instance.IniWriteValue(section, name, value.ToString());
}
/// <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>
public void SetInt(string section, string name, int value)
{
Instance.IniWriteValue(section, name, value.ToString());
}
/// <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>
public void SetString(string section, string name, string value)
{
Instance.IniWriteValue(section, name, value);
}
/// <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>
public void SetBool(string section, string name, bool value)
{
Instance.IniWriteValue(section, name, value ? "1" : "0");
}
}
public static class ModPrefsExtensions {
public static ModPrefs GetModPrefs(this IPlugin plugin) {
return ModPrefs.ModPrefses.First(o => o.Key == plugin).Value;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IllusionPlugin
{
/// <summary>
/// Allows to get and set preferences for your mod.
/// </summary>
public class ModPrefs {
internal static Dictionary<IPlugin, ModPrefs> ModPrefses { get; set; } = new Dictionary<IPlugin, ModPrefs>();
private IniFile Instance;
public ModPrefs(IPlugin plugin) {
Instance = new IniFile(Path.Combine(Environment.CurrentDirectory, $"UserData/ModPrefs/{plugin.Name}.ini"));
ModPrefses.Add(plugin, this);
}
/// <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>
public string GetString(string section, string name, string defaultValue = "", bool autoSave = false)
{
var value = Instance.IniReadValue(section, name);
if (value != "")
return value;
else if (autoSave)
SetString(section, name, defaultValue);
return defaultValue;
}
/// <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>
public int GetInt(string section, string name, int defaultValue = 0, bool autoSave = false)
{
if (int.TryParse(Instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
SetInt(section, name, defaultValue);
return defaultValue;
}
/// <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>
public float GetFloat(string section, string name, float defaultValue = 0f, bool autoSave = false)
{
if (float.TryParse(Instance.IniReadValue(section, name), out var value))
return value;
else if (autoSave)
SetFloat(section, name, defaultValue);
return defaultValue;
}
/// <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>
public bool GetBool(string section, string name, bool defaultValue = false, bool autoSave = false)
{
string sVal = GetString(section, name, null);
if (sVal == "1" || sVal == "0")
{
return sVal == "1";
} else if (autoSave)
{
SetBool(section, name, defaultValue);
}
return defaultValue;
}
/// <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>
public bool HasKey(string section, string name)
{
return Instance.IniReadValue(section, name) != null;
}
/// <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>
public void SetFloat(string section, string name, float value)
{
Instance.IniWriteValue(section, name, value.ToString());
}
/// <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>
public void SetInt(string section, string name, int value)
{
Instance.IniWriteValue(section, name, value.ToString());
}
/// <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>
public void SetString(string section, string name, string value)
{
Instance.IniWriteValue(section, name, value);
}
/// <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>
public void SetBool(string section, string name, bool value)
{
Instance.IniWriteValue(section, name, value ? "1" : "0");
}
}
public static class ModPrefsExtensions {
public static ModPrefs GetModPrefs(this IPlugin plugin) {
return ModPrefs.ModPrefses.First(o => o.Key == plugin).Value;
}
}
}

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

@ -1 +1 @@
dd098bdf8443f9e98a9261f325ce0c78fe53aba4
de4d7d5be2f255b6eb5fe16bec001496ad0c8963

+ 0
- 91
Launcher/Launcher.csproj View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.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>{D1390268-F68B-4A55-B50D-EAD25756C8EF}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Launcher</RootNamespace>
<AssemblyName>Launcher</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>syringe.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="syringe.ico" />
</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
- 100
Launcher/Program.cs View File

@ -1,100 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Launcher
{
static class Program
{
private static string[] TABOO_NAMES = {
//"Start",
//"Update",
//"Awake",
//"OnDestroy"
};
private static string[] ENTRY_TYPES = { "Display" };
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try {
var execPath = Application.ExecutablePath;
var fileName = Path.GetFileNameWithoutExtension(execPath);
if (fileName.IndexOf("VR") == -1 && fileName.IndexOf("_") == -1)
{
Fail("File not named correctly!");
}
bool vrMode = fileName.IndexOf("VR") > 0;
string baseName = execPath.Substring(0, vrMode
? execPath.LastIndexOf("VR")
: execPath.LastIndexOf("_"));
string executable = baseName + ".exe";
var file = new FileInfo(executable);
if (file.Exists)
{
var args = Environment.GetCommandLineArgs().ToList();
if (vrMode) args.Add("--vr");
EnsureIPA(executable);
StartGame(executable, args.ToArray());
}
else
{
MessageBox.Show("Could not find: " + file.FullName, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} catch(Exception globalException) {
MessageBox.Show(globalException.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static void EnsureIPA(string executable)
{
var processStart = new ProcessStartInfo("IPA.exe", EncodeParameterArgument(executable) + " --nowait");
processStart.UseShellExecute = false;
processStart.CreateNoWindow = true;
processStart.RedirectStandardError = true;
var process = Process.Start(processStart);
process.WaitForExit();
if(process.ExitCode != 0)
{
Fail(process.StandardError.ReadToEnd());
}
}
private static void StartGame(string executable, string[] args)
{
var arguments = string.Join(" ", args.ToArray());
Process.Start(executable, arguments);
}
private static void Fail(string reason) {
throw new Exception(reason);
}
/// <summary>
/// Encodes an argument for passing into a program
/// </summary>
/// <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>
private static string EncodeParameterArgument(string original)
{
if (string.IsNullOrEmpty(original))
return original;
string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0");
value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"");
return value;
}
}
}

+ 0
- 36
Launcher/Properties/AssemblyInfo.cs View File

@ -1,36 +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("Launcher")]
[assembly: AssemblyDescription("Rename to [EXE]_Patched.exe or [EXE]VR.exe")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Launcher")]
[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("d590f676-c2c0-4b80-ae93-6edf274320e6")]
// 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")]

+ 0
- 63
Launcher/Properties/Resources.Designer.cs View File

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Launcher.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Launcher.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

+ 0
- 117
Launcher/Properties/Resources.resx View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

+ 0
- 26
Launcher/Properties/Settings.Designer.cs View File

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Launcher.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

+ 0
- 7
Launcher/Properties/Settings.settings View File

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

+ 0
- 63
Launcher/Resources.Designer.cs View File

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Launcher {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Launcher.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

+ 0
- 121
Launcher/Resources.resx View File

@ -1,121 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</root>

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

@ -1 +0,0 @@
7c6dbd91916854c83d27e1fd6e1b9ccedbe983b8

+ 0
- 4
Launcher/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="net35" />
</packages>

BIN
Launcher/syringe.ico View File

Before After

Loading…
Cancel
Save