mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Implement prototype .NET loader
This commit is contained in:
12 files changed
+545
-2
No files matched your search
@@ -85,6 +85,11 @@ namespace BepInEx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ForceSetActive(bool value)
|
||||||
|
{
|
||||||
|
ConsoleActive = value;
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
|
public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
|
||||||
"Logging.Console", "Enabled",
|
"Logging.Console", "Enabled",
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace BepInEx.NetLauncher
|
||||||
|
{
|
||||||
|
public abstract class BasePlugin
|
||||||
|
{
|
||||||
|
protected HarmonyLib.Harmony HarmonyInstance { get; }
|
||||||
|
|
||||||
|
protected BasePlugin()
|
||||||
|
{
|
||||||
|
//var info = PluginInfoHelper.GetPluginInfo(this);
|
||||||
|
|
||||||
|
//HarmonyInstance = new HarmonyLib.Harmony("BepInEx.Plugin." + info.GUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Load();
|
||||||
|
|
||||||
|
public virtual bool Unload()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{490B052B-7F23-4052-AD04-613856618901}</ProjectGuid>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>BepInEx.NetLauncher</RootNamespace>
|
||||||
|
<AssemblyName>BepInEx.NetLauncher</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\bin\net\</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\net\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Mono.Cecil, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Mono.Cecil.Mdb, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Mono.Cecil.Pdb, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Mono.Cecil.Rocks, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Rocks.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="MonoMod.RuntimeDetour, Version=20.4.3.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\MonoMod.RuntimeDetour.20.4.3.1\lib\net40\MonoMod.RuntimeDetour.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="MonoMod.Utils, Version=20.4.3.1, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\MonoMod.Utils.20.4.3.1\lib\net40\MonoMod.Utils.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="BasePlugin.cs" />
|
||||||
|
<Compile Include="NetChainloader.cs" />
|
||||||
|
<Compile Include="NetPreloader.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Utility.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\BepInEx.Core\BepInEx.Core.csproj">
|
||||||
|
<Project>{4ffba620-f5ed-47f9-b90c-dad1316fd9b9}</Project>
|
||||||
|
<Name>BepInEx.Core</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj">
|
||||||
|
<Project>{15f8bc38-a761-4f93-8903-1b531ac5d9f9}</Project>
|
||||||
|
<Name>BepInEx.Preloader.Core</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\submodules\BepInEx.Harmony\BepInEx.Harmony\BepInEx.Harmony.csproj">
|
||||||
|
<Project>{54161cfe-ff42-4dde-b161-3a49545db5cd}</Project>
|
||||||
|
<Name>BepInEx.Harmony</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\submodules\BepInEx.Harmony\submodules\Harmony\Harmony\Harmony.csproj">
|
||||||
|
<Project>{a15d6ee6-f954-415b-8605-8a8470cc87dc}</Project>
|
||||||
|
<Name>Harmony</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using BepInEx.Bootstrap;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher
|
||||||
|
{
|
||||||
|
public class NetChainloader : BaseChainloader<BasePlugin>
|
||||||
|
{
|
||||||
|
public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly)
|
||||||
|
{
|
||||||
|
var type = pluginAssembly.GetType(pluginInfo.TypeName);
|
||||||
|
|
||||||
|
var pluginInstance = (BasePlugin)Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
pluginInstance.Load();
|
||||||
|
|
||||||
|
return pluginInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using BepInEx.Bootstrap;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using BepInEx.Preloader.Core;
|
||||||
|
using BepInEx.Preloader.Core.RuntimeFixes;
|
||||||
|
using MonoMod.RuntimeDetour;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher
|
||||||
|
{
|
||||||
|
public static class NetPreloader
|
||||||
|
{
|
||||||
|
private static readonly ManualLogSource Log = PreloaderLogger.Log;
|
||||||
|
|
||||||
|
|
||||||
|
public static void Start(string[] args)
|
||||||
|
{
|
||||||
|
if (ConfigEntrypointExecutable.Value == null)
|
||||||
|
{
|
||||||
|
Log.LogFatal($"Entry executable was not set. Please set this in your config before launching the application");
|
||||||
|
Program.ReadExit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string executablePath = Path.GetFullPath(ConfigEntrypointExecutable.Value);
|
||||||
|
|
||||||
|
if (!File.Exists(executablePath))
|
||||||
|
{
|
||||||
|
Log.LogFatal($"Unable to locate executable: {ConfigEntrypointExecutable.Value}");
|
||||||
|
Program.ReadExit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Paths.SetExecutablePath(executablePath);
|
||||||
|
Program.ResolveDirectories.Add(Paths.GameRootPath);
|
||||||
|
TypeLoader.SearchDirectories.Add(Paths.GameRootPath);
|
||||||
|
|
||||||
|
bool bridgeInitialized = Utility.TryDo(() =>
|
||||||
|
{
|
||||||
|
if (ConfigShimHarmony.Value)
|
||||||
|
HarmonyDetourBridge.Init();
|
||||||
|
}, out var harmonyBridgeException);
|
||||||
|
|
||||||
|
Logger.Sources.Add(TraceLogSource.CreateSource());
|
||||||
|
|
||||||
|
HarmonyFixes.Apply();
|
||||||
|
|
||||||
|
string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Process.GetCurrentProcess().ProcessName}";
|
||||||
|
Log.LogMessage(consoleTile);
|
||||||
|
|
||||||
|
if (ConsoleManager.ConsoleActive)
|
||||||
|
ConsoleManager.SetConsoleTitle(consoleTile);
|
||||||
|
|
||||||
|
//See BuildInfoAttribute for more information about this section.
|
||||||
|
object[] attributes = typeof(BuildInfoAttribute).Assembly.GetCustomAttributes(typeof(BuildInfoAttribute), false);
|
||||||
|
|
||||||
|
if (attributes.Length > 0)
|
||||||
|
{
|
||||||
|
var attribute = (BuildInfoAttribute)attributes[0];
|
||||||
|
Log.LogMessage(attribute.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.LogInfo($"CLR runtime version: {Environment.Version}");
|
||||||
|
|
||||||
|
if (harmonyBridgeException != null)
|
||||||
|
Log.LogWarning($"Failed to enable fix for Harmony for .NET Standard API. Error message: {harmonyBridgeException.Message}");
|
||||||
|
|
||||||
|
Log.LogMessage("Preloader started");
|
||||||
|
|
||||||
|
|
||||||
|
using (var assemblyPatcher = new AssemblyPatcher())
|
||||||
|
{
|
||||||
|
assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);
|
||||||
|
|
||||||
|
Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} patcher plugin(s) loaded");
|
||||||
|
|
||||||
|
assemblyPatcher.LoadAssemblyDirectory(Paths.GameRootPath, "dll", "exe");
|
||||||
|
|
||||||
|
Log.LogInfo($"{assemblyPatcher.AssembliesToPatch.Count} assemblies discovered");
|
||||||
|
|
||||||
|
assemblyPatcher.PatchAndLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.LogMessage("Preloader finished");
|
||||||
|
|
||||||
|
var chainloader = new NetChainloader();
|
||||||
|
chainloader.Initialize();
|
||||||
|
chainloader.Execute();
|
||||||
|
|
||||||
|
var assemblyName = AssemblyName.GetAssemblyName(executablePath);
|
||||||
|
var entrypointAssembly = Assembly.Load(assemblyName);
|
||||||
|
|
||||||
|
entrypointAssembly.EntryPoint.Invoke(null, new [] { args });
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Config
|
||||||
|
|
||||||
|
private static readonly ConfigEntry<string> ConfigEntrypointExecutable = ConfigFile.CoreConfig.Bind<string>(
|
||||||
|
"Preloader.Entrypoint", "Assembly",
|
||||||
|
null,
|
||||||
|
"The local filename of the .NET executable to target.");
|
||||||
|
|
||||||
|
private static readonly ConfigEntry<bool> ConfigShimHarmony = ConfigFile.CoreConfig.Bind(
|
||||||
|
"Preloader", "ShimHarmonySupport",
|
||||||
|
!Utility.CLRSupportsDynamicAssemblies,
|
||||||
|
"If enabled, basic Harmony functionality is patched to use MonoMod's RuntimeDetour instead.\nTry using this if Harmony does not work in a game.");
|
||||||
|
|
||||||
|
private static readonly ConfigEntry<bool> ConfigPreloaderCOutLogging = ConfigFile.CoreConfig.Bind(
|
||||||
|
"Logging", "PreloaderConsoleOutRedirection",
|
||||||
|
true,
|
||||||
|
"Redirects text from Console.Out during preloader patch loading to the BepInEx logging system.");
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using BepInEx.Preloader.Core;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher
|
||||||
|
{
|
||||||
|
internal static class NetPreloaderRunner
|
||||||
|
{
|
||||||
|
internal static void PreloaderMain(string[] args)
|
||||||
|
{
|
||||||
|
Logger.Listeners.Add(new ConsoleLogListener());
|
||||||
|
|
||||||
|
ConsoleManager.ForceSetActive(true);
|
||||||
|
|
||||||
|
NetPreloader.Start(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void OuterMain(string[] args, string filename)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Paths.SetExecutablePath(filename);
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
|
||||||
|
|
||||||
|
PreloaderMain(args);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
PreloaderLogger.Log.LogFatal("Unhandled exception");
|
||||||
|
PreloaderLogger.Log.LogFatal(ex);
|
||||||
|
Program.ReadExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Assembly LocalResolve(object sender, ResolveEventArgs args)
|
||||||
|
{
|
||||||
|
var assemblyName = new AssemblyName(args.Name);
|
||||||
|
|
||||||
|
var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
|
.FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
|
||||||
|
|
||||||
|
if (foundAssembly != null)
|
||||||
|
return foundAssembly;
|
||||||
|
|
||||||
|
if (LocalUtility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out foundAssembly)
|
||||||
|
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out foundAssembly)
|
||||||
|
|| LocalUtility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out foundAssembly))
|
||||||
|
return foundAssembly;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
internal static void ReadExit()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Press enter to exit...");
|
||||||
|
Console.ReadLine();
|
||||||
|
Environment.Exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("test");
|
||||||
|
|
||||||
|
string filename;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
filename = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName));
|
||||||
|
|
||||||
|
#else
|
||||||
|
filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "Core"));
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += RemoteResolve;
|
||||||
|
|
||||||
|
NetPreloaderRunner.OuterMain(args, filename);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Unhandled exception");
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
ReadExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> ResolveDirectories { get; set; } = new List<string>
|
||||||
|
{
|
||||||
|
"C:\\Windows\\Microsoft.NET\\assembly\\GAC_32\\Microsoft.Xna.Framework.Game\\v4.0_4.0.0.0__842cf8be1de50553\\"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Assembly RemoteResolve(object sender, ResolveEventArgs reference)
|
||||||
|
{
|
||||||
|
var assemblyName = new AssemblyName(reference.Name);
|
||||||
|
|
||||||
|
foreach (var directory in ResolveDirectories)
|
||||||
|
{
|
||||||
|
var potentialDirectories = new List<string> { directory };
|
||||||
|
|
||||||
|
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
var potentialFiles = potentialDirectories.Select(x => Path.Combine(x, $"{assemblyName.Name}.dll"))
|
||||||
|
.Concat(potentialDirectories.Select(x => Path.Combine(x, $"{assemblyName.Name}.exe")));
|
||||||
|
|
||||||
|
foreach (string path in potentialFiles)
|
||||||
|
{
|
||||||
|
if (!File.Exists(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var assembly = Assembly.LoadFrom(path);
|
||||||
|
|
||||||
|
if (assembly.GetName().Name == assemblyName.Name)
|
||||||
|
return assembly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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("BepInEx.NetLauncher")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("BepInEx.NetLauncher")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||||
|
[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("490b052b-7f23-4052-ad04-613856618901")]
|
||||||
|
|
||||||
|
// 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,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Generic helper properties and methods.
|
||||||
|
/// </summary>
|
||||||
|
public static class LocalUtility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve and load the given assembly DLL.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||||
|
/// <param name="directory">Directory to search the assembly from.</param>
|
||||||
|
/// <param name="assembly">The loaded assembly.</param>
|
||||||
|
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||||
|
private static bool TryResolveDllAssembly<T>(AssemblyName assemblyName, string directory, Func<string, T> loader, out T assembly) where T : class
|
||||||
|
{
|
||||||
|
assembly = null;
|
||||||
|
|
||||||
|
var potentialDirectories = new List<string> { directory };
|
||||||
|
|
||||||
|
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
foreach (string subDirectory in potentialDirectories)
|
||||||
|
{
|
||||||
|
string path = Path.Combine(subDirectory, $"{assemblyName.Name}.dll");
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assembly = loader(path);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to resolve and load the given assembly DLL.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assemblyName">Name of the assembly, of the type <see cref="AssemblyName" />.</param>
|
||||||
|
/// <param name="directory">Directory to search the assembly from.</param>
|
||||||
|
/// <param name="assembly">The loaded assembly.</param>
|
||||||
|
/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
|
||||||
|
public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly)
|
||||||
|
{
|
||||||
|
return TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Mono.Cecil" version="0.11.2" targetFramework="net452" />
|
||||||
|
<package id="MonoMod.RuntimeDetour" version="20.4.3.1" targetFramework="net452" />
|
||||||
|
<package id="MonoMod.Utils" version="20.4.3.1" targetFramework="net452" />
|
||||||
|
</packages>
|
||||||
@@ -43,7 +43,7 @@ namespace BepInEx.Preloader.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string DumpedAssembliesPath { get; set; } = Path.Combine(Paths.BepInExRootPath, "DumpedAssemblies");
|
public string DumpedAssembliesPath { get; set; } = Path.Combine(Paths.BepInExRootPath, "DumpedAssemblies");
|
||||||
|
|
||||||
public ManualLogSource Logger { get; } = new ManualLogSource("AssemblyPatcher");
|
public ManualLogSource Logger { get; } = BepInEx.Logging.Logger.CreateLogSource("AssemblyPatcher");
|
||||||
|
|
||||||
private static T CreateDelegate<T>(MethodInfo method) where T : class => method != null ? Delegate.CreateDelegate(typeof(T), method) as T : null;
|
private static T CreateDelegate<T>(MethodInfo method) where T : class => method != null ? Delegate.CreateDelegate(typeof(T), method) as T : null;
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ namespace BepInEx.Preloader.Core
|
|||||||
public void LoadAssemblyDirectory(string directory, params string[] assemblyExtensions)
|
public void LoadAssemblyDirectory(string directory, params string[] assemblyExtensions)
|
||||||
{
|
{
|
||||||
var filesToSearch = assemblyExtensions
|
var filesToSearch = assemblyExtensions
|
||||||
.SelectMany(ext => Directory.GetFiles(directory, "*." + ext));
|
.SelectMany(ext => Directory.GetFiles(directory, "*." + ext, SearchOption.TopDirectoryOnly));
|
||||||
|
|
||||||
foreach (string assemblyPath in filesToSearch)
|
foreach (string assemblyPath in filesToSearch)
|
||||||
{
|
{
|
||||||
@@ -192,6 +192,8 @@ namespace BepInEx.Preloader.Core
|
|||||||
|
|
||||||
AssembliesToPatch.Add(Path.GetFileName(assemblyPath), assembly);
|
AssembliesToPatch.Add(Path.GetFileName(assemblyPath), assembly);
|
||||||
|
|
||||||
|
Logger.LogDebug($"Assembly loaded: {Path.GetFileName(assemblyPath)}");
|
||||||
|
|
||||||
//if (UnityPatches.AssemblyLocations.ContainsKey(assembly.FullName))
|
//if (UnityPatches.AssemblyLocations.ContainsKey(assembly.FullName))
|
||||||
//{
|
//{
|
||||||
// Logger.LogWarning($"Tried to load duplicate assembly {Path.GetFileName(assemblyPath)} from Managed folder! Skipping...");
|
// Logger.LogWarning($"Tried to load duplicate assembly {Path.GetFileName(assemblyPath)} from Managed folder! Skipping...");
|
||||||
@@ -343,6 +345,8 @@ namespace BepInEx.Preloader.Core
|
|||||||
Assembly.Load(assemblyStream.ToArray());
|
Assembly.Load(assemblyStream.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.LogDebug($"Loaded '{assembly.FullName}' into memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Though we have to dispose of all assemblies regardless of them being patched or not
|
// Though we have to dispose of all assemblies regardless of them being patched or not
|
||||||
|
|||||||
+42
@@ -34,47 +34,88 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.Core", "BepInEx.Cor
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unity", "Unity", "{6E2DD21E-0854-4F4A-B925-D90E0016D03D}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unity", "Unity", "{6E2DD21E-0854-4F4A-B925-D90E0016D03D}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.NetLauncher", "BepInEx.NetLauncher\BepInEx.NetLauncher.csproj", "{490B052B-7F23-4052-AD04-613856618901}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetFramework", "NetFramework", "{6EC98884-A3DC-4828-85EF-5F10F7519429}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release_NetFramework|Any CPU = Release_NetFramework|Any CPU
|
||||||
|
Release_Unity|Any CPU = Release_Unity|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Debug|Any CPU.Build.0 = Release|Any CPU
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release|Any CPU.Build.0 = Release|Any CPU
|
{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Debug|Any CPU.Build.0 = Release|Any CPU
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release|Any CPU.Build.0 = Release|Any CPU
|
{54161CFE-FF42-4DDE-B161-3A49545DB5CD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Debug|Any CPU.ActiveCfg = Debug|x86
|
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Debug|Any CPU.Build.0 = Debug|x86
|
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
|
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Release_NetFramework|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Release_Unity|Any CPU.ActiveCfg = Release|x86
|
||||||
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Release|Any CPU.ActiveCfg = Release|x86
|
{E7CD429A-D057-48E3-8C51-E5C934E8E07B}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
{15F8BC38-A761-4F93-8903-1B531AC5D9F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D404C973-441D-48ED-B266-C21320BA0D87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D404C973-441D-48ED-B266-C21320BA0D87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D404C973-441D-48ED-B266-C21320BA0D87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D404C973-441D-48ED-B266-C21320BA0D87}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D404C973-441D-48ED-B266-C21320BA0D87}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -86,6 +127,7 @@ Global
|
|||||||
{A15D6EE6-F954-415B-8605-8A8470CC87DC} = {BAC58F7E-AAD8-4D0C-9490-9765ACBBA6FB}
|
{A15D6EE6-F954-415B-8605-8A8470CC87DC} = {BAC58F7E-AAD8-4D0C-9490-9765ACBBA6FB}
|
||||||
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
|
{EAE9FAE6-8011-45A3-8B6E-0C7F14210533} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
|
||||||
{D404C973-441D-48ED-B266-C21320BA0D87} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
|
{D404C973-441D-48ED-B266-C21320BA0D87} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
|
||||||
|
{490B052B-7F23-4052-AD04-613856618901} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {55AC11EF-F568-4C79-A356-7ED9510145B1}
|
SolutionGuid = {55AC11EF-F568-4C79-A356-7ED9510145B1}
|
||||||
|
|||||||
Reference in new issue
Block a user