mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-19 15:51:45 +00:00
Create .NET Core platform project
This commit is contained in:
22 files changed
+546
-164
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -94,7 +94,7 @@ public static class ConsoleManager
|
|||||||
public static TextWriter ConsoleStream => Driver?.ConsoleOut;
|
public static TextWriter ConsoleStream => Driver?.ConsoleOut;
|
||||||
|
|
||||||
|
|
||||||
public static void Initialize(bool alreadyActive)
|
public static void Initialize(bool alreadyActive, bool useWinApiEncoder)
|
||||||
{
|
{
|
||||||
if (PlatformHelper.Is(Platform.Unix))
|
if (PlatformHelper.Is(Platform.Unix))
|
||||||
Driver = new LinuxConsoleDriver();
|
Driver = new LinuxConsoleDriver();
|
||||||
@@ -104,7 +104,7 @@ public static class ConsoleManager
|
|||||||
throw new PlatformNotSupportedException("Was unable to determine console driver for platform " +
|
throw new PlatformNotSupportedException("Was unable to determine console driver for platform " +
|
||||||
PlatformHelper.Current);
|
PlatformHelper.Current);
|
||||||
|
|
||||||
Driver.Initialize(alreadyActive);
|
Driver.Initialize(alreadyActive, useWinApiEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DriverCheck()
|
private static void DriverCheck()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace BepInEx;
|
namespace BepInEx;
|
||||||
@@ -13,7 +13,7 @@ internal interface IConsoleDriver
|
|||||||
|
|
||||||
void PreventClose();
|
void PreventClose();
|
||||||
|
|
||||||
void Initialize(bool alreadyActive);
|
void Initialize(bool alreadyActive, bool useWinApiEncoder);
|
||||||
|
|
||||||
// Apparently Windows code-pages work in Mono.
|
// Apparently Windows code-pages work in Mono.
|
||||||
// https://stackoverflow.com/a/33456543
|
// https://stackoverflow.com/a/33456543
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using BepInEx.Logging;
|
using BepInEx.Logging;
|
||||||
@@ -46,7 +46,7 @@ internal class LinuxConsoleDriver : IConsoleDriver
|
|||||||
// Not supported by all distros
|
// Not supported by all distros
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(bool alreadyActive)
|
public void Initialize(bool alreadyActive, bool useWinApiEncoder)
|
||||||
{
|
{
|
||||||
// Console is always considered active on Unix
|
// Console is always considered active on Unix
|
||||||
ConsoleActive = true;
|
ConsoleActive = true;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -33,15 +33,37 @@ internal class WindowsConsoleDriver : IConsoleDriver
|
|||||||
private int ConsoleWidth => getWindowWidth?.Invoke() ?? 0;
|
private int ConsoleWidth => getWindowWidth?.Invoke() ?? 0;
|
||||||
private int ConsoleHeight => getWindowHeight?.Invoke() ?? 0;
|
private int ConsoleHeight => getWindowHeight?.Invoke() ?? 0;
|
||||||
|
|
||||||
|
private bool useWinApiEncoder;
|
||||||
|
|
||||||
public TextWriter StandardOut { get; private set; }
|
public TextWriter StandardOut { get; private set; }
|
||||||
public TextWriter ConsoleOut { get; private set; }
|
public TextWriter ConsoleOut { get; private set; }
|
||||||
|
|
||||||
public bool ConsoleActive { get; private set; }
|
public bool ConsoleActive { get; private set; }
|
||||||
public bool ConsoleIsExternal => true;
|
public bool ConsoleIsExternal => true;
|
||||||
|
|
||||||
public void Initialize(bool alreadyActive)
|
private bool TryCheckConsoleExists()
|
||||||
{
|
{
|
||||||
ConsoleActive = alreadyActive || ConsoleWidth != 0 && ConsoleHeight != 0;
|
try
|
||||||
|
{
|
||||||
|
return ConsoleWidth != 0 && ConsoleHeight != 0;
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
//System.IO.IOException: The handle is invalid.
|
||||||
|
// at System.ConsolePal.GetBufferInfo(Boolean throwOnNoConsole, Boolean & succeeded)
|
||||||
|
//at System.ConsolePal.get_WindowWidth()
|
||||||
|
//at System.Console.get_WindowWidth()
|
||||||
|
//at BepInEx.WindowsConsoleDriver.get_ConsoleWidth()
|
||||||
|
//at BepInEx.WindowsConsoleDriver.Initialize(Boolean alreadyActive)
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(bool alreadyActive, bool useWinApiEncoder)
|
||||||
|
{
|
||||||
|
ConsoleActive = alreadyActive || TryCheckConsoleExists();
|
||||||
|
this.useWinApiEncoder = useWinApiEncoder;
|
||||||
|
|
||||||
if (ConsoleActive)
|
if (ConsoleActive)
|
||||||
{
|
{
|
||||||
@@ -82,7 +104,7 @@ internal class WindowsConsoleDriver : IConsoleDriver
|
|||||||
|
|
||||||
var consoleOutStream = OpenFileStream(ConsoleWindow.ConsoleOutHandle);
|
var consoleOutStream = OpenFileStream(ConsoleWindow.ConsoleOutHandle);
|
||||||
// Can't use Console.OutputEncoding because it can be null (i.e. not preference by user)
|
// Can't use Console.OutputEncoding because it can be null (i.e. not preference by user)
|
||||||
ConsoleOut = new StreamWriter(consoleOutStream, ConsoleEncoding.OutputEncoding)
|
ConsoleOut = new StreamWriter(consoleOutStream, useWinApiEncoder ? ConsoleEncoding.OutputEncoding : Utility.UTF8NoBom)
|
||||||
{
|
{
|
||||||
AutoFlush = true
|
AutoFlush = true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("BepInEx.Preloader.Core")]
|
[assembly: InternalsVisibleTo("BepInEx.Preloader.Core")]
|
||||||
[assembly: InternalsVisibleTo("BepInEx.Unity")]
|
[assembly: InternalsVisibleTo("BepInEx.Unity")]
|
||||||
[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
|
[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
|
||||||
|
[assembly: InternalsVisibleTo("BepInEx.NetCore")]
|
||||||
[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
|
[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
|
||||||
[assembly: InternalsVisibleTo("BepInExTests")]
|
[assembly: InternalsVisibleTo("BepInExTests")]
|
||||||
@@ -41,7 +41,7 @@ public static class Preloader
|
|||||||
{
|
{
|
||||||
HarmonyBackendFix.Initialize();
|
HarmonyBackendFix.Initialize();
|
||||||
|
|
||||||
ConsoleManager.Initialize(false);
|
ConsoleManager.Initialize(false, false);
|
||||||
|
|
||||||
PreloaderLog = new PreloaderConsoleListener();
|
PreloaderLog = new PreloaderConsoleListener();
|
||||||
Logger.Listeners.Add(PreloaderLog);
|
Logger.Listeners.Add(PreloaderLog);
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<LangVersion>10</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
<LangVersion>10</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\BepInEx.NetLauncher.Common\BepInEx.NetLauncher.Common.csproj" />
|
||||||
|
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using BepInEx.NetCore;
|
||||||
|
using BepInEx.Preloader.Core;
|
||||||
|
|
||||||
|
internal class StartupHook
|
||||||
|
{
|
||||||
|
public static List<string> ResolveDirectories = new();
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string filename;
|
||||||
|
|
||||||
|
//#if DEBUG
|
||||||
|
// filename =
|
||||||
|
// Path.Combine(Directory.GetCurrentDirectory(),
|
||||||
|
// Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName));
|
||||||
|
// ResolveDirectories.Add(Path.GetDirectoryName(filename));
|
||||||
|
|
||||||
|
// // for debugging within VS
|
||||||
|
// ResolveDirectories.Add(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName));
|
||||||
|
//#else
|
||||||
|
filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||||
|
ResolveDirectories.Add(Path.Combine(Path.GetDirectoryName(filename), "BepInEx", "core"));
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += RemoteResolve;
|
||||||
|
|
||||||
|
NetCorePreloaderRunner.OuterMain(filename);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Unhandled exception");
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Assembly RemoteResolve(object sender, ResolveEventArgs reference)
|
||||||
|
{
|
||||||
|
var assemblyName = new AssemblyName(reference.Name);
|
||||||
|
|
||||||
|
foreach (var directory in ResolveDirectories)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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 (var path in potentialFiles)
|
||||||
|
{
|
||||||
|
if (!File.Exists(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Assembly assembly;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
assembly = Assembly.LoadFrom(path);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assembly.GetName().Name == assemblyName.Name)
|
||||||
|
return assembly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BepInEx.NetCore
|
||||||
|
{
|
||||||
|
internal static class NetCorePreloaderRunner
|
||||||
|
{
|
||||||
|
internal static void PreloaderMain()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConsoleManager.Initialize(false, false);
|
||||||
|
|
||||||
|
ConsoleManager.CreateConsole();
|
||||||
|
|
||||||
|
Logger.Listeners.Add(new ConsoleLogListener());
|
||||||
|
|
||||||
|
NetCorePreloader.Start();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
PreloaderLogger.Log.Log(LogLevel.Fatal, "Unhandled exception");
|
||||||
|
PreloaderLogger.Log.Log(LogLevel.Fatal, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void OuterMain(string filename)
|
||||||
|
{
|
||||||
|
PlatformUtils.SetPlatform();
|
||||||
|
|
||||||
|
Paths.SetExecutablePath(filename);
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
|
||||||
|
|
||||||
|
PreloaderMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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;
|
||||||
|
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var potentialDirectories = new List<string> { directory };
|
||||||
|
|
||||||
|
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
foreach (var subDirectory in potentialDirectories)
|
||||||
|
{
|
||||||
|
var 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) =>
|
||||||
|
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using BepInEx.Bootstrap;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using BepInEx.NetLauncher.Common;
|
||||||
|
using BepInEx.Preloader.Core;
|
||||||
|
using BepInEx.Preloader.Core.Logging;
|
||||||
|
using BepInEx.Preloader.Core.Patching;
|
||||||
|
using Mono.Cecil;
|
||||||
|
|
||||||
|
namespace BepInEx.NetCore
|
||||||
|
{
|
||||||
|
internal class NetCorePreloader
|
||||||
|
{
|
||||||
|
private static readonly ManualLogSource Log = PreloaderLogger.Log;
|
||||||
|
|
||||||
|
public static void Start()
|
||||||
|
{
|
||||||
|
var preloaderListener = new PreloaderConsoleListener();
|
||||||
|
Logger.Listeners.Add(preloaderListener);
|
||||||
|
|
||||||
|
var entrypointAssemblyPath = Path.ChangeExtension(Process.GetCurrentProcess().MainModule.FileName, "dll");
|
||||||
|
|
||||||
|
Paths.SetExecutablePath(entrypointAssemblyPath);
|
||||||
|
|
||||||
|
TypeLoader.SearchDirectories.Add(Path.GetDirectoryName(entrypointAssemblyPath));
|
||||||
|
|
||||||
|
Logger.Sources.Add(TraceLogSource.CreateSource());
|
||||||
|
|
||||||
|
ChainloaderLogHelper.PrintLogInfo(Log);
|
||||||
|
|
||||||
|
Log.Log(LogLevel.Info, $"CLR runtime version: {Environment.Version}");
|
||||||
|
|
||||||
|
|
||||||
|
AssemblyBuildInfo executableInfo;
|
||||||
|
|
||||||
|
using (var entrypointAssembly = AssemblyDefinition.ReadAssembly(entrypointAssemblyPath))
|
||||||
|
executableInfo = AssemblyBuildInfo.DetermineInfo(entrypointAssembly);
|
||||||
|
|
||||||
|
Log.LogInfo($"Game executable build architecture: {executableInfo}");
|
||||||
|
|
||||||
|
Log.Log(LogLevel.Message, "Preloader started");
|
||||||
|
|
||||||
|
using (var assemblyPatcher = new AssemblyPatcher())
|
||||||
|
{
|
||||||
|
assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);
|
||||||
|
|
||||||
|
Log.Log(LogLevel.Info,
|
||||||
|
$"{assemblyPatcher.PatcherContext.PatchDefinitions.Count} patcher definition(s) loaded");
|
||||||
|
|
||||||
|
assemblyPatcher.LoadAssemblyDirectories(new[] { Paths.GameRootPath }, new[] { "dll", "exe" });
|
||||||
|
|
||||||
|
Log.Log(LogLevel.Info, $"{assemblyPatcher.PatcherContext.AvailableAssemblies.Count} assemblies discovered");
|
||||||
|
|
||||||
|
assemblyPatcher.PatchAndLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.LogMessage("Preloader finished");
|
||||||
|
|
||||||
|
Logger.Listeners.Remove(preloaderListener);
|
||||||
|
|
||||||
|
var chainloader = new NetChainloader();
|
||||||
|
chainloader.Initialize();
|
||||||
|
chainloader.Execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using BepInEx.Configuration;
|
||||||
|
using BepInEx.Logging;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher.Common
|
||||||
|
{
|
||||||
|
public abstract class BasePlugin
|
||||||
|
{
|
||||||
|
protected BasePlugin()
|
||||||
|
{
|
||||||
|
var metadata = MetadataHelper.GetMetadata(this);
|
||||||
|
|
||||||
|
HarmonyInstance = new Harmony("BepInEx.Plugin." + metadata.GUID);
|
||||||
|
|
||||||
|
Log = Logger.CreateLogSource(metadata.Name);
|
||||||
|
|
||||||
|
Config = new ConfigFile(Utility.CombinePaths(Paths.ConfigPath, metadata.GUID + ".cfg"), false, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManualLogSource Log { get; }
|
||||||
|
|
||||||
|
public ConfigFile Config { get; }
|
||||||
|
|
||||||
|
public Harmony HarmonyInstance { get; set; }
|
||||||
|
|
||||||
|
public abstract void Load();
|
||||||
|
|
||||||
|
public virtual bool Unload() => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netstandard2.1;net40</TargetFrameworks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="HarmonyX" Version="2.8.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\BepInEx.Core\BepInEx.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using BepInEx.Bootstrap;
|
||||||
|
using BepInEx.Preloader.Core.Logging;
|
||||||
|
|
||||||
|
namespace BepInEx.NetLauncher.Common
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void InitializeLoggers()
|
||||||
|
{
|
||||||
|
base.InitializeLoggers();
|
||||||
|
|
||||||
|
ChainloaderLogHelper.RewritePreloaderLogs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using BepInEx.Configuration;
|
|
||||||
using BepInEx.Logging;
|
|
||||||
using HarmonyLib;
|
|
||||||
|
|
||||||
namespace BepInEx.NetLauncher;
|
|
||||||
|
|
||||||
public abstract class BasePlugin
|
|
||||||
{
|
|
||||||
protected BasePlugin()
|
|
||||||
{
|
|
||||||
var metadata = MetadataHelper.GetMetadata(this);
|
|
||||||
|
|
||||||
HarmonyInstance = new Harmony("BepInEx.Plugin." + metadata.GUID);
|
|
||||||
|
|
||||||
Log = Logger.CreateLogSource(metadata.Name);
|
|
||||||
|
|
||||||
Config = new ConfigFile(Utility.CombinePaths(Paths.ConfigPath, metadata.GUID + ".cfg"), false, metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ManualLogSource Log { get; }
|
|
||||||
|
|
||||||
public ConfigFile Config { get; }
|
|
||||||
|
|
||||||
public Harmony HarmonyInstance { get; set; }
|
|
||||||
|
|
||||||
public abstract void Load();
|
|
||||||
|
|
||||||
public virtual bool Unload() => false;
|
|
||||||
}
|
|
||||||
@@ -17,17 +17,18 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>portable</DebugType>
|
<DebugType>portable</DebugType>
|
||||||
<OutputPath>..\bin\NetLauncher\</OutputPath>
|
<OutputPath>..\bin\NetLauncher\</OutputPath>
|
||||||
<DocumentationFile/>
|
<DocumentationFile />
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\BepInEx.Core\BepInEx.Core.csproj"/>
|
<ProjectReference Include="..\BepInEx.Core\BepInEx.Core.csproj" />
|
||||||
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj" PrivateAssets="All"/>
|
<ProjectReference Include="..\BepInEx.NetLauncher.Common\BepInEx.NetLauncher.Common.csproj" />
|
||||||
|
<ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="HarmonyX" Version="2.8.0"/>
|
<PackageReference Include="HarmonyX" Version="2.8.0" />
|
||||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All"/>
|
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="..\BepInEx.Shared\BepInEx.Shared.projitems" Label="Shared"/>
|
<Import Project="..\BepInEx.Shared\BepInEx.Shared.projitems" Label="Shared" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using BepInEx.Bootstrap;
|
|
||||||
using BepInEx.Preloader.Core.Logging;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void InitializeLoggers()
|
|
||||||
{
|
|
||||||
base.InitializeLoggers();
|
|
||||||
|
|
||||||
ChainloaderLogHelper.RewritePreloaderLogs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
|
|||||||
using BepInEx.Bootstrap;
|
using BepInEx.Bootstrap;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using BepInEx.Logging;
|
using BepInEx.Logging;
|
||||||
|
using BepInEx.NetLauncher.Common;
|
||||||
using BepInEx.NetLauncher.RuntimeFixes;
|
using BepInEx.NetLauncher.RuntimeFixes;
|
||||||
using BepInEx.Preloader.Core;
|
using BepInEx.Preloader.Core;
|
||||||
using BepInEx.Preloader.Core.Logging;
|
using BepInEx.Preloader.Core.Logging;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ internal static class NetPreloaderRunner
|
|||||||
{
|
{
|
||||||
Logger.Listeners.Add(new ConsoleLogListener());
|
Logger.Listeners.Add(new ConsoleLogListener());
|
||||||
|
|
||||||
ConsoleManager.Initialize(true);
|
ConsoleManager.Initialize(true, false);
|
||||||
|
|
||||||
NetPreloader.Start(args);
|
NetPreloader.Start(args);
|
||||||
}
|
}
|
||||||
@@ -148,3 +148,62 @@ internal class Program
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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;
|
||||||
|
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var potentialDirectories = new List<string> { directory };
|
||||||
|
|
||||||
|
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
||||||
|
|
||||||
|
foreach (var subDirectory in potentialDirectories)
|
||||||
|
{
|
||||||
|
var 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) =>
|
||||||
|
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
||||||
|
}
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
if (!Directory.Exists(directory))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var potentialDirectories = new List<string> { directory };
|
|
||||||
|
|
||||||
potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
|
|
||||||
|
|
||||||
foreach (var subDirectory in potentialDirectories)
|
|
||||||
{
|
|
||||||
var 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) =>
|
|
||||||
TryResolveDllAssembly(assemblyName, directory, Assembly.LoadFile, out assembly);
|
|
||||||
}
|
|
||||||
@@ -6,43 +6,66 @@ namespace BepInEx.Preloader.Core
|
|||||||
{
|
{
|
||||||
public class AssemblyBuildInfo
|
public class AssemblyBuildInfo
|
||||||
{
|
{
|
||||||
|
public enum FrameworkType
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
NetFramework,
|
||||||
|
NetStandard,
|
||||||
|
NetCore
|
||||||
|
}
|
||||||
|
|
||||||
public Version NetFrameworkVersion { get; private set; }
|
public Version NetFrameworkVersion { get; private set; }
|
||||||
|
|
||||||
public bool IsAnyCpu { get; set; }
|
public bool IsAnyCpu { get; set; }
|
||||||
|
|
||||||
public bool Is64Bit { get; set; }
|
public bool Is64Bit { get; set; }
|
||||||
|
|
||||||
private static Version GetNet4Version(AssemblyDefinition assemblyDefinition)
|
public FrameworkType AssemblyFrameworkType { get; set; }
|
||||||
|
|
||||||
|
private void SetNet4Version(AssemblyDefinition assemblyDefinition)
|
||||||
{
|
{
|
||||||
|
NetFrameworkVersion = new Version(0, 0);
|
||||||
|
AssemblyFrameworkType = FrameworkType.Unknown;
|
||||||
|
|
||||||
var targetFrameworkAttribute = assemblyDefinition.CustomAttributes.FirstOrDefault(x =>
|
var targetFrameworkAttribute = assemblyDefinition.CustomAttributes.FirstOrDefault(x =>
|
||||||
x.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute");
|
x.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute");
|
||||||
|
|
||||||
if (targetFrameworkAttribute == null)
|
if (targetFrameworkAttribute == null)
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
if (targetFrameworkAttribute.ConstructorArguments.Count < 1)
|
if (targetFrameworkAttribute.ConstructorArguments.Count < 1)
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
if (targetFrameworkAttribute.ConstructorArguments[0].Type.Name != "String")
|
if (targetFrameworkAttribute.ConstructorArguments[0].Type.Name != "String")
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
string versionInfo = (string)targetFrameworkAttribute.ConstructorArguments[0].Value;
|
string versionInfo = (string)targetFrameworkAttribute.ConstructorArguments[0].Value;
|
||||||
|
|
||||||
var values = versionInfo.Split(',');
|
var values = versionInfo.Split(',');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var value in values)
|
foreach (var value in values)
|
||||||
{
|
{
|
||||||
if (!value.StartsWith("Version=v"))
|
if (value.StartsWith(".NET"))
|
||||||
continue;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
return new Version(value.Substring("Version=v".Length));
|
AssemblyFrameworkType = value switch
|
||||||
|
{
|
||||||
|
".NETFramework" => FrameworkType.NetFramework,
|
||||||
|
".NETCoreApp" => FrameworkType.NetCore,
|
||||||
|
".NETStandard" => FrameworkType.NetStandard,
|
||||||
|
_ => FrameworkType.Unknown
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (value.StartsWith("Version=v"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NetFrameworkVersion = new Version(value.Substring("Version=v".Length));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
catch {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AssemblyBuildInfo DetermineInfo(AssemblyDefinition assemblyDefinition)
|
public static AssemblyBuildInfo DetermineInfo(AssemblyDefinition assemblyDefinition)
|
||||||
@@ -56,20 +79,23 @@ namespace BepInEx.Preloader.Core
|
|||||||
if (runtime == TargetRuntime.Net_1_0)
|
if (runtime == TargetRuntime.Net_1_0)
|
||||||
{
|
{
|
||||||
buildInfo.NetFrameworkVersion = new Version(1, 0);
|
buildInfo.NetFrameworkVersion = new Version(1, 0);
|
||||||
|
buildInfo.AssemblyFrameworkType = FrameworkType.NetFramework;
|
||||||
}
|
}
|
||||||
else if (runtime == TargetRuntime.Net_1_1)
|
else if (runtime == TargetRuntime.Net_1_1)
|
||||||
{
|
{
|
||||||
buildInfo.NetFrameworkVersion = new Version(1, 1);
|
buildInfo.NetFrameworkVersion = new Version(1, 1);
|
||||||
|
buildInfo.AssemblyFrameworkType = FrameworkType.NetFramework;
|
||||||
}
|
}
|
||||||
else if (runtime == TargetRuntime.Net_2_0)
|
else if (runtime == TargetRuntime.Net_2_0)
|
||||||
{
|
{
|
||||||
// Assume 3.5 here. The code to determine versions between 2.0 and 3.5 is not worth the amount of non-unity games that use it, if any
|
// Assume 3.5 here. The code to determine versions between 2.0 and 3.5 is not worth the amount of non-unity games that use it, if any
|
||||||
|
|
||||||
buildInfo.NetFrameworkVersion = new Version(3, 5);
|
buildInfo.NetFrameworkVersion = new Version(3, 5);
|
||||||
|
buildInfo.AssemblyFrameworkType = FrameworkType.NetFramework;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buildInfo.NetFrameworkVersion = GetNet4Version(assemblyDefinition) ?? new Version(4, 0);
|
buildInfo.SetNet4Version(assemblyDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bitness
|
// bitness
|
||||||
@@ -131,12 +157,20 @@ namespace BepInEx.Preloader.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
string frameworkType = AssemblyFrameworkType switch {
|
||||||
|
FrameworkType.NetFramework => "Framework",
|
||||||
|
FrameworkType.NetStandard => "Standard",
|
||||||
|
FrameworkType.NetCore => "Core",
|
||||||
|
FrameworkType.Unknown => "Unknown",
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
if (IsAnyCpu)
|
if (IsAnyCpu)
|
||||||
{
|
{
|
||||||
return $".NET Framework {NetFrameworkVersion}, AnyCPU ({(Is64Bit ? "64" : "32")}-bit preferred)";
|
return $".NET {frameworkType} {NetFrameworkVersion}, AnyCPU ({(Is64Bit ? "64" : "32")}-bit preferred)";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $".NET Framework {NetFrameworkVersion}, {(Is64Bit ? "x64" : "x86")}";
|
return $".NET {frameworkType} {NetFrameworkVersion}, {(Is64Bit ? "x64" : "x86")}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("BepInEx.Preloader.Unity")]
|
[assembly: InternalsVisibleTo("BepInEx.Preloader.Unity")]
|
||||||
[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
|
[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
|
||||||
|
[assembly: InternalsVisibleTo("BepInEx.NetCore")]
|
||||||
[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
|
[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
|
||||||
@@ -43,7 +43,7 @@ internal static class UnityPreloader
|
|||||||
{
|
{
|
||||||
HarmonyBackendFix.Initialize();
|
HarmonyBackendFix.Initialize();
|
||||||
|
|
||||||
ConsoleManager.Initialize(false);
|
ConsoleManager.Initialize(false, true);
|
||||||
AllocateConsole();
|
AllocateConsole();
|
||||||
|
|
||||||
Utility.TryDo(() =>
|
Utility.TryDo(() =>
|
||||||
|
|||||||
+26
-6
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.28922.388
|
VisualStudioVersion = 17.0.32112.339
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInExTests", "BepInExTests\BepInExTests.csproj", "{E7CD429A-D057-48E3-8C51-E5C934E8E07B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInExTests", "BepInExTests\BepInExTests.csproj", "{E7CD429A-D057-48E3-8C51-E5C934E8E07B}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
@@ -26,23 +26,25 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IL2CPP", "IL2CPP", "{D5F47C
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInEx.IL2CPP", "BepInEx.IL2CPP\BepInEx.IL2CPP.csproj", "{429D5F83-7FEC-4D09-AB82-E868EB61AF59}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInEx.IL2CPP", "BepInEx.IL2CPP\BepInEx.IL2CPP.csproj", "{429D5F83-7FEC-4D09-AB82-E868EB61AF59}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assets", "Assets", "{68C57430-3E92-4B50-A9A5-208FE9CCD914}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Markdown", "Markdown", "{68C57430-3E92-4B50-A9A5-208FE9CCD914}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
build.cake = build.cake
|
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BepInEx.Shared", "BepInEx.Shared\BepInEx.Shared.shproj", "{5C7847FB-C16D-47BD-BB17-1045669F9AA7}"
|
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BepInEx.Shared", "BepInEx.Shared\BepInEx.Shared.shproj", "{5C7847FB-C16D-47BD-BB17-1045669F9AA7}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BepInEx.NetLauncher.Common", "BepInEx.NetLauncher.Common\BepInEx.NetLauncher.Common.csproj", "{76EB1952-7826-471C-9CF3-815D094DA077}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.NetCore", "BepInEx.NetCore\BepInEx.NetCore.csproj", "{08083F40-98AA-4176-BA01-817C18C35C7F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||||
|
BepInEx.Shared\BepInEx.Shared.projitems*{15f8bc38-a761-4f93-8903-1b531ac5d9f9}*SharedItemsImports = 5
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{429d5f83-7fec-4d09-ab82-e868eb61af59}*SharedItemsImports = 5
|
BepInEx.Shared\BepInEx.Shared.projitems*{429d5f83-7fec-4d09-ab82-e868eb61af59}*SharedItemsImports = 5
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{490b052b-7f23-4052-ad04-613856618901}*SharedItemsImports = 5
|
BepInEx.Shared\BepInEx.Shared.projitems*{490b052b-7f23-4052-ad04-613856618901}*SharedItemsImports = 5
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{4ffba620-f5ed-47f9-b90c-dad1316fd9b9}*SharedItemsImports = 5
|
BepInEx.Shared\BepInEx.Shared.projitems*{4ffba620-f5ed-47f9-b90c-dad1316fd9b9}*SharedItemsImports = 5
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{5c7847fb-c16d-47bd-bb17-1045669f9aa7}*SharedItemsImports = 13
|
BepInEx.Shared\BepInEx.Shared.projitems*{5c7847fb-c16d-47bd-bb17-1045669f9aa7}*SharedItemsImports = 13
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{6e6bc1e5-5be8-4566-b3ae-52c4cb218aeb}*SharedItemsImports = 5
|
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{d404c973-441d-48ed-b266-c21320ba0d87}*SharedItemsImports = 5
|
BepInEx.Shared\BepInEx.Shared.projitems*{d404c973-441d-48ed-b266-c21320ba0d87}*SharedItemsImports = 5
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{dc89f18b-235b-4c01-ab31-af40dce5c4c7}*SharedItemsImports = 5
|
|
||||||
BepInEx.Shared\BepInEx.Shared.projitems*{eae9fae6-8011-45a3-8b6e-0c7f14210533}*SharedItemsImports = 5
|
BepInEx.Shared\BepInEx.Shared.projitems*{eae9fae6-8011-45a3-8b6e-0c7f14210533}*SharedItemsImports = 5
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -102,6 +104,22 @@ Global
|
|||||||
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.Build.0 = Release|Any CPU
|
{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -111,6 +129,8 @@ Global
|
|||||||
{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}
|
{490B052B-7F23-4052-AD04-613856618901} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||||
{429D5F83-7FEC-4D09-AB82-E868EB61AF59} = {D5F47CFC-E4F3-46EE-B4F3-2474CF7D9E2C}
|
{429D5F83-7FEC-4D09-AB82-E868EB61AF59} = {D5F47CFC-E4F3-46EE-B4F3-2474CF7D9E2C}
|
||||||
|
{76EB1952-7826-471C-9CF3-815D094DA077} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
|
||||||
|
{08083F40-98AA-4176-BA01-817C18C35C7F} = {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