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 CS Hammer Tweak v1.0.0
plugins/CSHammerTweak.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CastleStructures.HammerCompat { [BepInPlugin("codex.CastleStructures.HammerCompat", "CastleStructures Hammer Compat", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <RetryInjectionRoutine>d__14 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Plugin <>4__this; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RetryInjectionRoutine>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown int num = <>1__state; Plugin plugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 60) { if (plugin.TryInjectPieces("Retry")) { return false; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } if (!plugin._sawCastlePieces) { ((BaseUnityPlugin)plugin).Logger.LogWarning((object)"Timed out waiting for CastleStructures pieces (rkc_*) to appear. Original CastleStructures may not be loaded."); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "codex.CastleStructures.HammerCompat"; public const string PluginName = "CastleStructures Hammer Compat"; public const string PluginVersion = "1.0.0"; private const string CastlePrefix = "rkc_"; private const string CastleCategory = "Castle"; private const string BuildItTable = "_RKCustomTable"; private ConfigEntry<bool> _showInVanillaHammer; private ConfigEntry<bool> _showInImprovedHammer; private bool _vanillaInjected; private bool _improvedInjected; private bool _sawCastlePieces; private void Awake() { _showInVanillaHammer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInVanillaHammer", true, "If true, inject CastleStructures pieces into vanilla Hammer. Requires restart to apply."); _showInImprovedHammer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInImprovedHammer", true, "If true and BuildIt is installed, inject CastleStructures pieces into BuildIt's Improved Hammer (_RKCustomTable). Requires restart to apply."); ((BaseUnityPlugin)this).Config.Save(); if (!_showInVanillaHammer.Value && !_showInImprovedHammer.Value) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Both CastleStructures hammer compat toggles are disabled. Nothing will be injected."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"CastleStructures Hammer Compat loaded. Config changes require restart (not applied live)."); PrefabManager.OnPrefabsRegistered += TryInjectFromEvent; ((MonoBehaviour)this).StartCoroutine(RetryInjectionRoutine()); } private void OnDestroy() { PrefabManager.OnPrefabsRegistered -= TryInjectFromEvent; } private void TryInjectFromEvent() { TryInjectPieces("OnPrefabsRegistered"); } [IteratorStateMachine(typeof(<RetryInjectionRoutine>d__14))] private IEnumerator RetryInjectionRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RetryInjectionRoutine>d__14(0) { <>4__this = this }; } private bool TryInjectPieces(string source) { List<GameObject> list = FindCastlePieces(); if (list.Count == 0) { return false; } _sawCastlePieces = true; bool flag = !_showInVanillaHammer.Value; bool flag2 = !_showInImprovedHammer.Value; if (_showInVanillaHammer.Value) { EnsureCategory("Hammer", "Castle"); PieceTable val = ResolvePieceTable("Hammer"); if ((Object)(object)val != (Object)null) { int num = InjectIntoTable("Hammer", val, list, "Castle", ((BaseUnityPlugin)this).Logger); if (num > 0 || _vanillaInjected) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[{source}] CastleStructures -> Hammer injected {num} new pieces."); } _vanillaInjected = true; flag = true; } } if (_showInImprovedHammer.Value) { PieceTable val2 = ResolvePieceTable("_RKCustomTable"); if ((Object)(object)val2 != (Object)null) { EnsureCategory("_RKCustomTable", "Castle"); int num2 = InjectIntoTable("_RKCustomTable", val2, list, "Castle", ((BaseUnityPlugin)this).Logger); if (num2 > 0 || _improvedInjected) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] CastleStructures -> {1} injected {2} new pieces.", source, "_RKCustomTable", num2)); } _improvedInjected = true; flag2 = true; } else if (IsBuildItLoaded()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + source + "] BuildIt detected but _RKCustomTable not available yet. Will retry.")); } } if (flag && flag2) { PrefabManager.OnPrefabsRegistered -= TryInjectFromEvent; return true; } return false; } private List<GameObject> FindCastlePieces() { List<GameObject> list = new List<GameObject>(); if ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.m_prefabs == null) { return list; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (!((Object)(object)prefab == (Object)null) && (((Object)prefab).name ?? string.Empty).StartsWith("rkc_", StringComparison.OrdinalIgnoreCase) && !((Object)(object)prefab.GetComponent<Piece>() == (Object)null)) { list.Add(prefab); } } return list; } private static int InjectIntoTable(string tableName, PieceTable table, List<GameObject> prefabs, string categoryName, ManualLogSource logger) { if (table.m_pieces == null) { table.m_pieces = new List<GameObject>(); } int num = 0; PieceManager instance = PieceManager.Instance; MethodInfo[] array = ((instance != null) ? (from m in ((object)instance).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public) where m.Name == "RegisterPieceInPieceTable" select m).ToArray() : Array.Empty<MethodInfo>()); foreach (GameObject prefab in prefabs) { if (!table.m_pieces.Any((GameObject p) => (Object)(object)p != (Object)null && string.Equals(((Object)p).name, ((Object)prefab).name, StringComparison.Ordinal))) { bool flag = false; if (instance != null && array.Length != 0) { flag = TryRegisterViaPieceManager(instance, array, tableName, table, prefab, categoryName); } if (!flag) { table.m_pieces.Add(prefab); logger.LogDebug((object)("Fallback injected piece '" + ((Object)prefab).name + "' into '" + tableName + "' by direct table list add.")); } num++; } } return num; } private static bool TryRegisterViaPieceManager(object pieceManager, MethodInfo[] registerMethods, string tableName, PieceTable table, GameObject prefab, string categoryName) { foreach (MethodInfo methodInfo in registerMethods) { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; bool flag = true; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; string text = parameters[j].Name ?? string.Empty; if (parameterType == typeof(string)) { if (text.IndexOf("table", StringComparison.OrdinalIgnoreCase) >= 0) { array[j] = tableName; } else if (text.IndexOf("piece", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("prefab", StringComparison.OrdinalIgnoreCase) >= 0) { array[j] = ((Object)prefab).name; } else if (text.IndexOf("categor", StringComparison.OrdinalIgnoreCase) >= 0) { array[j] = categoryName; } else { array[j] = categoryName; } } else if (typeof(GameObject).IsAssignableFrom(parameterType)) { array[j] = prefab; } else if (typeof(PieceTable).IsAssignableFrom(parameterType)) { array[j] = table; } else { if (!(parameterType == typeof(bool))) { flag = false; break; } array[j] = false; } } if (flag) { try { methodInfo.Invoke(pieceManager, array); return true; } catch { } } } return false; } private PieceTable ResolvePieceTable(string tableName) { try { if (tableName == "Hammer") { GameObject prefab = PrefabManager.Instance.GetPrefab("Hammer"); return (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildPieces; } GameObject prefab2 = PrefabManager.Instance.GetPrefab(tableName); return ((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<PieceTable>() : null; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to resolve piece table '" + tableName + "': " + ex.Message)); return null; } } private void EnsureCategory(string tableName, string categoryName) { try { object instance = PieceManager.Instance; if (instance == null) { return; } MethodInfo[] source = (from m in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public) where m.Name == "AddPieceCategory" select m).ToArray(); MethodInfo methodInfo = source.FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters3 = m.GetParameters(); return parameters3.Length == 2 && parameters3[0].ParameterType == typeof(string) && parameters3[1].ParameterType == typeof(string); }); if (methodInfo != null) { methodInfo.Invoke(instance, new object[2] { tableName, categoryName }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered piece category '" + categoryName + "' for table '" + tableName + "' via AddPieceCategory(string,string).")); return; } PieceTable val = ResolvePieceTable(tableName); if ((Object)(object)val != (Object)null) { MethodInfo methodInfo2 = source.FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters2 = m.GetParameters(); return parameters2.Length == 2 && typeof(PieceTable).IsAssignableFrom(parameters2[0].ParameterType) && parameters2[1].ParameterType == typeof(string); }); if (methodInfo2 != null) { methodInfo2.Invoke(instance, new object[2] { val, categoryName }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered piece category '" + categoryName + "' for table '" + tableName + "' via AddPieceCategory(PieceTable,string).")); return; } } MethodInfo methodInfo3 = source.FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return parameters.Length == 1 && parameters[0].ParameterType == typeof(string); }); if (methodInfo3 != null) { methodInfo3.Invoke(instance, new object[1] { categoryName }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered global piece category '" + categoryName + "' (table-specific overload unavailable for '" + tableName + "').")); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No supported AddPieceCategory overload found while adding '" + categoryName + "' to '" + tableName + "'.")); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to add category '" + categoryName + "' to '" + tableName + "': " + ex.Message)); } } private static bool IsBuildItLoaded() { foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { if ((pluginInfo.Key ?? string.Empty).IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } PluginInfo value = pluginInfo.Value; if (((value != null) ? value.Metadata : null) != null) { string obj = pluginInfo.Value.Metadata.GUID ?? string.Empty; string text = pluginInfo.Value.Metadata.Name ?? string.Empty; if (obj.IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("buildit", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } } return false; } } }