diff --git a/Doorstop b/Doorstop
index 02647aa4..bcab2ee0 160000
--- a/Doorstop
+++ b/Doorstop
@@ -1 +1 @@
-Subproject commit 02647aa40bdde4e5027eb596082a6787497b92e9
+Subproject commit bcab2ee05684ad679aa926b4414600f3892657f0
diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs
index f0316662..22ff4fab 100644
--- a/IPA.Injector/Injector.cs
+++ b/IPA.Injector/Injector.cs
@@ -16,6 +16,7 @@ using MethodAttributes = Mono.Cecil.MethodAttributes;
#if NET3
using Net3_Proxy;
using Path = Net3_Proxy.Path;
+using File = Net3_Proxy.File;
using Directory = Net3_Proxy.Directory;
#endif
@@ -29,6 +30,7 @@ namespace IPA.Injector
{
private static Task pluginAsyncLoadTask;
private static Task permissionFixTask;
+ private static string otherNewtonsoftJson = null;
// ReSharper disable once UnusedParameter.Global
internal static void Main(string[] args)
@@ -45,6 +47,16 @@ namespace IPA.Injector
SetupLibraryLoading();
+ var otherNewtonsoft = Path.Combine(
+ Directory.EnumerateDirectories(Environment.CurrentDirectory, "*_Data").First(),
+ "Managed",
+ "Newtonsoft.Json.dll");
+ if (File.Exists(otherNewtonsoft))
+ { // this game ships its own Newtonsoft; force load ours and flag loading theirs
+ LibLoader.LoadLibrary(new AssemblyName("Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"));
+ otherNewtonsoftJson = otherNewtonsoft;
+ }
+
EnsureDirectories();
// this is weird, but it prevents Mono from having issues loading the type.
@@ -259,6 +271,9 @@ namespace IPA.Injector
if (bootstrapped) return;
bootstrapped = true;
+ if (otherNewtonsoftJson != null)
+ Assembly.LoadFrom(otherNewtonsoftJson);
+
Application.logMessageReceived += delegate (string condition, string stackTrace, LogType type)
{
var level = UnityLogRedirector.LogTypeToLevel(type);
diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs
index ce588cf0..98dbe8aa 100644
--- a/IPA.Loader/Config/SelfConfig.cs
+++ b/IPA.Loader/Config/SelfConfig.cs
@@ -51,7 +51,6 @@ namespace IPA.Config
public bool AutoCheckUpdates = true;
}
- [JsonProperty(Required = Required.Always)]
public UpdateObject Updates = new UpdateObject();
public class DebugObject
@@ -63,7 +62,6 @@ namespace IPA.Config
public int HideLogThreshold = 512;
}
- [JsonProperty(Required = Required.Always)]
public DebugObject Debug = new DebugObject();
[JsonProperty(Required = Required.Default)]
diff --git a/IPA.Loader/Loader/LibLoader.cs b/IPA.Loader/Loader/LibLoader.cs
index 5ab7588e..dab45cff 100644
--- a/IPA.Loader/Loader/LibLoader.cs
+++ b/IPA.Loader/Loader/LibLoader.cs
@@ -49,6 +49,11 @@ namespace IPA.Loader
public static Assembly AssemblyLibLoader(object source, ResolveEventArgs e)
{
var asmName = new AssemblyName(e.Name);
+ return LoadLibrary(asmName);
+ }
+
+ internal static Assembly LoadLibrary(AssemblyName asmName)
+ {
Log(Logger.Level.Debug, $"Resolving library {asmName}");
SetupAssemblyFilenames();
diff --git a/IPA.Loader/Logging/ConsoleWindow.cs b/IPA.Loader/Logging/ConsoleWindow.cs
index a9cf9469..0d8c9a7e 100644
--- a/IPA.Loader/Logging/ConsoleWindow.cs
+++ b/IPA.Loader/Logging/ConsoleWindow.cs
@@ -91,7 +91,14 @@ namespace IPA.Logging
if (!file.IsInvalid)
{
handle = file;
+#if NET4
var fs = new FileStream(file, dotNetFileAccess);
+#elif NET3
+#pragma warning disable CS0618
+ // this is marked obsolete, and shouldn't need to be used, but the constructor used in .NET 4 doesn't exist in Unity's mscorlib.dll
+ var fs = new FileStream(file.DangerousGetHandle(), dotNetFileAccess);
+#pragma warning restore
+#endif
return fs;
}
@@ -99,7 +106,7 @@ namespace IPA.Logging
return null;
}
- #region Win API Functions and Constants
+#region Win API Functions and Constants
[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
@@ -150,6 +157,6 @@ namespace IPA.Logging
private const uint AttachParent = 0xFFFFFFFF;
- #endregion
+#endregion
}
}
\ No newline at end of file
diff --git a/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs b/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
index 338940eb..7d4d5b3b 100644
--- a/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
+++ b/IPA.Loader/Logging/Printers/ColoredConsolePrinter.cs
@@ -19,7 +19,9 @@ namespace IPA.Logging.Printers
/// The color to print messages as.
///
/// the color to print this message as
- public ConsoleColor Color { get; set; } = Console.ForegroundColor;
+ // Initializer calls this function because Unity's .NET 3.5 doesn't have the color properties on Console
+ // TODO: move this garbo out to Net3_Proxy
+ public ConsoleColor Color { get; set; } = GetConsoleColor(WinConsole.OutHandle);
///
/// Prints an entry to the console window.
@@ -71,6 +73,12 @@ namespace IPA.Logging.Printers
return (short)(attr | (int)color);
}
+ private static ConsoleColor GetConsoleColor(IntPtr handle)
+ {
+ GetConsoleScreenBufferInfo(handle, out var info);
+ return (ConsoleColor)(info.Attribute & 15);
+ }
+
// ReSharper disable NotAccessedField.Local
#pragma warning disable 649
diff --git a/IPA.Loader/Logging/Printers/GZFilePrinter.cs b/IPA.Loader/Logging/Printers/GZFilePrinter.cs
index 64968295..58d50053 100644
--- a/IPA.Loader/Logging/Printers/GZFilePrinter.cs
+++ b/IPA.Loader/Logging/Printers/GZFilePrinter.cs
@@ -23,7 +23,13 @@ namespace IPA.Logging.Printers
IntPtr lpSecurityAttributes
);
- internal static Regex removeControlCodes = new Regex("\x1b\\[\\d+m", RegexOptions.Compiled);
+#if NET4
+ private const RegexOptions reOptions = RegexOptions.Compiled;
+#elif NET3 // Needed because Compiled doesn't exist in Unity's .NET 3 runtime
+ private const RegexOptions reOptions = RegexOptions.None;
+#endif
+
+ internal static Regex removeControlCodes = new Regex("\x1b\\[\\d+m", reOptions);
private FileInfo fileInfo;
diff --git a/IPA.Loader/Logging/StdoutInterceptor.cs b/IPA.Loader/Logging/StdoutInterceptor.cs
index 5ef6aa71..495815b8 100644
--- a/IPA.Loader/Logging/StdoutInterceptor.cs
+++ b/IPA.Loader/Logging/StdoutInterceptor.cs
@@ -121,12 +121,16 @@ namespace IPA.Logging
var console = typeof(Console);
var resetColor = console.GetMethod("ResetColor");
var foregroundProperty = console.GetProperty("ForegroundColor");
- var setFg = foregroundProperty.GetSetMethod();
- var getFg = foregroundProperty.GetGetMethod();
+ var setFg = foregroundProperty?.GetSetMethod();
+ var getFg = foregroundProperty?.GetGetMethod();
- harmony.Patch(resetColor, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchResetColor"));
- harmony.Patch(setFg, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchSetForegroundColor"));
- harmony.Patch(getFg, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchGetForegroundColor"));
+ if (resetColor != null)
+ harmony.Patch(resetColor, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchResetColor"));
+ if (foregroundProperty != null)
+ {
+ harmony.Patch(setFg, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchSetForegroundColor"));
+ harmony.Patch(getFg, transpiler: new HarmonyMethod(typeof(ConsoleHarmonyPatches), "PatchGetForegroundColor"));
+ }
}
public static ConsoleColor GetColor() => stdoutInterceptor.currentColor;
diff --git a/docs/build.ps1 b/docs/build.ps1
index 389ab67e..5a87c729 100644
--- a/docs/build.ps1
+++ b/docs/build.ps1
@@ -55,6 +55,7 @@ if ((Test-Path $newtonsoftLoc -PathType Leaf) -and (Test-Path $selfConfigLoc -Pa
# Generate schema
$schemagen = New-Object -TypeName Newtonsoft.Json.Schema.Generation.JSchemaGenerator
+ $schemagen.DefaultRequired = [Newtonsoft.Json.Required]::Always
$schema = $schemagen.Generate([IPA.Config.SelfConfig])
$schema.ToString() | Out-File "other_api/config/_schema.json"