@@ -0,0 +1,45 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio 14 | |||
VisualStudioVersion = 14.0.25123.0 | |||
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}") = "Launcher", "Launcher\Launcher.csproj", "{D1390268-F68B-4A55-B50D-EAD25756C8EF}" | |||
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 | |||
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 | |||
{D1390268-F68B-4A55-B50D-EAD25756C8EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{D1390268-F68B-4A55-B50D-EAD25756C8EF}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{D1390268-F68B-4A55-B50D-EAD25756C8EF}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{D1390268-F68B-4A55-B50D-EAD25756C8EF}.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 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
EndGlobal |
@@ -0,0 +1,66 @@ | |||
<?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> | |||
<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.Xml" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="Program.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> | |||
--> | |||
<Target Name="AfterBuild"> | |||
<Message Text="Packing..." Importance="normal" /> | |||
<ItemGroup> | |||
<LauncherDlls Include="$(SolutionDir)Launcher\$(OutDir)*.dll" /> | |||
<Launcher Include="$(SolutionDir)Launcher\$(OutDir)Launcher.exe" /> | |||
<Dlls Include="$(SolutionDir)IllusionInjector\$(OutDir)**\*" /> | |||
</ItemGroup> | |||
<Copy SourceFiles="@(Dlls)" DestinationFolder="$(OutputPath)IPA\Managed" /> | |||
<Copy SourceFiles="@(Launcher)" DestinationFolder="$(OutputPath)IPA" /> | |||
<Copy SourceFiles="@(LauncherDlls)" DestinationFolder="$(OutputPath)" /> | |||
</Target> | |||
</Project> |
@@ -0,0 +1,75 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Text; | |||
namespace IPA | |||
{ | |||
class Program | |||
{ | |||
static void Main(string[] args) | |||
{ | |||
if(args.Length < 1 || !args[0].EndsWith(".exe")) | |||
{ | |||
Fail("Drag an (executable) file on the exe!"); | |||
} | |||
string launcherSrc = Path.Combine("IPA", "Launcher.exe"); | |||
string managedFolder = Path.Combine("IPA", "Managed"); | |||
// Sanitizing | |||
if (!File.Exists(launcherSrc)) Fail("Couldn't find launcher! Make sure you extracted all contents of the release archive."); | |||
if (!File.Exists(launcherSrc)) Fail("Couldn't find DLLs! Make sure you extracted all contents of the release archive."); | |||
// Copying | |||
try | |||
{ | |||
string projectName = Path.GetFileNameWithoutExtension(args[0]); | |||
string launcherPath = Path.Combine(Environment.CurrentDirectory, projectName + "_Patched.exe"); | |||
string dataPath = Path.Combine(Path.Combine(Environment.CurrentDirectory, projectName + "_Data"), "Managed"); | |||
File.Copy(launcherSrc, launcherPath, true); | |||
CopyAll(new DirectoryInfo(managedFolder), new DirectoryInfo(dataPath)); | |||
Console.WriteLine("Successfully copied files!"); | |||
} catch(Exception e) | |||
{ | |||
Fail("Oops! This should not have happened.\n\n" + e); | |||
} | |||
} | |||
public static void CopyAll(DirectoryInfo source, DirectoryInfo target) | |||
{ | |||
Directory.CreateDirectory(target.FullName); | |||
// Copy each file into the new directory. | |||
foreach (FileInfo fi in source.GetFiles()) | |||
{ | |||
Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name); | |||
fi.CopyTo(Path.Combine(target.FullName, fi.Name), true); | |||
} | |||
// Copy each subdirectory using recursion. | |||
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) | |||
{ | |||
DirectoryInfo nextTargetSubDir = | |||
target.CreateSubdirectory(diSourceSubDir.Name); | |||
CopyAll(diSourceSubDir, nextTargetSubDir); | |||
} | |||
} | |||
static void Fail(string message) | |||
{ | |||
Console.BackgroundColor = ConsoleColor.Red; | |||
Console.ForegroundColor = ConsoleColor.White; | |||
Console.Write("{0,80}", ""); | |||
Console.Write("{0,-80}", " "+message); | |||
Console.Write("{0,80}", ""); | |||
Console.ReadLine(); | |||
Environment.Exit(1); | |||
} | |||
} | |||
} |
@@ -0,0 +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("IPA")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("IPA")] | |||
[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("1.0.0.0")] | |||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,18 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using UnityEngine; | |||
namespace IllusionInjector | |||
{ | |||
class Bootstrapper : MonoBehaviour | |||
{ | |||
public event Action Destroyed = delegate {}; | |||
void OnDestroy() | |||
{ | |||
Destroyed(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
using IllusionPlugin; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using UnityEngine; | |||
namespace IllusionInjector | |||
{ | |||
public class CompositePlugin : IPlugin | |||
{ | |||
IEnumerable<IPlugin> plugins; | |||
private delegate void CompositeCall(IPlugin plugin); | |||
public CompositePlugin(IEnumerable<IPlugin> plugins) | |||
{ | |||
this.plugins = plugins; | |||
} | |||
public void OnApplicationStart() | |||
{ | |||
Invoke(plugin => plugin.OnApplicationStart()); | |||
} | |||
public void OnApplicationQuit() | |||
{ | |||
Invoke(plugin => plugin.OnApplicationQuit()); | |||
} | |||
public void OnLevelWasLoaded(int level) | |||
{ | |||
foreach (var plugin in plugins) | |||
{ | |||
try | |||
{ | |||
plugin.OnLevelWasLoaded(level); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine("{0}: {1}", plugin.Name, ex); | |||
} | |||
} | |||
} | |||
private void Invoke(CompositeCall callback) | |||
{ | |||
foreach (var plugin in plugins) | |||
{ | |||
try | |||
{ | |||
callback(plugin); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine("{0}: {1}", plugin.Name, ex); | |||
} | |||
} | |||
} | |||
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 void OnUpdate() | |||
{ | |||
Invoke(plugin => plugin.OnUpdate()); | |||
} | |||
public void OnFixedUpdate() | |||
{ | |||
Invoke(plugin => plugin.OnFixedUpdate()); | |||
} | |||
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(); | |||
}); | |||
} | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
using System; | |||
using System.Collections; | |||
using System.Runtime.InteropServices; | |||
using System.IO; | |||
using System.Text; | |||
namespace Windows | |||
{ | |||
class GuiConsole | |||
{ | |||
public static void CreateConsole() | |||
{ | |||
if (hasConsole) | |||
return; | |||
if (oldOut == IntPtr.Zero) | |||
oldOut = GetStdHandle( -11 ); | |||
if (! AllocConsole()) | |||
throw new Exception("AllocConsole() failed"); | |||
conOut = CreateFile( "CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero ); | |||
if (! SetStdHandle(-11, conOut)) | |||
throw new Exception("SetStdHandle() failed"); | |||
StreamToConsole(); | |||
hasConsole = true; | |||
} | |||
public static void ReleaseConsole() | |||
{ | |||
if (! hasConsole) | |||
return; | |||
if (! CloseHandle(conOut)) | |||
throw new Exception("CloseHandle() failed"); | |||
conOut = IntPtr.Zero; | |||
if (! FreeConsole()) | |||
throw new Exception("FreeConsole() failed"); | |||
if (! SetStdHandle(-11, oldOut)) | |||
throw new Exception("SetStdHandle() failed"); | |||
StreamToConsole(); | |||
hasConsole = false; | |||
} | |||
private static void StreamToConsole() | |||
{ | |||
Stream cstm = Console.OpenStandardOutput(); | |||
StreamWriter cstw = new StreamWriter( cstm, Encoding.Default ); | |||
cstw.AutoFlush = true; | |||
Console.SetOut( cstw ); | |||
Console.SetError( cstw ); | |||
} | |||
private static bool hasConsole = false; | |||
private static IntPtr conOut; | |||
private static IntPtr oldOut; | |||
[DllImport("kernel32.dll", SetLastError=true)] | |||
private static extern bool AllocConsole(); | |||
[DllImport("kernel32.dll", SetLastError=false)] | |||
private static extern bool FreeConsole(); | |||
[DllImport("kernel32.dll", SetLastError=true)] | |||
private static extern IntPtr GetStdHandle( int nStdHandle ); | |||
[DllImport("kernel32.dll", SetLastError=true)] | |||
private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput); | |||
[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] | |||
private static extern IntPtr CreateFile( | |||
string fileName, | |||
int desiredAccess, | |||
int shareMode, | |||
IntPtr securityAttributes, | |||
int creationDisposition, | |||
int flagsAndAttributes, | |||
IntPtr templateFile ); | |||
[DllImport("kernel32.dll", ExactSpelling=true, SetLastError=true)] | |||
private static extern bool CloseHandle(IntPtr handle); | |||
} | |||
} |
@@ -0,0 +1,66 @@ | |||
<?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> | |||
</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> |
@@ -0,0 +1,26 @@ | |||
using System; | |||
using UnityEngine; | |||
namespace IllusionInjector | |||
{ | |||
public static class Injector | |||
{ | |||
private static bool injected = false; | |||
public static void Inject() | |||
{ | |||
if (!injected) | |||
{ | |||
injected = true; | |||
var bootstrapper = new GameObject("Bootstrapper").AddComponent<Bootstrapper>(); | |||
bootstrapper.Destroyed += Bootstrapper_Destroyed; | |||
} | |||
} | |||
private static void Bootstrapper_Destroyed() | |||
{ | |||
var singleton = new GameObject("PluginManager"); | |||
singleton.AddComponent<PluginComponent>(); ; | |||
} | |||
} | |||
} |
@@ -0,0 +1,63 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
using UnityEngine; | |||
namespace IllusionInjector | |||
{ | |||
public class PluginComponent : MonoBehaviour | |||
{ | |||
private CompositePlugin plugins; | |||
private bool freshlyLoaded = false; | |||
void Awake() | |||
{ | |||
DontDestroyOnLoad(gameObject); | |||
if (Environment.CommandLine.Contains("--verbose") && !Screen.fullScreen) | |||
{ | |||
Windows.GuiConsole.CreateConsole(); | |||
} | |||
plugins = new CompositePlugin(PluginManager.Plugins); | |||
plugins.OnApplicationStart(); | |||
} | |||
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() | |||
{ | |||
plugins.OnApplicationQuit(); | |||
} | |||
void OnLevelWasLoaded(int level) | |||
{ | |||
plugins.OnLevelWasLoaded(level); | |||
freshlyLoaded = true; | |||
} | |||
} | |||
} |
@@ -0,0 +1,126 @@ | |||
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; | |||
/// <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); | |||
Console.WriteLine(exeName); | |||
_Plugins = new List<IPlugin>(); | |||
if (!Directory.Exists(pluginDirectory)) return; | |||
String[] files = Directory.GetFiles(pluginDirectory, "*.dll"); | |||
foreach (var s in files) | |||
{ | |||
_Plugins.AddRange(LoadPluginsFromFile(Path.Combine(pluginDirectory, s), exeName)); | |||
} | |||
// DEBUG | |||
Console.WriteLine("-----------------------------"); | |||
Console.WriteLine("Loading plugins from {0} and found {1}", pluginDirectory, _Plugins.Count); | |||
Console.WriteLine("-----------------------------"); | |||
foreach (var plugin in _Plugins) | |||
{ | |||
Console.WriteLine(" {0}: {1}", plugin.Name, plugin.Version); | |||
} | |||
Console.WriteLine("-----------------------------"); | |||
} | |||
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 || Enumerable.Contains(filter, exeName, StringComparer.OrdinalIgnoreCase)) | |||
plugins.Add(pluginInstance); | |||
} | |||
catch (Exception) | |||
{ | |||
} | |||
} | |||
} | |||
} | |||
catch (Exception) | |||
{ | |||
} | |||
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(); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +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("IllusionInjector")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("IllusionInjector")] | |||
[assembly: AssemblyCopyright("Copyright © 2015")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
// Setting ComVisible to false makes the types in this assembly not visible | |||
// to COM components. If you need to access a type in this assembly from | |||
// COM, set the ComVisible attribute to true on that type. | |||
[assembly: ComVisible(false)] | |||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||
[assembly: Guid("400a540a-d21f-4609-966b-206059b6e73b")] | |||
// 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,0 +1,17 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace IllusionPlugin | |||
{ | |||
public interface IEnhancedPlugin : IPlugin | |||
{ | |||
/// <summary> | |||
/// Gets a list of executables this plugin should be excuted on (without the file ending) | |||
/// </summary> | |||
/// <example>{ "PlayClub", "PlayClubStudio" }</example> | |||
string[] Filter { get; } | |||
void OnLateUpdate(); | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
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 whenever a level is loaded. | |||
/// </summary> | |||
/// <param name="level"></param> | |||
void OnLevelWasLoaded(int level); | |||
/// <summary> | |||
/// Gets invoked after the first update cycle after a level was loaded. | |||
/// </summary> | |||
/// <param name="level"></param> | |||
void OnLevelWasInitialized(int level); | |||
/// <summary> | |||
/// Gets invoked on every graphic update. | |||
/// </summary> | |||
void OnUpdate(); | |||
/// <summary> | |||
/// Gets invoked on ever physics update. | |||
/// </summary> | |||
void OnFixedUpdate(); | |||
} | |||
} |
@@ -0,0 +1,178 @@ | |||
<?xml version="1.0"?> | |||
<doc> | |||
<assembly> | |||
<name>IllusionPlugin</name> | |||
</assembly> | |||
<members> | |||
<member name="P:IllusionPlugin.IEnhancedPlugin.Filter"> | |||
<summary> | |||
Gets a list of executables this plugin should be excuted on (without the file ending) | |||
</summary> | |||
<example>{ "PlayClub", "PlayClubStudio" }</example> | |||
</member> | |||
<member name="T:IllusionPlugin.IniFile"> | |||
<summary> | |||
Create a New INI file to store or load data | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.IniFile.#ctor(System.String)"> | |||
<summary> | |||
INIFile Constructor. | |||
</summary> | |||
<PARAM name="INIPath"></PARAM> | |||
</member> | |||
<member name="M:IllusionPlugin.IniFile.IniWriteValue(System.String,System.String,System.String)"> | |||
<summary> | |||
Write Data to the INI File | |||
</summary> | |||
<PARAM name="Section"></PARAM> | |||
Section name | |||
<PARAM name="Key"></PARAM> | |||
Key Name | |||
<PARAM name="Value"></PARAM> | |||
Value Name | |||
</member> | |||
<member name="M:IllusionPlugin.IniFile.IniReadValue(System.String,System.String)"> | |||
<summary> | |||
Read Data Value From the Ini File | |||
</summary> | |||
<PARAM name="Section"></PARAM> | |||
<PARAM name="Key"></PARAM> | |||
<PARAM name="Path"></PARAM> | |||
<returns></returns> | |||
</member> | |||
<member name="T:IllusionPlugin.IPlugin"> | |||
<summary> | |||
Interface for generic Illusion unity plugins. Every class that implements this will be loaded if the DLL is placed at | |||
data/Managed/Plugins. | |||
</summary> | |||
</member> | |||
<member name="P:IllusionPlugin.IPlugin.Name"> | |||
<summary> | |||
Gets the name of the plugin. | |||
</summary> | |||
</member> | |||
<member name="P:IllusionPlugin.IPlugin.Version"> | |||
<summary> | |||
Gets the version of the plugin. | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnApplicationStart"> | |||
<summary> | |||
Gets invoked when the application is started. | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnApplicationQuit"> | |||
<summary> | |||
Gets invoked when the application is closed. | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnLevelWasLoaded(System.Int32)"> | |||
<summary> | |||
Gets invoked whenever a level is loaded. | |||
</summary> | |||
<param name="level"></param> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnLevelWasInitialized(System.Int32)"> | |||
<summary> | |||
Gets invoked after the first update cycle after a level was loaded. | |||
</summary> | |||
<param name="level"></param> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnUpdate"> | |||
<summary> | |||
Gets invoked on every graphic update. | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.IPlugin.OnFixedUpdate"> | |||
<summary> | |||
Gets invoked on ever physics update. | |||
</summary> | |||
</member> | |||
<member name="T:IllusionPlugin.ModPrefs"> | |||
<summary> | |||
Allows to get and set preferences for your mod. | |||
</summary> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.GetString(System.String,System.String,System.String,System.Boolean)"> | |||
<summary> | |||
Gets a string from the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="defaultValue">Value that should be used when no value is found.</param> | |||
<param name="autoSave">Whether or not the default value should be written if no value is found.</param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.GetInt(System.String,System.String,System.Int32,System.Boolean)"> | |||
<summary> | |||
Gets an int from the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="defaultValue">Value that should be used when no value is found.</param> | |||
<param name="autoSave">Whether or not the default value should be written if no value is found.</param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.GetFloat(System.String,System.String,System.Single,System.Boolean)"> | |||
<summary> | |||
Gets a float from the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="defaultValue">Value that should be used when no value is found.</param> | |||
<param name="autoSave">Whether or not the default value should be written if no value is found.</param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.GetBool(System.String,System.String,System.Boolean,System.Boolean)"> | |||
<summary> | |||
Gets a bool from the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="defaultValue">Value that should be used when no value is found.</param> | |||
<param name="autoSave">Whether or not the default value should be written if no value is found.</param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.HasKey(System.String,System.String)"> | |||
<summary> | |||
Checks whether or not a key exists in the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<returns></returns> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.SetFloat(System.String,System.String,System.Single)"> | |||
<summary> | |||
Sets a float in the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="value">Value that should be written.</param> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.SetInt(System.String,System.String,System.Int32)"> | |||
<summary> | |||
Sets an int in the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="value">Value that should be written.</param> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.SetString(System.String,System.String,System.String)"> | |||
<summary> | |||
Sets a string in the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="value">Value that should be written.</param> | |||
</member> | |||
<member name="M:IllusionPlugin.ModPrefs.SetBool(System.String,System.String,System.Boolean)"> | |||
<summary> | |||
Sets a bool in the ini. | |||
</summary> | |||
<param name="section">Section of the key.</param> | |||
<param name="name">Name of the key.</param> | |||
<param name="value">Value that should be written.</param> | |||
</member> | |||
</members> | |||
</doc> |
@@ -0,0 +1,55 @@ | |||
<?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" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="IEnhancedPlugin.cs" /> | |||
<Compile Include="IniFile.cs" /> | |||
<Compile Include="IPlugin.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> |
@@ -0,0 +1,89 @@ | |||
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; | |||
} | |||
} | |||
/// <summary> | |||
/// INIFile Constructor. | |||
/// </summary> | |||
/// <PARAM name="INIPath"></PARAM> | |||
public IniFile(string 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, this.Path); | |||
} | |||
/// <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, this.Path); | |||
return result.ToString(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,166 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Text; | |||
namespace IllusionPlugin | |||
{ | |||
/// <summary> | |||
/// Allows to get and set preferences for your mod. | |||
/// </summary> | |||
public static class ModPrefs | |||
{ | |||
private static IniFile _instance; | |||
private static IniFile Instance | |||
{ | |||
get | |||
{ | |||
if (_instance == null) | |||
{ | |||
_instance = new IniFile(Path.Combine(Environment.CurrentDirectory, "UserData/modprefs.ini")); | |||
} | |||
return _instance; | |||
} | |||
} | |||
/// <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 static string GetString(string section, string name, string defaultValue = "", bool autoSave = false) | |||
{ | |||
string 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 static int GetInt(string section, string name, int defaultValue = 0, bool autoSave = false) | |||
{ | |||
int value; | |||
if (int.TryParse(Instance.IniReadValue(section, name), out 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 static float GetFloat(string section, string name, float defaultValue = 0f, bool autoSave = false) | |||
{ | |||
float value; | |||
if (float.TryParse(Instance.IniReadValue(section, name), out 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 static 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 static 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 static 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 static 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 static 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 static void SetBool(string section, string name, bool value) | |||
{ | |||
Instance.IniWriteValue(section, name, value ? "1" : "0"); | |||
} | |||
} | |||
} |
@@ -0,0 +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("IllusionPlugin")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("IllusionPlugin")] | |||
[assembly: AssemblyCopyright("Copyright © 2015")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
// Setting ComVisible to false makes the types in this assembly not visible | |||
// to COM components. If you need to access a type in this assembly from | |||
// COM, set the ComVisible attribute to true on that type. | |||
[assembly: ComVisible(false)] | |||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||
[assembly: Guid("e8cea89d-6c2f-4729-94b3-f355f7db19e5")] | |||
// 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,0 +1,104 @@ | |||
<?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>QuietLauncher</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> | |||
<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.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> | |||
</Compile> | |||
<EmbeddedResource Include="Resources.resx"> | |||
<Generator>ResXFileCodeGenerator</Generator> | |||
<LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||
</EmbeddedResource> | |||
<None Include="packages.config" /> | |||
<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> | |||
<None Include="Resources\DirectToRift.exe" /> | |||
</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,0 +1,299 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Windows.Forms; | |||
using Mono.Cecil; | |||
using Mono.Cecil.Cil; | |||
using System.Threading; | |||
namespace QuietLauncher | |||
{ | |||
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) return; | |||
bool vrMode = fileName.IndexOf("VR") > 0; | |||
bool directMode = Application.ExecutablePath.EndsWith("_DirectToRift.exe"); | |||
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(); | |||
bool created = false; | |||
var dataFolder = Path.Combine(file.DirectoryName, Path.GetFileNameWithoutExtension(file.Name) + "_Data"); | |||
var assemblyPath = Path.Combine(Path.Combine(dataFolder, "Managed"), "Assembly-CSharp.dll"); | |||
var enginePath = Path.Combine(Path.Combine(dataFolder, "Managed"), "UnityEngine.dll"); | |||
var directToRiftPath = baseName + "_DirectToRift.exe"; | |||
try | |||
{ | |||
if (directMode) | |||
{ | |||
//args[Array.IndexOf(args, "--direct")] = "-force-d3d11"; | |||
if (!File.Exists(directToRiftPath)) | |||
{ | |||
File.WriteAllBytes(directToRiftPath, Resources.DirectToRift); | |||
created = true; | |||
} | |||
file = new FileInfo(directToRiftPath); | |||
} | |||
if (vrMode) args.Add("--vr"); | |||
var arguments = string.Join(" ", args.ToArray()); | |||
try | |||
{ | |||
Patch(assemblyPath, enginePath); | |||
} | |||
catch (Exception ex) | |||
{ | |||
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||
} | |||
Process.Start(file.FullName, arguments); | |||
} | |||
finally | |||
{ | |||
if (created && directMode) | |||
{ | |||
var thread = new Thread(new ThreadStart(delegate | |||
{ | |||
int attempts = 0; | |||
while (File.Exists(directToRiftPath) && attempts++ < 20) | |||
{ | |||
Thread.Sleep(1000); | |||
try | |||
{ | |||
File.Delete(directToRiftPath); | |||
} | |||
catch (Exception ex) | |||
{ | |||
} | |||
} | |||
})); | |||
thread.Start(); | |||
thread.Join(); | |||
// Clean up | |||
} | |||
} | |||
} | |||
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); | |||
} | |||
} | |||
static string PrepareBackup(FileInfo file) | |||
{ | |||
string backup = file.FullName + ".Original"; | |||
if (File.Exists(backup)) | |||
{ | |||
int i = 1; | |||
string backupBase = backup; | |||
while (File.Exists(backup)) | |||
{ | |||
backup = backupBase + i++; | |||
} | |||
} | |||
return backup; | |||
} | |||
static void Patch(string assemblyFile, string engineFile) | |||
{ | |||
var input = new FileInfo(assemblyFile); | |||
var engineInput = new FileInfo(engineFile); | |||
string assemblyBackup = PrepareBackup(input); | |||
string engineBackup = PrepareBackup(engineInput); | |||
if (!input.Exists) Fail("File does not exist."); | |||
var directory = input.DirectoryName; | |||
var injectorPath = Path.Combine(directory, "IllusionInjector.dll"); | |||
if (!File.Exists(injectorPath)) Fail("You're missing IllusionInjector.dll. Please make sure to extract all files correctly."); | |||
var resolver = new DefaultAssemblyResolver(); | |||
resolver.AddSearchDirectory(directory); | |||
var parameters = new ReaderParameters | |||
{ | |||
// SymbolReaderProvider = GetSymbolReaderProvider(), | |||
AssemblyResolver = resolver, | |||
}; | |||
var assemblyModule = ModuleDefinition.ReadModule(input.FullName, parameters); | |||
var engineModule = ModuleDefinition.ReadModule(engineInput.FullName, parameters); | |||
if (!IsPatched(engineModule)) //|| !isVirtualized) | |||
{ | |||
// Make backup | |||
input.CopyTo(engineBackup); | |||
// First, let's add the reference | |||
var nameReference = new AssemblyNameReference("IllusionInjector", new Version(1, 0, 0, 0)); | |||
engineModule.AssemblyReferences.Add(nameReference); | |||
var targetType = FindEntryType(engineModule); | |||
if (targetType == null) Fail("Couldn't find entry class. Aborting."); | |||
var awakeMethod = targetType.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic); | |||
if (awakeMethod == null) | |||
{ | |||
Fail("Couldn't find awake method. Aborting."); | |||
} | |||
var injector = ModuleDefinition.ReadModule(injectorPath); | |||
var methodReference = engineModule.Import(injector.GetType("IllusionInjector.Injector").Methods.First(m => m.Name == "Inject")); | |||
//var methodReference = module.GetMemberReferences().FirstOrDefault(r => r.FullName == "IllusionInjector.Injector"); | |||
awakeMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, methodReference)); | |||
engineModule.Write(engineInput.FullName); | |||
} | |||
if(!IsVirtualized(assemblyModule)) | |||
{ | |||
input.CopyTo(assemblyBackup); | |||
Virtualize(assemblyModule); | |||
assemblyModule.Write(input.FullName); | |||
} | |||
} | |||
/// <summary> | |||
/// The forbidden deed of the gods -- make ALL methods virtual and public | |||
/// </summary> | |||
/// <param name="module"></param> | |||
private static void Virtualize(ModuleDefinition module) | |||
{ | |||
foreach (var type in module.Types) | |||
{ | |||
VirtualizeType(type); | |||
} | |||
} | |||
private static void VirtualizeType(TypeDefinition type) | |||
{ | |||
if (type.IsSealed) return; | |||
if (type.IsInterface) return; | |||
if (type.IsAbstract) return; | |||
// These two don't seem to work. | |||
if (type.Name == "SceneControl" || type.Name == "ConfigUI") return; | |||
//if (type.FullName.Contains("RootMotion")) return; | |||
//if (type.Methods.Any(m => m.Body != null && m.Body.Variables.Any(v => v.VariableType.FullName.Contains("<")))) return; | |||
//if (!type.FullName.Contains("H_VoiceControl")) return; | |||
//if (!type.FullName.Contains("Human")) return; | |||
//if (type.Namespace.Length > 1) return; | |||
// Take care of sub types | |||
foreach (var subType in type.NestedTypes) | |||
{ | |||
VirtualizeType(subType); | |||
} | |||
foreach (var method in type.Methods) | |||
{ | |||
Console.WriteLine(method.Name); | |||
if (method.IsManaged | |||
&& !TABOO_NAMES.Contains(method.Name) | |||
&& method.IsIL | |||
&& !method.IsStatic | |||
&& !method.IsVirtual | |||
&& !method.IsAbstract | |||
&& !method.IsAddOn | |||
&& !method.IsConstructor | |||
&& !method.IsSpecialName | |||
&& !method.IsGenericInstance | |||
&& !method.HasOverrides) | |||
{ | |||
method.IsVirtual = true; | |||
method.IsPublic = true; | |||
method.IsPrivate = false; | |||
method.IsNewSlot = true; | |||
method.IsHideBySig = true; | |||
} | |||
} | |||
foreach (var field in type.Fields) | |||
{ | |||
if (field.IsPrivate) field.IsFamily = true; | |||
//field.IsPublic = true; | |||
} | |||
//foreach (var property in type.Properties) | |||
//{ | |||
// property.GetMethod.IsVirtual = true; | |||
// property.GetMethod.IsPublic = true; | |||
// property.SetMethod.IsVirtual = true; | |||
// property.SetMethod.IsPublic = true; | |||
//} | |||
} | |||
private static bool IsPatched(ModuleDefinition module) | |||
{ | |||
foreach (var @ref in module.AssemblyReferences) | |||
{ | |||
if (@ref.Name == "IllusionInjector") return true; | |||
} | |||
return false; | |||
} | |||
private static bool IsVirtualized(ModuleDefinition module) | |||
{ | |||
return module.GetTypes().SelectMany(t => t.Methods.Where(m => m.Name == "Awake")).All(m => m.IsVirtual); | |||
} | |||
private static void Fail(string reason) { | |||
throw new Exception(reason); | |||
} | |||
private static TypeDefinition FindEntryType(ModuleDefinition module) | |||
{ | |||
return module.GetTypes().FirstOrDefault(IsEntryType); | |||
} | |||
private static bool IsEntryType(TypeDefinition type) | |||
{ | |||
return ENTRY_TYPES.Contains(type.Name); | |||
} | |||
} | |||
} |
@@ -0,0 +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("QuietLauncher")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("QuietLauncher")] | |||
[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,0 +1,71 @@ | |||
//------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by a tool. | |||
// Runtime Version:4.0.30319.34209 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// </auto-generated> | |||
//------------------------------------------------------------------------------ | |||
namespace QuietLauncher.Properties | |||
{ | |||
/// <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 ((resourceMan == null)) | |||
{ | |||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("QuietLauncher.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,0 +1,117 @@ | |||
<?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,0 +1,30 @@ | |||
//------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by a tool. | |||
// Runtime Version:4.0.30319.34209 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// </auto-generated> | |||
//------------------------------------------------------------------------------ | |||
namespace QuietLauncher.Properties | |||
{ | |||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] | |||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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,0 +1,7 @@ | |||
<?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,0 +1,73 @@ | |||
//------------------------------------------------------------------------------ | |||
// <auto-generated> | |||
// This code was generated by a tool. | |||
// Runtime Version:4.0.30319.34209 | |||
// | |||
// Changes to this file may cause incorrect behavior and will be lost if | |||
// the code is regenerated. | |||
// </auto-generated> | |||
//------------------------------------------------------------------------------ | |||
namespace QuietLauncher { | |||
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("QuietLauncher.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; | |||
} | |||
} | |||
/// <summary> | |||
/// Looks up a localized resource of type System.Byte[]. | |||
/// </summary> | |||
internal static byte[] DirectToRift { | |||
get { | |||
object obj = ResourceManager.GetObject("DirectToRift", resourceCulture); | |||
return ((byte[])(obj)); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,124 @@ | |||
<?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" /> | |||
<data name="DirectToRift" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||
<value>Resources\DirectToRift.exe;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</data> | |||
</root> |
@@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net35" /> | |||
</packages> |