using System; using System.Collections; 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 BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; using Mono.Collections.Generic; [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("SADmodelfixpatcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SADmodelfixpatcher")] [assembly: AssemblyTitle("SADmodelfixpatcher")] [assembly: AssemblyVersion("1.0.0.0")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 SillyValuablesCompatPatcher { public static class Patcher { [CompilerGenerated] private sealed class d__9 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private TypeDefinition <>2__current; private int <>l__initialThreadId; private TypeDefinition t; public TypeDefinition <>3__t; private Enumerator <>7__wrap1; private IEnumerator <>7__wrap2; TypeDefinition IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if ((uint)(num - -4) <= 1u || num == 2) { try { if (num == -4 || num == 2) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>7__wrap1 = default(Enumerator); <>7__wrap2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = t; <>1__state = 1; return true; case 1: <>1__state = -1; <>7__wrap1 = t.NestedTypes.GetEnumerator(); <>1__state = -3; goto IL_00cf; case 2: { <>1__state = -4; goto IL_00b5; } IL_00cf: if (<>7__wrap1.MoveNext()) { TypeDefinition current = <>7__wrap1.Current; <>7__wrap2 = AllTypes(current).GetEnumerator(); <>1__state = -4; goto IL_00b5; } <>m__Finally1(); <>7__wrap1 = default(Enumerator); return false; IL_00b5: if (<>7__wrap2.MoveNext()) { TypeDefinition current2 = <>7__wrap2.Current; <>2__current = current2; <>1__state = 2; return true; } <>m__Finally2(); <>7__wrap2 = null; goto IL_00cf; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } private void <>m__Finally2() { <>1__state = -3; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__9 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__9(0); } d__.t = <>3__t; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static ManualLogSource? _log; private static ManualLogSource Log => _log ?? (_log = Logger.CreateLogSource("SAD Model Fix")); public static IEnumerable TargetDLLs { get; } = Array.Empty(); public static void Patch(AssemblyDefinition _) { } public static void Initialize() { try { Run(); } catch (Exception arg) { Log.LogError((object)$"[SillyValuables compat] Failed: {arg}"); } } private static void Run() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Invalid comparison between Unknown and I4 //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Invalid comparison between Unknown and I4 //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Invalid comparison between Unknown and I4 //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Invalid comparison between Unknown and I4 string text = Directory.GetFiles(Path.Combine(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(Patcher).Assembly.Location) ?? AppDomain.CurrentDomain.BaseDirectory, "..", "..")), "plugins"), "SillyValuables.dll", SearchOption.AllDirectories).FirstOrDefault(); if (text == null) { Log.LogInfo((object)"[SillyValuables compat] SillyValuables.dll not found — nothing to do."); return; } string managedPath = Paths.ManagedPath; string text2 = Path.Combine(managedPath, "Assembly-CSharp.dll"); if (!File.Exists(text2)) { Log.LogWarning((object)("[SillyValuables compat] Assembly-CSharp.dll not found at " + text2)); return; } byte[] buffer = File.ReadAllBytes(text); DefaultAssemblyResolver val = new DefaultAssemblyResolver(); ((BaseAssemblyResolver)val).AddSearchDirectory(managedPath); ((BaseAssemblyResolver)val).AddSearchDirectory(Path.GetDirectoryName(text)); ModuleDefinition val2 = ModuleDefinition.ReadModule((Stream)new MemoryStream(buffer), new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val }); try { List<(MethodDefinition, Instruction)> list = new List<(MethodDefinition, Instruction)>(); foreach (TypeDefinition item in ((IEnumerable)val2.Types).SelectMany(AllTypes)) { Enumerator enumerator2 = item.Methods.GetEnumerator(); try { while (enumerator2.MoveNext()) { MethodDefinition current = enumerator2.Current; if (!current.HasBody) { continue; } Enumerator enumerator3 = current.Body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current2 = enumerator3.Current; OpCode opCode = current2.OpCode; if ((int)((OpCode)(ref opCode)).Code != 110) { opCode = current2.OpCode; if ((int)((OpCode)(ref opCode)).Code != 39) { continue; } } object operand = current2.Operand; MethodReference val3 = (MethodReference)((operand is MethodReference) ? operand : null); if (val3 != null && ((MemberReference)((MemberReference)val3).DeclaringType).Name == "Sound" && ((MemberReference)val3).Name == "PlayLoop" && val3.Parameters.Count == 4 && (int)((ParameterReference)val3.Parameters[0]).ParameterType.MetadataType == 2 && (int)((ParameterReference)val3.Parameters[1]).ParameterType.MetadataType == 12) { list.Add((current, current2)); } } } finally { ((IDisposable)enumerator3).Dispose(); } } } finally { ((IDisposable)enumerator2).Dispose(); } } if (list.Count == 0) { Log.LogInfo((object)"[SillyValuables compat] No Sound.PlayLoop(4) calls found — already patched or version changed."); return; } ModuleDefinition val4 = ModuleDefinition.ReadModule(text2, new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val }); try { TypeDefinition type = val4.GetType("Sound"); if (type == null) { Log.LogWarning((object)"[SillyValuables compat] Sound type not found in Assembly-CSharp."); return; } MethodDefinition val5 = ((IEnumerable)type.Methods).FirstOrDefault((Func)((MethodDefinition m) => ((MemberReference)m).Name == "PlayLoop" && ((MethodReference)m).Parameters.Count == 5 && (int)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType.MetadataType == 2 && (int)((ParameterReference)((MethodReference)m).Parameters[4]).ParameterType.MetadataType == 12)); if (val5 == null) { Log.LogWarning((object)"[SillyValuables compat] Sound.PlayLoop(bool,float,float,float,float) not found in Assembly-CSharp."); return; } MethodReference operand2 = val2.ImportReference((MethodReference)(object)val5); foreach (var (val6, val7) in list) { MethodBodyRocks.SimplifyMacros(val6.Body); ILProcessor iLProcessor = val6.Body.GetILProcessor(); Instruction val8 = iLProcessor.Create(OpCodes.Ldc_R4, 1f); iLProcessor.InsertBefore(val7, val8); val7.Operand = operand2; MethodBodyRocks.OptimizeMacros(val6.Body); } using MemoryStream memoryStream = new MemoryStream(); val2.Write((Stream)memoryStream); File.WriteAllBytes(text, memoryStream.ToArray()); Log.LogInfo((object)$"[SillyValuables compat] Patched {list.Count} Sound.PlayLoop(4) call(s) in SillyValuables.dll. Sounds will work correctly."); } finally { ((IDisposable)val4)?.Dispose(); } } finally { ((IDisposable)val2)?.Dispose(); } } [IteratorStateMachine(typeof(d__9))] private static IEnumerable AllTypes(TypeDefinition t) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(-2) { <>3__t = t }; } } }