Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of GoosCombatOverhaul v2.3.0
BepInEx/patchers/GooCombatOverhaul/GooCombatOverhaul.SdwCompatibilityPatcher.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("GooCombatOverhaul.SdwCompatibilityPatcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.3.0.0")] [assembly: AssemblyInformationalVersion("2.3.0")] [assembly: AssemblyProduct("GooCombatOverhaul.SdwCompatibilityPatcher")] [assembly: AssemblyTitle("GooCombatOverhaul.SdwCompatibilityPatcher")] [assembly: AssemblyVersion("2.3.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace GooCombatOverhaul.SdwCompatibilityPatcher { internal enum BroadcastFieldRepair { Unsupported, AlreadyCompatible, Restored } internal static class BroadcastFieldCompatibility { internal static BroadcastFieldRepair Restore(AssemblyDefinition assembly) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (((AssemblyNameReference)assembly.Name).Name != "assembly_valheim") { return BroadcastFieldRepair.Unsupported; } TypeDefinition type = assembly.MainModule.GetType("ZRoutedRpc"); if (type == null || ((MemberReference)type).FullName != "ZRoutedRpc") { return BroadcastFieldRepair.Unsupported; } FieldDefinition val = null; Enumerator<FieldDefinition> enumerator = type.Fields.GetEnumerator(); try { while (enumerator.MoveNext()) { FieldDefinition current = enumerator.Current; if (!(((MemberReference)current).Name != "Everybody")) { if (val != null) { return BroadcastFieldRepair.Unsupported; } val = current; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (val == null || !val.IsPublic || !val.IsStatic || (int)((FieldReference)val).FieldType.MetadataType != 10) { return BroadcastFieldRepair.Unsupported; } if (!val.IsLiteral) { return BroadcastFieldRepair.AlreadyCompatible; } if (!val.HasConstant || !(val.Constant is long num) || num != 0L) { return BroadcastFieldRepair.Unsupported; } val.Attributes = (FieldAttributes)((val.Attributes & 0x7FBF) | 0x10 | 0x20); val.HasConstant = false; return BroadcastFieldRepair.Restored; } } public static class Patcher { private static string[]? _targetDlls; public static IEnumerable<string> TargetDLLs => _targetDlls ?? (_targetDlls = ((!SdwPluginPresence.IsInstalled(Paths.PluginPath)) ? Array.Empty<string>() : new string[1] { "assembly_valheim.dll" })); public static void Patch(AssemblyDefinition assembly) { try { PatchAndReport(assembly); } catch (Exception) { } } private static void PatchAndReport(AssemblyDefinition assembly) { ManualLogSource val = Logger.CreateLogSource("GCO SDW API Compatibility"); try { BroadcastFieldRepair broadcastFieldRepair; try { broadcastFieldRepair = BroadcastFieldCompatibility.Restore(assembly); } catch (Exception ex) { val.LogWarning((object)("Could not inspect ZRoutedRpc.Everybody; no field was changed and SDW ServerSync compatibility was not prepared. " + ex.Message)); return; } switch (broadcastFieldRepair) { case BroadcastFieldRepair.Restored: val.LogInfo((object)"Prepared the in-memory ZRoutedRpc.Everybody compatibility field for SDW. Broadcast target remains 0; GCO will verify the loaded field at startup."); break; case BroadcastFieldRepair.AlreadyCompatible: val.LogInfo((object)"ZRoutedRpc.Everybody already supports legacy static-field reads; no compatibility change required."); break; default: val.LogWarning((object)"Unsupported ZRoutedRpc.Everybody declaration. No field was changed; SDW ServerSync compatibility could not be prepared for this game build."); break; } } finally { ((IDisposable)val)?.Dispose(); } } } internal static class SdwPluginPresence { private const string SdwGuid = "org.bepinex.plugins.dualwield"; private const int MaxNamedFiles = 10; internal static bool IsInstalled(string? pluginDirectory) { List<string> list = new List<string>(); bool flag = false; try { flag = !string.IsNullOrEmpty(pluginDirectory) && Directory.Exists(pluginDirectory) && ScanDirectory(pluginDirectory, list); } catch (Exception) { } if (!flag && list.Count > 0) { WarnUnreadable(list); } return flag; } private static bool ScanDirectory(string directory, List<string> unreadable) { string fileName = Path.GetFileName(directory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); bool flag = true; string[] array; try { array = Directory.GetFiles(directory, "*.dll", SearchOption.TopDirectoryOnly); } catch (Exception) { array = new string[0]; flag = false; unreadable.Add(fileName + " (folder)"); } string[] array2 = array; for (int i = 0; i < array2.Length; i++) { if (DeclaresSdw(array2[i], unreadable)) { return true; } } string[] directories; try { directories = Directory.GetDirectories(directory); } catch (Exception) { if (flag) { unreadable.Add(fileName + " (subfolders)"); } return false; } array2 = directories; for (int i = 0; i < array2.Length; i++) { if (ScanDirectory(array2[i], unreadable)) { return true; } } return false; } private static bool DeclaresSdw(string path, List<string> unreadable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) try { AssemblyDefinition val = AssemblyDefinition.ReadAssembly(path, new ReaderParameters { ReadingMode = (ReadingMode)2, ReadSymbols = false }); try { Enumerator<TypeDefinition> enumerator = val.MainModule.Types.GetEnumerator(); try { while (enumerator.MoveNext()) { Enumerator<CustomAttribute> enumerator2 = enumerator.Current.CustomAttributes.GetEnumerator(); try { while (enumerator2.MoveNext()) { CustomAttribute current = enumerator2.Current; TypeReference attributeType = current.AttributeType; if (((attributeType != null) ? ((MemberReference)attributeType).FullName : null) == "BepInEx.BepInPlugin" && current.ConstructorArguments.Count == 3) { CustomAttributeArgument val2 = current.ConstructorArguments[0]; if (((CustomAttributeArgument)(ref val2)).Value is string a && string.Equals(a, "org.bepinex.plugins.dualwield", StringComparison.Ordinal)) { return true; } } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } catch (BadImageFormatException) { if (HasCliHeader(path)) { unreadable.Add(Path.GetFileName(path)); } } catch (Exception) { unreadable.Add(Path.GetFileName(path)); } return false; } private static bool HasCliHeader(string path) { try { byte[] array = new byte[4096]; int num; using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { num = fileStream.Read(array, 0, array.Length); } if (num < 64 || array[0] != 77 || array[1] != 90) { return false; } int num2 = BitConverter.ToInt32(array, 60); if (num2 < 0 || num2 + 24 > num || array[num2] != 80 || array[num2 + 1] != 69 || array[num2 + 2] != 0 || array[num2 + 3] != 0) { return false; } int num3 = num2 + 24; if (num3 + 2 > num) { return false; } int num4 = BitConverter.ToUInt16(array, num3) switch { 523 => num3 + 112, 267 => num3 + 96, _ => -1, }; int num5 = num4 + 112; if (num4 < 0 || num5 + 8 > num || BitConverter.ToUInt32(array, num4 - 4) < 15) { return false; } return BitConverter.ToUInt32(array, num5) != 0 && BitConverter.ToUInt32(array, num5 + 4) != 0; } catch (Exception) { return false; } } private static void WarnUnreadable(List<string> unreadable) { try { string text = string.Join(", ", unreadable.GetRange(0, Math.Min(unreadable.Count, 10)).ToArray()); if (unreadable.Count > 10) { text += $" and {unreadable.Count - 10} more"; } ManualLogSource val = Logger.CreateLogSource("GCO SDW API Compatibility"); try { val.LogWarning((object)("These plugin files could not be read: " + text + ". If Smoothbrain Dual Wield is one of them, its sync fix was not prepared.")); } finally { ((IDisposable)val)?.Dispose(); } } catch (Exception) { } } } }