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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Newtonsoft.Json;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Kesomannen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Preload patcher for ComponentBundler.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+53f977741280d51e7853900d4d33ad3755f3ef2f")]
[assembly: AssemblyProduct("ComponentBundler")]
[assembly: AssemblyTitle("ComponentBundler.Preloader")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ComponentBundler.Preloader
{
public static class ComponentBundlingPreloader
{
internal static readonly ManualLogSource Logger = Logger.CreateLogSource("ComponentBundler.Preloader");
internal static readonly Dictionary<string, List<string>> BundledComponents = new Dictionary<string, List<string>>();
public static IReadOnlyCollection<string> TargettedComponentFullNames => BundledComponents.Keys;
public static bool Bundle(AssemblyDefinition targetAssembly, string targetFullName, string toAddFullName)
{
if (BundledComponents.TryGetValue(targetFullName, out var value))
{
value.Add(toAddFullName);
Logger.LogInfo((object)("Bundled " + toAddFullName + " with " + targetFullName));
return true;
}
MethodGenerator.CreateMethod(targetAssembly, targetFullName, "Awake");
BundledComponents.Add(targetFullName, new List<string> { toAddFullName });
Logger.LogInfo((object)("Bundled " + toAddFullName + " with " + targetFullName));
return true;
}
public static IEnumerable<string> GetBundle(string targetComponentFullName)
{
if (!BundledComponents.TryGetValue(targetComponentFullName, out var value))
{
return Enumerable.Empty<string>();
}
return value;
}
public static bool TryGetBundle(string targetComponentFullName, out IEnumerable<string> bundle)
{
if (BundledComponents.TryGetValue(targetComponentFullName, out var value))
{
bundle = value;
return true;
}
bundle = Enumerable.Empty<string>();
return false;
}
}
public static class MethodGenerator
{
internal static readonly ManualLogSource Logger = Logger.CreateLogSource("ComponentBundler.MethodGenerator");
public static bool CreateMethod(AssemblyDefinition assembly, string classFullName, string methodName)
{
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Expected O, but got Unknown
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
TypeDefinition type = assembly.MainModule.GetType(classFullName);
if (type == null)
{
string text = "Target type " + classFullName + " not found in " + ((AssemblyNameReference)assembly.Name).Name + "!";
if (!classFullName.Contains('.'))
{
text += " Did you forget to include the namespace?";
}
Logger.LogError((object)text);
return false;
}
if (((IEnumerable<MethodDefinition>)type.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == methodName))
{
return true;
}
MethodDefinition val = null;
TypeReference baseType = type.BaseType;
while (baseType != null)
{
TypeDefinition val2 = baseType.Resolve();
if (val2 == null)
{
Logger.LogError((object)("Failed to resolve base type " + ((MemberReference)baseType).FullName));
return false;
}
val = ((IEnumerable<MethodDefinition>)val2.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == methodName));
if (val != null)
{
break;
}
baseType = val2.BaseType;
}
MethodDefinition val3 = new MethodDefinition(methodName, (MethodAttributes)1, assembly.MainModule.TypeSystem.Void);
ILProcessor iLProcessor = val3.Body.GetILProcessor();
if (val != null)
{
iLProcessor.Emit(OpCodes.Ldarg_0);
iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
Logger.LogInfo((object)("Added call to base method " + ((MemberReference)val).Name + " in " + classFullName + "." + methodName));
}
iLProcessor.Emit(OpCodes.Ret);
type.Methods.Add(val3);
Logger.LogInfo((object)("Added " + methodName + " to " + classFullName));
return true;
}
}
public static class Patcher
{
public static IEnumerable<string> TargetDLLs
{
get
{
yield return "Assembly-CSharp.dll";
}
}
public static void Patch(AssemblyDefinition assembly)
{
string? directoryName = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
RecursiveSearch(directoryName, "bundler_config", delegate(Dictionary<string, string[]> file)
{
foreach (KeyValuePair<string, string[]> item in file)
{
item.Deconstruct(out var key2, out var value2);
string targetFullName = key2;
value2 = value2;
foreach (string toAddFullName in value2)
{
ComponentBundlingPreloader.Bundle(assembly, targetFullName, toAddFullName);
}
}
});
RecursiveSearch(directoryName, "method_gen_config", delegate(Dictionary<string, string[]> file)
{
foreach (KeyValuePair<string, string[]> item2 in file)
{
item2.Deconstruct(out var key, out var value);
string classFullName = key;
value = value;
foreach (string methodName in value)
{
MethodGenerator.CreateMethod(assembly, classFullName, methodName);
}
}
});
}
private static void RecursiveSearch<T>(string pluginDirectory, string fileName, Action<T> action)
{
//IL_0028: Expected O, but got Unknown
string[] files = Directory.GetFiles(pluginDirectory, fileName, SearchOption.AllDirectories);
foreach (string text in files)
{
try
{
string text2 = File.ReadAllText(text);
action(JsonConvert.DeserializeObject<T>(text2));
}
catch (JsonException val)
{
JsonException val2 = val;
ComponentBundlingPreloader.Logger.LogError((object)("Failed to read config file " + text + ": " + ((Exception)(object)val2).Message));
}
}
}
}
}