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 AuroraBlueprints v1.2.1
plugins/AuroraBlueprints.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [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("aurora")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Converts modded custom-category hammer pieces into tradeable blueprint consumables")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AuroraBlueprints")] [assembly: AssemblyTitle("AuroraBlueprints")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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 AuroraBlueprints { [HarmonyPatch] public static class BlueprintDrops { public class BlueprintGlowPulse : MonoBehaviour { private Light _light; private float _baseIntensity; private float _baseRange; private void Start() { _light = ((Component)this).GetComponent<Light>(); if ((Object)(object)_light != (Object)null) { _baseIntensity = _light.intensity; _baseRange = _light.range; } } private void Update() { if (!((Object)(object)_light == (Object)null)) { float num = Mathf.Sin(Time.time * 2.5f) * 0.5f + 0.5f; _light.intensity = _baseIntensity * (0.7f + 0.6f * num); _light.range = _baseRange * (0.85f + 0.3f * num); if ((Object)(object)((Component)this).transform.parent != (Object)null) { ((Component)this).transform.parent.Rotate(0f, 30f * Time.deltaTime, 0f, (Space)0); } } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__15_0; internal void <AddCommands>b__15_0(ConsoleEventArgs args) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player."); return; } if (BlueprintManager.Blueprints.Count == 0) { args.Context.AddString("No blueprints available. Has the scan run?"); return; } SpawnRandomBlueprint(((Component)localPlayer).transform.position, "admin_command"); args.Context.AddString("Random blueprint dropped."); } } [CompilerGenerated] private sealed class <CheckAndAttachGlowDelayed>d__13 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ItemDrop drop; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckAndAttachGlowDelayed>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)drop == (Object)null) { return false; } try { bool flag = false; if ((Object)(object)drop.m_itemData?.m_dropPrefab != (Object)null && ((Object)drop.m_itemData.m_dropPrefab).name.StartsWith("ABP_")) { flag = true; } else if (drop.m_itemData?.m_shared?.m_name != null && drop.m_itemData.m_shared.m_name.StartsWith("$ABP_")) { flag = true; } else if (((Object)((Component)drop).gameObject).name.StartsWith("ABP_")) { flag = true; } if (flag && (Object)(object)((Component)drop).GetComponentInChildren<BlueprintGlowPulse>() == (Object)null) { AttachGlow(((Component)drop).gameObject); } } catch { } 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(); } } private const string RPC_BlueprintAnnounce = "AuroraBlueprints_Announce"; private static bool _rpcRegistered = false; private static readonly HashSet<string> BossPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Eikthyr", "gd_king", "Bonemass", "Dragon", "GoblinKing", "SeekerQueen", "Fader", "EikthyrSpirit_RtD", "TrollKing_RtD", "SwampBoss_RtD", "TheElder", "TheQueen" }; public static void TryRegisterRPC() { if (!_rpcRegistered && ZRoutedRpc.instance != null) { _rpcRegistered = true; ZRoutedRpc.instance.Register<string>("AuroraBlueprints_Announce", (Action<long, string>)OnBlueprintAnnounce); } } private static void OnBlueprintAnnounce(long sender, string message) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } private static void BroadcastAnnouncement(string message) { TryRegisterRPC(); ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AuroraBlueprints_Announce", new object[1] { message }); } } [HarmonyPatch(typeof(CharacterDrop), "OnDeath")] [HarmonyPostfix] public static void CharacterDrop_OnDeath(CharacterDrop __instance) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || BlueprintManager.Blueprints.Count == 0) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && !component.IsPlayer()) { string prefabName = GetPrefabName(((Component)__instance).gameObject); float num = ((BossPrefabs.Contains(prefabName) || ((Object)(object)component != (Object)null && component.IsBoss())) ? ((Plugin.BossDropChance?.Value ?? 10f) / 100f) : ((Plugin.MobDropChance?.Value ?? 1f) / 100f)); if (!(Random.value > num)) { string dropperName = FindNearestPlayerName(((Component)__instance).transform.position); SpawnRandomBlueprint(((Component)__instance).transform.position, prefabName, dropperName); } } } private static string FindNearestPlayerName(Vector3 position) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) try { Player val = null; float num = float.MaxValue; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null)) { float num2 = Vector3.Distance(((Component)allPlayer).transform.position, position); if (num2 < num) { num = num2; val = allPlayer; } } } if ((Object)(object)val != (Object)null && num < 100f) { return val.GetPlayerName(); } } catch { } return null; } public static void SpawnRandomBlueprint(Vector3 position, string sourceName = "admin", string dropperName = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (BlueprintManager.Blueprints.Count == 0) { return; } List<string> list = new List<string>(BlueprintManager.Blueprints.Keys); string text = list[Random.Range(0, list.Count)]; BlueprintInfo blueprintInfo = BlueprintManager.Blueprints[text]; if ((Object)(object)blueprintInfo?.BlueprintPrefab == (Object)null) { return; } Vector3 val = position + Vector3.up * 0.75f; try { ObjectDB instance = ObjectDB.instance; GameObject val2 = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val2 == (Object)null) { return; } GameObject obj = Object.Instantiate<GameObject>(val2, val, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ((Object)obj).name = ((Object)blueprintInfo.BlueprintPrefab).name; ItemDrop component = obj.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { ItemDrop component2 = blueprintInfo.BlueprintPrefab.GetComponent<ItemDrop>(); if (component2?.m_itemData?.m_shared != null) { component.m_itemData.m_shared = component2.m_itemData.m_shared; } component.m_itemData.m_stack = 1; component.m_itemData.m_dropPrefab = blueprintInfo.BlueprintPrefab; } AttachGlow(obj); string displayName = blueprintInfo.DisplayName; BroadcastAnnouncement((!string.IsNullOrEmpty(dropperName)) ? ("<color=#ffd700>" + dropperName + "</color> <color=#b5651d>has dropped a Blueprint: " + displayName + "!</color>") : ("<color=#b5651d>A Blueprint: " + displayName + " has dropped!</color>")); Plugin.Log.LogInfo((object)("BlueprintDrop: " + sourceName + " dropped " + text + " (credit: " + (dropperName ?? "unknown") + ")")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("BlueprintDrop: Failed to drop " + text + ": " + ex.Message)); } } private static void AttachGlow(GameObject target) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return; } try { GameObject val = new GameObject("BlueprintGlow"); val.transform.SetParent(target.transform, false); val.transform.localPosition = new Vector3(0f, 0.5f, 0f); Light obj = val.AddComponent<Light>(); obj.type = (LightType)2; obj.color = new Color(1f, 0.78f, 0.2f, 1f); obj.intensity = 3.5f; obj.range = 8f; obj.shadows = (LightShadows)0; obj.renderMode = (LightRenderMode)1; val.AddComponent<BlueprintGlowPulse>(); TryAttachVfx(target); } catch (Exception ex) { Plugin.Log.LogWarning((object)("AttachGlow failed: " + ex.Message)); } } private static void TryAttachVfx(GameObject target) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[5] { "vfx_coin_pile", "vfx_haldor_appear", "vfx_blob_attack_trail", "vfx_potion_eitr_minor", "vfx_spirit_attack" }; try { if ((Object)(object)ZNetScene.instance == (Object)null) { return; } string[] array2 = array; foreach (string text in array2) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { Object.Instantiate<GameObject>(prefab, target.transform.position + Vector3.up * 0.3f, Quaternion.identity).transform.SetParent(target.transform, true); break; } } } catch { } } [HarmonyPatch(typeof(ItemDrop), "Awake")] [HarmonyPostfix] public static void ItemDrop_Awake_Glow(ItemDrop __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponentInChildren<BlueprintGlowPulse>() != (Object)null)) { ((MonoBehaviour)__instance).StartCoroutine(CheckAndAttachGlowDelayed(__instance)); } } [IteratorStateMachine(typeof(<CheckAndAttachGlowDelayed>d__13))] private static IEnumerator CheckAndAttachGlowDelayed(ItemDrop drop) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckAndAttachGlowDelayed>d__13(0) { drop = drop }; } [HarmonyPatch(typeof(ZRoutedRpc), "SetUID")] [HarmonyPostfix] public static void ZRoutedRpc_SetUID() { TryRegisterRPC(); } [HarmonyPatch(typeof(Terminal), "InitTerminal")] [HarmonyPostfix] public static void AddCommands() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__15_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player."); } else if (BlueprintManager.Blueprints.Count == 0) { args.Context.AddString("No blueprints available. Has the scan run?"); } else { SpawnRandomBlueprint(((Component)localPlayer).transform.position, "admin_command"); args.Context.AddString("Random blueprint dropped."); } }; <>c.<>9__15_0 = val; obj = (object)val; } new ConsoleCommand("droprandomabp", "Drop a random blueprint at your position", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static string GetPrefabName(GameObject obj) { if ((Object)(object)obj == (Object)null) { return ""; } string text = ((Object)obj).name; int num = text.IndexOf("(Clone)"); if (num > 0) { text = text.Substring(0, num); } return text.Trim(); } } public static class BlueprintHammerItem { [CompilerGenerated] private sealed class <RecipeRetryRoutine>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RecipeRetryRoutine>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; if (_recipeAdded) { return false; } if (!((Object)(object)ObjectDB.instance == (Object)null)) { AddRecipe(ObjectDB.instance); if (_recipeAdded) { Plugin.Log.LogInfo((object)"BlueprintHammer: recipe finalized after retry."); return false; } } <i>5__2++; break; } if (<i>5__2 < 24) { <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; } 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 PrefabName = "BlueprintHammer"; public const string SharedName = "$item_blueprint_hammer"; public const string DescKey = "$item_blueprint_hammer_desc"; private static GameObject _prefabRoot; private static bool _created; private static bool _registeredInObjectDB; public static bool SuppressDrops; private static bool _recipeAdded; private static Recipe _addedRecipe; private const int RequiredResourceCount = 3; public static GameObject Prefab { get; private set; } public static bool IsLocalWielding() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } try { ItemData val = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem").Invoke((Humanoid)(object)localPlayer); if (val == null) { return false; } if (val.m_shared?.m_name == "$item_blueprint_hammer") { return true; } if ((Object)(object)val.m_dropPrefab != (Object)null && ((Object)val.m_dropPrefab).name == "BlueprintHammer") { return true; } return false; } catch { return false; } } public static void CreateItemPrefab(ObjectDB objectDB) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_created || (Object)(object)objectDB == (Object)null || objectDB.m_items == null || objectDB.m_items.Count < 50) { return; } GameObject val = objectDB.GetItemPrefab("MarketplaceHammer"); if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab("MarketplaceHammer"); } if ((Object)(object)val == (Object)null) { val = objectDB.GetItemPrefab("Hammer"); } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"BlueprintHammer: No Hammer template found — retry later."); return; } if ((Object)(object)_prefabRoot == (Object)null) { _prefabRoot = new GameObject("AuroraBlueprintHammerRoot"); _prefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_prefabRoot); } try { GameObject val2 = Object.Instantiate<GameObject>(val, _prefabRoot.transform); ((Object)val2).name = "BlueprintHammer"; ItemDrop component = val2.GetComponent<ItemDrop>(); if (component?.m_itemData?.m_shared == null) { Plugin.Log.LogError((object)"BlueprintHammer: template has no ItemDrop/shared."); return; } SharedData shared = component.m_itemData.m_shared; shared.m_name = "$item_blueprint_hammer"; shared.m_description = "$item_blueprint_hammer_desc"; shared.m_maxStackSize = 1; shared.m_maxQuality = 1; shared.m_questItem = false; shared.m_teleportable = true; ApplyGoldenTint(val2); component.m_itemData.m_dropPrefab = val2; Prefab = val2; _created = true; Plugin.Log.LogInfo((object)("BlueprintHammer: created from template '" + ((Object)val).name + "'.")); } catch (Exception arg) { Plugin.Log.LogError((object)$"BlueprintHammer: create failed: {arg}"); } } private static void ApplyGoldenTint(GameObject root) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.82f, 0.18f, 1f); try { Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || val2.sharedMaterials == null) { continue; } Material[] materials = val2.materials; for (int j = 0; j < materials.Length; j++) { if (!((Object)(object)materials[j] == (Object)null)) { if (materials[j].HasProperty("_Color")) { materials[j].color = Color.Lerp(materials[j].color, val, 0.7f); } if (materials[j].HasProperty("_EmissionColor")) { materials[j].SetColor("_EmissionColor", val * 0.4f); } } } val2.materials = materials; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("BlueprintHammer: tint failed: " + ex.Message)); } } public static void RegisterInObjectDB(ObjectDB objectDB) { if ((Object)(object)objectDB == (Object)null || objectDB.m_items == null || objectDB.m_items.Count < 50) { return; } if (!_created) { CreateItemPrefab(objectDB); } if (_created && !((Object)(object)Prefab == (Object)null)) { if (!objectDB.m_items.Exists((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "BlueprintHammer")) { objectDB.m_items.Add(Prefab); } UpdateHash(objectDB); if (!_recipeAdded) { AddRecipe(objectDB); } if (!_registeredInObjectDB) { _registeredInObjectDB = true; Plugin.Log.LogInfo((object)"BlueprintHammer: registered in ObjectDB."); } } } private static void UpdateHash(ObjectDB objectDB) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; string[] array = new string[2] { "m_itemByHash", "m_itemsByHash" }; foreach (string name in array) { FieldInfo field = typeof(ObjectDB).GetField(name, bindingAttr); if (!(field == null) && field.GetValue(objectDB) is Dictionary<int, GameObject> dictionary) { dictionary[StringExtensionMethods.GetStableHashCode(((Object)Prefab).name)] = Prefab; break; } } } public static void RegisterInZNetScene(ZNetScene zns) { if ((Object)(object)zns == (Object)null || (Object)(object)Prefab == (Object)null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Dictionary<int, GameObject> dictionary = null; string[] array = new string[2] { "m_namedPrefabs", "m_prefabsByHash" }; foreach (string name in array) { FieldInfo field = typeof(ZNetScene).GetField(name, bindingAttr); if (!(field == null)) { dictionary = field.GetValue(zns) as Dictionary<int, GameObject>; if (dictionary != null) { break; } } } if (dictionary != null) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)Prefab).name); if (!dictionary.ContainsKey(stableHashCode)) { dictionary[stableHashCode] = Prefab; Plugin.Log.LogInfo((object)"BlueprintHammer: registered in ZNetScene."); } } } private static GameObject FindItemPrefab(ObjectDB db, params string[] names) { string[] array = names; foreach (string text in array) { GameObject itemPrefab = db.GetItemPrefab(text); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } } array = names; foreach (string value in array) { foreach (GameObject item in db.m_items) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return item; } } } return null; } private static void AddRecipe(ObjectDB objectDB) { if ((Object)(object)Prefab == (Object)null) { Plugin.Log.LogWarning((object)"BlueprintHammer: recipe skipped — Prefab is null."); return; } if (objectDB.m_recipes == null) { Plugin.Log.LogWarning((object)"BlueprintHammer: recipe skipped — m_recipes null."); return; } ItemDrop component = Prefab.GetComponent<ItemDrop>(); GameObject val = FindItemPrefab(objectDB, "GoldIngot", "Gold"); GameObject val2 = FindItemPrefab(objectDB, "Veridium", "veridium"); GameObject val3 = FindItemPrefab(objectDB, "Thunderstone", "ThunderStone", "thunderstone"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)"BlueprintHammer: ingredient 'GoldIngot' not yet available."); } if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogInfo((object)"BlueprintHammer: ingredient 'Veridium' not yet available (waiting for WackysDatabase)."); } if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogInfo((object)"BlueprintHammer: ingredient 'Thunderstone' not yet available."); } List<Requirement> list = new List<Requirement>(); if ((Object)(object)val != (Object)null) { list.Add(MakeReq(val, 1)); } if ((Object)(object)val2 != (Object)null) { list.Add(MakeReq(val2, 1)); } if ((Object)(object)val3 != (Object)null) { list.Add(MakeReq(val3, 5)); } if (_recipeAdded && (Object)(object)_addedRecipe != (Object)null) { Requirement[] resources = _addedRecipe.m_resources; int num = ((resources != null) ? resources.Length : 0); if (list.Count <= num) { return; } objectDB.m_recipes.Remove(_addedRecipe); _addedRecipe = null; _recipeAdded = false; Plugin.Log.LogInfo((object)$"BlueprintHammer: removing old incomplete recipe ({num} resources) — re-adding with {list.Count}."); } else { foreach (Recipe recipe in objectDB.m_recipes) { if ((Object)(object)recipe == (Object)null) { continue; } if (!((Object)(object)recipe.m_item == (Object)(object)component)) { if (!((Object)(object)recipe.m_item != (Object)null)) { continue; } GameObject gameObject = ((Component)recipe.m_item).gameObject; if (!(((gameObject != null) ? ((Object)gameObject).name : null) == "BlueprintHammer")) { continue; } } Requirement[] resources2 = recipe.m_resources; int num2 = ((resources2 != null) ? resources2.Length : 0); if (list.Count <= num2) { _addedRecipe = recipe; _recipeAdded = true; return; } objectDB.m_recipes.Remove(recipe); Plugin.Log.LogInfo((object)$"BlueprintHammer: removing existing inferior recipe ({num2} resources) — re-adding with {list.Count}."); break; } } if (list.Count == 0) { Plugin.Log.LogWarning((object)"BlueprintHammer: no recipe resources resolved — recipe skipped (will retry)."); return; } CraftingStation val4 = null; GameObject val5 = objectDB.GetItemPrefab("forge"); if ((Object)(object)val5 == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val5 = ZNetScene.instance.GetPrefab("forge"); } if ((Object)(object)val5 != (Object)null) { val4 = val5.GetComponent<CraftingStation>(); } if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogWarning((object)"BlueprintHammer: Forge station not found — recipe will retry later."); return; } Recipe val6 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val6).name = "Recipe_BlueprintHammer"; val6.m_item = component; val6.m_craftingStation = val4; val6.m_minStationLevel = 2; val6.m_amount = 1; val6.m_resources = list.ToArray(); val6.m_enabled = true; objectDB.m_recipes.Add(val6); _addedRecipe = val6; _recipeAdded = list.Count >= 3; try { MethodInfo method = typeof(ObjectDB).GetMethod("UpdateItemHashes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(objectDB, null); } } catch { } string arg = (_recipeAdded ? "FINAL" : "PARTIAL — will retry for missing ingredients"); Plugin.Log.LogInfo((object)$"BlueprintHammer: recipe added ({list.Count}/{3} resources) at Forge level 2 [{arg}]."); } [IteratorStateMachine(typeof(<RecipeRetryRoutine>d__22))] public static IEnumerator RecipeRetryRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RecipeRetryRoutine>d__22(0); } private static Requirement MakeReq(GameObject prefab, int amount) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown ItemDrop component = prefab.GetComponent<ItemDrop>(); return new Requirement { m_resItem = component, m_amount = amount, m_amountPerLevel = 0, m_recover = true }; } public static void RegisterLocalization() { Localization instance = Localization.instance; if (instance == null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Dictionary<string, string> dictionary = null; string[] array = new string[3] { "m_translations", "m_words", "m_strings" }; foreach (string name in array) { FieldInfo field = typeof(Localization).GetField(name, bindingAttr); if (!(field == null)) { dictionary = field.GetValue(instance) as Dictionary<string, string>; if (dictionary != null) { break; } } } if (dictionary != null) { dictionary["item_blueprint_hammer"] = "Blueprint Hammer"; dictionary["item_blueprint_hammer_desc"] = "A gold-plated builder's hammer. Repairs pieces without a crafting station, and recovers blueprints from blueprinted builds instead of destroying them."; } } } [HarmonyPatch] public static class BlueprintHammerPatches { private static readonly Dictionary<int, Requirement[]> _pendingRestore = new Dictionary<int, Requirement[]>(); [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPostfix] public static void ObjectDB_Awake_Postfix(ObjectDB __instance) { BlueprintHammerItem.RegisterInObjectDB(__instance); BlueprintHammerItem.RegisterLocalization(); } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPostfix] public static void ObjectDB_CopyOtherDB_Postfix(ObjectDB __instance) { BlueprintHammerItem.RegisterInObjectDB(__instance); BlueprintHammerItem.RegisterLocalization(); } [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPostfix] public static void ZNetScene_Awake_Postfix(ZNetScene __instance) { BlueprintHammerItem.RegisterInZNetScene(__instance); if ((Object)(object)ObjectDB.instance != (Object)null) { BlueprintHammerItem.RegisterInObjectDB(ObjectDB.instance); } if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(BlueprintHammerItem.RecipeRetryRoutine()); } } [HarmonyPatch(typeof(Player), "RemovePiece")] [HarmonyPrefix] public static bool RemovePiece_Prefix(Player __instance, ref bool __result) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!BlueprintHammerItem.IsLocalWielding()) { return true; } Piece val = null; try { MethodInfo method = typeof(Player).GetMethod("PieceRayTest", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { object[] array = new object[6] { Vector3.zero, Vector3.zero, null, null, null, false }; if ((bool)method.Invoke(__instance, array)) { object obj = array[2]; val = (Piece)((obj is Piece) ? obj : null); } } } catch { } if ((Object)(object)val == (Object)null) { return true; } string text = ((Object)((Component)val).gameObject).name; int num = text.IndexOf("(Clone)"); if (num > 0) { text = text.Substring(0, num).Trim(); } string key = "ABP_" + text; if (!BlueprintManager.Blueprints.ContainsKey(key)) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "That is not a blueprint build", 0, (Sprite)null, false); } __result = false; return false; } BlueprintInfo info = BlueprintManager.Blueprints[key]; Vector3 pos = ((Component)val).transform.position + Vector3.up * 0.75f; try { SpawnSpecificBlueprint(info, pos); } catch (Exception ex) { Plugin.Log.LogWarning((object)("BlueprintHammer: spawn blueprint failed: " + ex.Message)); } Piece val2 = val; Requirement[] resources = val2.m_resources; val2.m_resources = (Requirement[])(object)new Requirement[0]; BlueprintHammerItem.SuppressDrops = true; try { _pendingRestore[((Object)val2).GetInstanceID()] = resources; } catch { } return true; } [HarmonyPatch(typeof(Player), "RemovePiece")] [HarmonyPostfix] public static void RemovePiece_Postfix() { BlueprintHammerItem.SuppressDrops = false; if (_pendingRestore.Count > 16) { _pendingRestore.Clear(); } } public static void SpawnSpecificBlueprint(BlueprintInfo info, Vector3 pos) { //IL_0034: 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) if (info == null || (Object)(object)info.BlueprintPrefab == (Object)null) { return; } ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val == (Object)null) { return; } GameObject obj = Object.Instantiate<GameObject>(val, pos, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ((Object)obj).name = ((Object)info.BlueprintPrefab).name; ItemDrop component = obj.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { ItemDrop component2 = info.BlueprintPrefab.GetComponent<ItemDrop>(); if (component2?.m_itemData?.m_shared != null) { component.m_itemData.m_shared = component2.m_itemData.m_shared; } component.m_itemData.m_stack = 1; component.m_itemData.m_dropPrefab = info.BlueprintPrefab; } } } public class BlueprintInfo { public GameObject PiecePrefab; public string OriginalPieceName; public string DisplayName; public Requirement[] OriginalRequirements; public CraftingStation OriginalCraftingStation; public PieceCategory OriginalCategory; public GameObject BlueprintPrefab; } public static class BlueprintManager { [CompilerGenerated] private sealed class <ForceSelectPieceDelayed>d__28 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player player; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ForceSelectPieceDelayed>d__28(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)player == (Object)null || !HasActiveBlueprint) { return false; } try { player.SetSelectedPiece(new Vector2Int(0, 0)); Hud instance = Hud.instance; if ((Object)(object)instance != (Object)null) { FieldInfo field = typeof(Hud).GetField("m_lastPieceCategory", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(instance, (object)(PieceCategory)(-1)); } } } catch { } 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(); } } [CompilerGenerated] private sealed class <UnequipHammerDelayed>d__36 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Player player; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <UnequipHammerDelayed>d__36(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)player != (Object)null) { ((Humanoid)player).HideHandItems(false, true); } 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 static readonly Dictionary<string, BlueprintInfo> Blueprints = new Dictionary<string, BlueprintInfo>(); public static readonly Dictionary<string, string> SharedNameToBlueprint = new Dictionary<string, string>(); private static GameObject _prefabRoot; private static bool _scanned = false; private static readonly List<GameObject> _removedPieces = new List<GameObject>(); public static BlueprintInfo ActiveBlueprint; public static ItemData ActiveBlueprintItem; public static List<GameObject> OriginalHammerPieces; public static float LastBlueprintUseTime = -999f; public const float PostBlueprintHammerLockSeconds = 1.5f; private static Sprite _fallbackParchmentIcon; private static Sprite _cachedHammerIcon; public static bool HasActiveBlueprint => ActiveBlueprint != null; public static void RestoreFromCache() { if (Blueprints.Count > 0 || (Object)(object)ObjectDB.instance == (Object)null) { return; } string path = Path.Combine(Path.Combine(Paths.ConfigPath, "AuroraBlueprints"), "blueprint_cache.txt"); if (!File.Exists(path)) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer"); if ((Object)(object)itemPrefab == (Object)null) { return; } try { string[] array = File.ReadAllLines(path); int num = 0; string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string[] array3 = array2[i].Split(new char[1] { '|' }); if (array3.Length >= 3) { string text = array3[0].Trim(); string originalPieceName = array3[1].Trim(); string displayName = array3[2].Trim(); if (!Blueprints.ContainsKey(text)) { CreateBlueprintItem(new BlueprintInfo { OriginalPieceName = originalPieceName, DisplayName = displayName }, text, itemPrefab); num++; } } } if (num > 0) { Plugin.Log.LogInfo((object)$"Restored {num} blueprints from cache (before inventory load)."); RegisterAll(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("RestoreFromCache failed: " + ex.Message)); } } private static void SaveCache() { try { string text = Path.Combine(Paths.ConfigPath, "AuroraBlueprints"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } string path = Path.Combine(text, "blueprint_cache.txt"); List<string> list = new List<string>(); foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints) { list.Add(blueprint.Key + "|" + blueprint.Value.OriginalPieceName + "|" + blueprint.Value.DisplayName); } File.WriteAllLines(path, list.ToArray()); Plugin.Log.LogInfo((object)$"Saved {list.Count} blueprints to cache."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("SaveCache failed: " + ex.Message)); } } public static void ScanAndCreateBlueprints() { //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Invalid comparison between Unknown and I4 //IL_0135: 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_014f: Expected I4, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Invalid comparison between Unknown and I4 //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Invalid comparison between Unknown and I4 bool flag = Blueprints.Count > 0; foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints) { if ((Object)(object)blueprint.Value.PiecePrefab == (Object)null) { flag = false; break; } } if ((_scanned && flag) || (Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer"); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component?.m_itemData?.m_shared?.m_buildPieces == (Object)null) { return; } PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; BuildExcludeSet(); List<GameObject> list = new List<GameObject>(); foreach (GameObject piece in buildPieces.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } Piece component2 = piece.GetComponent<Piece>(); if ((Object)(object)component2 == (Object)null || IsPieceExcluded(((Object)piece).name)) { continue; } string name = Enum.GetName(typeof(PieceCategory), component2.m_category); int num = (int)component2.m_category; if (name == "Crafting" || num == 1 || Plugin.VanillaPieceNames.Contains(((Object)piece).name) || string.IsNullOrEmpty(component2.m_name)) { continue; } string text = component2.m_name.ToLowerInvariant(); string text2 = ((Object)piece).name.ToLowerInvariant(); if (text.Contains("repair") || text2.Contains("repair") || text.Contains("upgrade") || text2.Contains("upgrade") || ((Object)piece).name == "piece_repair" || ((Object)piece).name == "Hammer" || ((Object)piece).name == "Cultivator" || ((Object)piece).name == "Hoe" || component2.m_name == "$piece_repair" || component2.m_resources == null || component2.m_resources.Length == 0 || (int)component2.m_category >= 100 || (Object)(object)piece.GetComponent<StationExtension>() != (Object)null) { continue; } Collider[] componentsInChildren = piece.GetComponentsInChildren<Collider>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { continue; } string text3 = "ABP_" + ((Object)piece).name; if (Blueprints.TryGetValue(text3, out var value)) { if ((Object)(object)value.PiecePrefab == (Object)null) { value.PiecePrefab = piece; value.OriginalRequirements = component2.m_resources; value.OriginalCraftingStation = component2.m_craftingStation; value.OriginalCategory = component2.m_category; BlueprintInfo blueprintInfo = value; Localization instance = Localization.instance; blueprintInfo.DisplayName = ((instance != null) ? instance.Localize(component2.m_name) : null) ?? component2.m_name; if ((Object)(object)value.BlueprintPrefab != (Object)null && (int)SystemInfo.graphicsDeviceType != 4 && (Object)(object)component2.m_icon != (Object)null) { ItemDrop component3 = value.BlueprintPrefab.GetComponent<ItemDrop>(); if (component3?.m_itemData?.m_shared != null) { Sprite val = CreateBorderedIcon(component2.m_icon); component3.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val ?? component2.m_icon }; } } Plugin.Log.LogInfo((object)("[SCAN] Updated cached blueprint with real prefab: " + text3)); GameObject blueprintPrefab = value.BlueprintPrefab; RefreshInventoryIcons(text3, ((blueprintPrefab != null) ? blueprintPrefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared); } list.Add(piece); } else { BlueprintInfo obj = new BlueprintInfo { PiecePrefab = piece, OriginalPieceName = ((Object)piece).name }; Localization instance2 = Localization.instance; obj.DisplayName = ((instance2 != null) ? instance2.Localize(component2.m_name) : null) ?? component2.m_name; obj.OriginalRequirements = component2.m_resources; obj.OriginalCraftingStation = component2.m_craftingStation; obj.OriginalCategory = component2.m_category; BlueprintInfo blueprintInfo2 = obj; Plugin.Log.LogInfo((object)("[SCAN] Blueprinting: " + ((Object)piece).name + " (category=" + (name ?? ("custom_" + num)) + ", display=" + blueprintInfo2.DisplayName + ")")); CreateBlueprintItem(blueprintInfo2, text3, itemPrefab); list.Add(piece); } } if ((int)SystemInfo.graphicsDeviceType != 4) { foreach (GameObject item in list) { buildPieces.m_pieces.Remove(item); _removedPieces.Add(item); } } if (Blueprints.Count > 0) { _scanned = true; Plugin.Log.LogInfo((object)$"Created {Blueprints.Count} blueprints from custom-category pieces."); RegisterAll(); SaveCache(); } else { Plugin.Log.LogInfo((object)"No custom-category pieces found in hammer. Will retry later."); } } private static HashSet<string> BuildExcludeSet() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string[] array = (Plugin.ExcludePrefabs?.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { hashSet.Add(text); } } return hashSet; } private static bool NameMatchesPattern(string name, string pattern) { if (string.IsNullOrEmpty(pattern) || string.IsNullOrEmpty(name)) { return false; } bool flag = pattern.StartsWith("*"); bool flag2 = pattern.EndsWith("*"); if (flag && flag2) { string value = pattern.Substring(1, pattern.Length - 2); return name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0; } if (flag) { return name.EndsWith(pattern.Substring(1), StringComparison.OrdinalIgnoreCase); } if (flag2) { return name.StartsWith(pattern.Substring(0, pattern.Length - 1), StringComparison.OrdinalIgnoreCase); } return name.Equals(pattern, StringComparison.OrdinalIgnoreCase); } public static bool IsPieceExcluded(string pieceName) { foreach (string item in BuildExcludeSet()) { if (NameMatchesPattern(pieceName, item)) { return true; } } return false; } private static void CreateBlueprintItem(BlueprintInfo info, string bpName, GameObject hammerPrefab) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Invalid comparison between Unknown and I4 //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_prefabRoot == (Object)null) { _prefabRoot = new GameObject("AuroraBlueprintPrefabs"); _prefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_prefabRoot); } try { GameObject val = Object.Instantiate<GameObject>(hammerPrefab, _prefabRoot.transform); ((Object)val).name = bpName; ItemDrop component = val.GetComponent<ItemDrop>(); if (component?.m_itemData?.m_shared == null) { Plugin.Log.LogWarning((object)("Failed to configure blueprint " + bpName + " - no ItemDrop.shared")); return; } SharedData shared = component.m_itemData.m_shared; shared.m_name = "$" + bpName; shared.m_description = "$" + bpName + "_desc"; shared.m_itemType = (ItemType)2; shared.m_maxStackSize = 50; shared.m_weight = 0.1f; shared.m_teleportable = true; shared.m_maxQuality = 1; shared.m_questItem = false; shared.m_buildPieces = null; shared.m_useDurability = false; shared.m_maxDurability = 0f; shared.m_durabilityPerLevel = 0f; bool num = (int)SystemInfo.graphicsDeviceType == 4; Piece val2 = (((Object)(object)info.PiecePrefab != (Object)null) ? info.PiecePrefab.GetComponent<Piece>() : null); if (!num && (Object)(object)val2 != (Object)null && (Object)(object)val2.m_icon != (Object)null) { Sprite val3 = CreateBorderedIcon(val2.m_icon); shared.m_icons = (Sprite[])(object)new Sprite[1] { val3 ?? val2.m_icon }; } shared.m_attack = new Attack(); shared.m_secondaryAttack = new Attack(); shared.m_animationState = (AnimationState)0; component.m_itemData.m_dropPrefab = val; info.BlueprintPrefab = val; Blueprints[bpName] = info; SharedNameToBlueprint["$" + bpName] = bpName; Plugin.Log.LogInfo((object)("Blueprint created: " + bpName + " -> " + info.DisplayName)); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to create blueprint " + bpName + ": " + ex.Message)); } } public static void RemoveBlueprintedPiecesFromHammer() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Invalid comparison between Unknown and I4 if (Blueprints.Count == 0 || (int)SystemInfo.graphicsDeviceType == 4) { return; } ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val == (Object)null) { return; } PieceTable val2 = val.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val2 == (Object)null) { return; } int num = 0; for (int num2 = val2.m_pieces.Count - 1; num2 >= 0; num2--) { GameObject val3 = val2.m_pieces[num2]; if (!((Object)(object)val3 == (Object)null) && !IsProtectedHammerEntry(val3)) { string key = "ABP_" + ((Object)val3).name; if (Blueprints.ContainsKey(key)) { val2.m_pieces.RemoveAt(num2); num++; } else { Piece component = val3.GetComponent<Piece>(); if ((Object)(object)component != (Object)null && (int)component.m_category > 100) { val2.m_pieces.RemoveAt(num2); num++; } } } } if (num > 0) { Plugin.Log.LogInfo((object)$"Removed {num} blueprinted/modded-category pieces from hammer."); } } public static void RemoveModdedCategoriesFromHammer() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Invalid comparison between Unknown and I4 ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val == (Object)null) { return; } PieceTable val2 = val.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val2 == (Object)null) { return; } int num = 0; for (int num2 = val2.m_pieces.Count - 1; num2 >= 0; num2--) { GameObject val3 = val2.m_pieces[num2]; if (!((Object)(object)val3 == (Object)null) && !IsProtectedHammerEntry(val3)) { Piece component = val3.GetComponent<Piece>(); if ((Object)(object)component != (Object)null && (int)component.m_category > 100) { val2.m_pieces.RemoveAt(num2); num++; } } } if (num > 0) { Plugin.Log.LogInfo((object)$"RemoveModdedCategoriesFromHammer: Stripped {num} modded-category pieces."); } } private static bool IsProtectedHammerEntry(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } if (((Object)go).name == "piece_repair" || ((Object)go).name == "Hammer" || ((Object)go).name == "Cultivator" || ((Object)go).name == "Hoe") { return true; } Piece component = go.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { return false; } if (component.m_name == "$piece_repair") { return true; } if (!string.IsNullOrEmpty(component.m_name) && component.m_name.ToLowerInvariant().Contains("repair")) { return true; } return false; } private static void RefreshInventoryIcons(string bpName, SharedData updatedShared) { if (updatedShared == null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null) { return; } string text = "$" + bpName; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem?.m_shared != null && !(allItem.m_shared.m_name != text) && allItem.m_shared != updatedShared && updatedShared.m_icons != null && updatedShared.m_icons.Length != 0) { allItem.m_shared.m_icons = updatedShared.m_icons; Plugin.Log.LogInfo((object)("Refreshed icon for inventory item " + text)); } } } public static void RefreshAllInventoryIcons() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null || (int)SystemInfo.graphicsDeviceType == 4) { return; } int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem?.m_shared == null) { continue; } string text = allItem.m_shared.m_name ?? ""; if (!text.StartsWith("$ABP_") || !SharedNameToBlueprint.TryGetValue(text, out var value) || !Blueprints.TryGetValue(value, out var value2)) { continue; } if ((Object)(object)value2.PiecePrefab == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { value2.PiecePrefab = ZNetScene.instance.GetPrefab(value2.OriginalPieceName); if ((Object)(object)value2.PiecePrefab != (Object)null) { Piece component = value2.PiecePrefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { value2.OriginalRequirements = component.m_resources; value2.OriginalCraftingStation = component.m_craftingStation; value2.OriginalCategory = component.m_category; BlueprintInfo blueprintInfo = value2; Localization instance = Localization.instance; blueprintInfo.DisplayName = ((instance != null) ? instance.Localize(component.m_name) : null) ?? component.m_name; if ((Object)(object)component.m_icon != (Object)null && (Object)(object)value2.BlueprintPrefab != (Object)null) { ItemDrop component2 = value2.BlueprintPrefab.GetComponent<ItemDrop>(); if (component2?.m_itemData?.m_shared != null) { Sprite val = CreateBorderedIcon(component.m_icon); component2.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val ?? component.m_icon }; } } } } } if ((Object)(object)value2.BlueprintPrefab == (Object)null) { continue; } ItemDrop component3 = value2.BlueprintPrefab.GetComponent<ItemDrop>(); if (component3?.m_itemData?.m_shared == null) { continue; } Sprite[] icons = component3.m_itemData.m_shared.m_icons; bool flag = icons != null && icons.Length != 0 && (Object)(object)icons[0] != (Object)null; if (!flag) { Sprite orCreateFallbackIcon = GetOrCreateFallbackIcon(); if ((Object)(object)orCreateFallbackIcon != (Object)null) { component3.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { orCreateFallbackIcon }; icons = component3.m_itemData.m_shared.m_icons; flag = true; } } if (flag) { Sprite cachedHammerIcon = GetCachedHammerIcon(); bool flag2 = allItem.m_shared.m_icons == null || allItem.m_shared.m_icons.Length == 0 || (Object)(object)allItem.m_shared.m_icons[0] == (Object)null || ((Object)(object)cachedHammerIcon != (Object)null && (Object)(object)allItem.m_shared.m_icons[0] == (Object)(object)cachedHammerIcon); if (allItem.m_shared.m_icons != icons || flag2) { allItem.m_shared.m_icons = icons; num++; } } } if (num > 0) { Plugin.Log.LogInfo((object)$"Refreshed icons for {num} blueprint items in inventory."); } } public static void RegisterAll() { RegisterInObjectDB(ObjectDB.instance); if ((Object)(object)ZNetScene.instance != (Object)null) { RegisterInZNetScene(ZNetScene.instance); } RegisterLocalization(); } public static void RegisterInObjectDB(ObjectDB objectDB) { if (objectDB?.m_items == null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints) { GameObject prefab = blueprint.Value.BlueprintPrefab; if (!((Object)(object)prefab == (Object)null) && !objectDB.m_items.Exists((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)prefab).name)) { objectDB.m_items.Add(prefab); } } string[] array = new string[2] { "m_itemByHash", "m_itemsByHash" }; foreach (string name in array) { FieldInfo field = typeof(ObjectDB).GetField(name, bindingAttr); if (field == null || !(field.GetValue(objectDB) is Dictionary<int, GameObject> dictionary)) { continue; } { foreach (KeyValuePair<string, BlueprintInfo> blueprint2 in Blueprints) { if ((Object)(object)blueprint2.Value.BlueprintPrefab != (Object)null) { dictionary[StringExtensionMethods.GetStableHashCode(((Object)blueprint2.Value.BlueprintPrefab).name)] = blueprint2.Value.BlueprintPrefab; } } break; } } } public static void RegisterInZNetScene(ZNetScene zNetScene) { if ((Object)(object)zNetScene == (Object)null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Dictionary<int, GameObject> dictionary = null; string[] array = new string[2] { "m_namedPrefabs", "m_prefabsByHash" }; foreach (string name in array) { FieldInfo field = typeof(ZNetScene).GetField(name, bindingAttr); if (!(field == null)) { dictionary = field.GetValue(zNetScene) as Dictionary<int, GameObject>; if (dictionary != null) { break; } } } if (dictionary == null) { return; } foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints) { GameObject blueprintPrefab = blueprint.Value.BlueprintPrefab; if (!((Object)(object)blueprintPrefab == (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)blueprintPrefab).name); if (!dictionary.ContainsKey(stableHashCode)) { dictionary[stableHashCode] = blueprintPrefab; } } } } public static void RegisterLocalization() { Localization instance = Localization.instance; if (instance == null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Dictionary<string, string> dictionary = null; string[] array = new string[2] { "m_translations", "m_words" }; foreach (string name in array) { FieldInfo field = typeof(Localization).GetField(name, bindingAttr); if (!(field == null)) { dictionary = field.GetValue(instance) as Dictionary<string, string>; if (dictionary != null) { break; } } } if (dictionary == null) { return; } foreach (KeyValuePair<string, BlueprintInfo> blueprint in Blueprints) { string key = blueprint.Key; string displayName = blueprint.Value.DisplayName; dictionary[key] = "<color=#b5651d>Blueprint: " + displayName + "</color>"; dictionary[key + "_desc"] = "Use to place a " + displayName + ".\nNo materials required. One-time use.\nBlueprint is consumed after successful placement."; } } public static void FixDropPrefab(ItemData item) { if (item != null && !((Object)(object)item.m_dropPrefab != (Object)null)) { string text = item.m_shared?.m_name ?? ""; if (text.StartsWith("$ABP_") && SharedNameToBlueprint.TryGetValue(text, out var value) && Blueprints.TryGetValue(value, out var value2) && (Object)(object)value2.BlueprintPrefab != (Object)null) { item.m_dropPrefab = value2.BlueprintPrefab; } } } public static bool StartPlacement(Player player, ItemData blueprintItem) { //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) string key = blueprintItem.m_shared?.m_name ?? ""; if (!SharedNameToBlueprint.TryGetValue(key, out var value)) { return false; } if (!Blueprints.TryGetValue(value, out var value2)) { return false; } if (ActiveBlueprint != null) { Plugin.Log.LogWarning((object)"StartPlacement called while another blueprint is active — restoring previous first."); RestoreAndClear(); } GameObject val = value2.PiecePrefab; if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab(value2.OriginalPieceName); if ((Object)(object)val != (Object)null) { value2.PiecePrefab = val; } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Blueprint piece prefab '" + value2.OriginalPieceName + "' not found!")); return false; } Piece component = val.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)("Blueprint piece '" + value2.OriginalPieceName + "' has no Piece component!")); return false; } ItemData val2 = FindHammerInInventory(player); if (val2 == null) { Plugin.Log.LogWarning((object)"Player has no hammer in inventory! Cannot place blueprint."); return false; } ObjectDB instance = ObjectDB.instance; GameObject val3 = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val3 == (Object)null) { return false; } PieceTable val4 = val3.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val4 == (Object)null) { return false; } List<GameObject> list = new List<GameObject>(val4.m_pieces); if (list.Count < 10) { Plugin.Log.LogError((object)$"StartPlacement aborting: hammer piece table has only {list.Count} pieces — refusing to corrupt it further."); MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)2, "<color=#ff4444>Hammer piece table appears corrupted — cannot start blueprint.</color>", 0, (Sprite)null, false); } return false; } ActiveBlueprint = value2; ActiveBlueprintItem = blueprintItem; if (OriginalHammerPieces == null || OriginalHammerPieces.Count < 10) { OriginalHammerPieces = list; } value2.OriginalRequirements = component.m_resources; value2.OriginalCraftingStation = component.m_craftingStation; value2.OriginalCategory = component.m_category; component.m_resources = (Requirement[])(object)new Requirement[0]; component.m_craftingStation = null; component.m_category = (PieceCategory)0; val4.m_pieces.Clear(); val4.m_pieces.Add(val); try { MethodInfo method = typeof(PieceTable).GetMethod("UpdateAvailable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 4) { method.Invoke(val4, new object[4] { new HashSet<string>(), player, true, false }); } else if (parameters.Length == 3) { method.Invoke(val4, new object[3] { new HashSet<string>(), player, true }); } } } catch { } ((Humanoid)player).EquipItem(val2, true); player.SetSelectedPiece(new Vector2Int(0, 0)); ((MonoBehaviour)player).StartCoroutine(ForceSelectPieceDelayed(player, val)); return true; } [IteratorStateMachine(typeof(<ForceSelectPieceDelayed>d__28))] private static IEnumerator ForceSelectPieceDelayed(Player player, GameObject piecePrefab) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ForceSelectPieceDelayed>d__28(0) { player = player }; } public static void OnPlacementSuccess(Player player) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (!HasActiveBlueprint) { return; } if (ActiveBlueprintItem != null) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null) { if (ActiveBlueprintItem.m_stack > 1) { ItemData activeBlueprintItem = ActiveBlueprintItem; activeBlueprintItem.m_stack--; } else { inventory.RemoveItem(ActiveBlueprintItem); } } } LastBlueprintUseTime = Time.time; RestoreAndClear(); try { RemoveBlueprintedPiecesFromHammer(); FieldInfo field = typeof(Player).GetField("m_lastSelectedPiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(player, (object)new Vector2Int(-1, -1)); } MethodInfo method = typeof(Player).GetMethod("SetPlaceMode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(player, new object[1]); } } catch { } ((MonoBehaviour)player).StartCoroutine(UnequipHammerDelayed(player)); } public static void OnPlacementCancelled() { if (HasActiveBlueprint) { RestoreAndClear(); } } private static void RestoreAndClear() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (ActiveBlueprint != null) { GameObject piecePrefab = ActiveBlueprint.PiecePrefab; Piece val = ((piecePrefab != null) ? piecePrefab.GetComponent<Piece>() : null); if ((Object)(object)val != (Object)null) { val.m_resources = ActiveBlueprint.OriginalRequirements; val.m_craftingStation = ActiveBlueprint.OriginalCraftingStation; val.m_category = ActiveBlueprint.OriginalCategory; } } if (OriginalHammerPieces != null) { ObjectDB instance = ObjectDB.instance; GameObject val2 = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val2 != (Object)null) { PieceTable val3 = val2.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val3 != (Object)null) { val3.m_pieces.Clear(); val3.m_pieces.AddRange(OriginalHammerPieces); } } } ClearState(); try { Hud instance2 = Hud.instance; if ((Object)(object)instance2 != (Object)null) { FieldInfo field = typeof(Hud).GetField("m_lastPieceCategory", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { field.SetValue(instance2, (object)(PieceCategory)(-1)); } } } catch { } } private static void ClearState() { ActiveBlueprint = null; ActiveBlueprintItem = null; OriginalHammerPieces = null; } private static ItemData FindHammerInInventory(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return null; } foreach (ItemData allItem in inventory.GetAllItems()) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "Hammer") { return allItem; } if (allItem.m_shared?.m_name == "$item_hammer") { return allItem; } } return null; } [IteratorStateMachine(typeof(<UnequipHammerDelayed>d__36))] private static IEnumerator UnequipHammerDelayed(Player player) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UnequipHammerDelayed>d__36(0) { player = player }; } public static Sprite GetCachedHammerIcon() { if ((Object)(object)_cachedHammerIcon != (Object)null) { return _cachedHammerIcon; } try { ObjectDB instance = ObjectDB.instance; GameObject obj = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); Sprite[] array = ((obj != null) ? obj.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_icons; if (array != null && array.Length != 0) { _cachedHammerIcon = array[0]; } } catch { } return _cachedHammerIcon; } public static Sprite GetOrCreateFallbackIcon() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_fallbackParchmentIcon != (Object)null) { return _fallbackParchmentIcon; } try { int num = 64; Texture2D val = new Texture2D(num, num, (TextureFormat)5, false) { filterMode = (FilterMode)1, hideFlags = (HideFlags)61 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.78f, 0.66f, 0.45f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.62f, 0.5f, 0.32f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.55f, 0.35f, 0.15f, 1f); int num2 = 3; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { if (i < num2 || i >= num - num2 || j < num2 || j >= num - num2) { val.SetPixel(i, j, val4); continue; } bool flag = (i + j) % 9 == 0 || (i * 3 + j * 5) % 17 == 0; val.SetPixel(i, j, flag ? val3 : val2); } } Color val5 = default(Color); ((Color)(ref val5))..ctor(0.3f, 0.2f, 0.1f, 1f); int num3 = num / 2; int num4 = num / 2; for (int k = -10; k <= 10; k++) { val.SetPixel(num3 + k, num4, val5); } for (int l = -8; l <= 8; l++) { val.SetPixel(num3, num4 + l, val5); } for (int m = -6; m <= 6; m++) { val.SetPixel(num3 - 12 + m, num4 + m, val5); val.SetPixel(num3 + 12 - m, num4 + m, val5); } val.Apply(); _fallbackParchmentIcon = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fallback icon creation failed: " + ex.Message)); } return _fallbackParchmentIcon; } private static Sprite CreateBorderedIcon(Sprite original) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)original == (Object)null || (Object)(object)original.texture == (Object)null) { return null; } try { Texture2D texture = original.texture; Rect rect = original.rect; int num = (int)((Rect)(ref rect)).width; rect = original.rect; int num2 = (int)((Rect)(ref rect)).height; rect = original.rect; int num3 = (int)((Rect)(ref rect)).x; rect = original.rect; int num4 = (int)((Rect)(ref rect)).y; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)texture, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(num, num2, (TextureFormat)5, false) { filterMode = (FilterMode)1, hideFlags = (HideFlags)61 }; val.ReadPixels(new Rect((float)num3, (float)num4, (float)num, (float)num2), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.55f, 0.35f, 0.15f, 1f); int num5 = 3; for (int i = 0; i < num; i++) { for (int j = 0; j < num2; j++) { if (i < num5 || i >= num - num5 || j < num5 || j >= num2 - num5) { val.SetPixel(i, j, val2); } } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to create bordered icon: " + ex.Message)); return null; } } } [HarmonyPatch] public static class BlueprintPatches { private static bool _hasScanned; [HarmonyPatch(typeof(Player), "AddKnownPiece")] [HarmonyPrefix] public static bool AddKnownPiece_BlockModded(Piece piece) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if ((Object)(object)piece == (Object)null) { return true; } if ((int)piece.m_category > 4 && (int)piece.m_category < 100) { return false; } string key = "ABP_" + ((Object)((Component)piece).gameObject).name; if (BlueprintManager.Blueprints.ContainsKey(key)) { return false; } return true; } [HarmonyPatch(typeof(Player), "OnSpawned")] [HarmonyPostfix] public static void Player_OnSpawned_StripKnown(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } try { typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.NonPublic); BlueprintManager.RemoveModdedCategoriesFromHammer(); if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RemoveBlueprintedPiecesFromHammer(); } } catch { } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] [HarmonyPrefix] public static bool EquipItem_BlockHammerRecent(Humanoid __instance, ItemData item) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (item == null) { return true; } if (!(item.m_shared?.m_name == "$item_hammer") && (!((Object)(object)item.m_dropPrefab != (Object)null) || !(((Object)item.m_dropPrefab).name == "Hammer"))) { return true; } if (BlueprintManager.HasActiveBlueprint) { return true; } if (Time.time - BlueprintManager.LastBlueprintUseTime < 1.5f) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "<color=#b5651d>Hammer cooling down after blueprint use...</color>", 0, (Sprite)null, false); } return false; } return true; } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPostfix] public static void ObjectDB_Awake(ObjectDB __instance) { if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RegisterInObjectDB(__instance); BlueprintManager.RegisterLocalization(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPostfix] public static void ObjectDB_CopyOtherDB(ObjectDB __instance) { if (BlueprintManager.Blueprints.Count == 0) { BlueprintManager.RestoreFromCache(); } if (!_hasScanned) { BlueprintManager.ScanAndCreateBlueprints(); if (BlueprintManager.Blueprints.Count > 0) { _hasScanned = true; } } if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RegisterInObjectDB(__instance); BlueprintManager.RegisterLocalization(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPostfix] public static void ZNetScene_Awake(ZNetScene __instance) { if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RegisterInZNetScene(__instance); } } [HarmonyPatch(typeof(Player), "OnSpawned")] [HarmonyPostfix] public static void Player_OnSpawned(Player __instance) { if (!_hasScanned) { BlueprintManager.ScanAndCreateBlueprints(); if (BlueprintManager.Blueprints.Count > 0) { _hasScanned = true; } } Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory != null) { foreach (ItemData allItem in inventory.GetAllItems()) { BlueprintManager.FixDropPrefab(allItem); } } BlueprintManager.RefreshAllInventoryIcons(); } [HarmonyPatch(typeof(Inventory), "Load")] [HarmonyPostfix] public static void Inventory_Load(Inventory __instance) { foreach (ItemData allItem in __instance.GetAllItems()) { BlueprintManager.FixDropPrefab(allItem); } } [HarmonyPatch(typeof(Humanoid), "DropItem")] [HarmonyPrefix] public static void DropItem_Fix(ItemData item) { BlueprintManager.FixDropPrefab(item); } [HarmonyPatch(typeof(Player), "AutoPickup")] [HarmonyPrefix] public static void AutoPickup_Fix(Player __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } try { Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, __instance.m_autoPickupRange, LayerMask.GetMask(new string[1] { "item" })); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null)) { ItemDrop componentInParent = ((Component)val).GetComponentInParent<ItemDrop>(); if (componentInParent?.m_itemData != null) { BlueprintManager.FixDropPrefab(componentInParent.m_itemData); } } } } catch { } } [HarmonyPatch(typeof(Humanoid), "UseItem")] [HarmonyPrefix] public static bool UseItem_Prefix(Humanoid __instance, ItemData item) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (item?.m_shared == null) { return true; } if (!(item.m_shared.m_name ?? "").StartsWith("$ABP_")) { return true; } if (!BlueprintManager.StartPlacement((Player)(object)((__instance is Player) ? __instance : null), item)) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "<color=#ff4444>Cannot use blueprint — need a Hammer in inventory!</color>", 0, (Sprite)null, false); } } return false; } [HarmonyPatch(typeof(Hud), "TogglePieceSelection")] [HarmonyPostfix] public static void Hud_TogglePieceSelection() { BlueprintManager.ScanAndCreateBlueprints(); BlueprintManager.RemoveModdedCategoriesFromHammer(); if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RemoveBlueprintedPiecesFromHammer(); } } [HarmonyPatch(typeof(InventoryGui), "Show")] [HarmonyPostfix] public static void InventoryGui_Show_Postfix() { BlueprintManager.ScanAndCreateBlueprints(); BlueprintManager.RefreshAllInventoryIcons(); } [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] [HarmonyPostfix] public static void InventoryGui_UpdateCraftingPanel_Postfix() { BlueprintManager.RefreshAllInventoryIcons(); } [HarmonyPatch(typeof(Hud), "UpdatePieceList")] [HarmonyPostfix] public static void Hud_UpdatePieceList_Postfix(Hud __instance) { BlueprintManager.RemoveModdedCategoriesFromHammer(); if (BlueprintManager.Blueprints.Count > 0) { BlueprintManager.RemoveBlueprintedPiecesFromHammer(); } HideModdedCategoryTabs(__instance); } private static void HideModdedCategoryTabs(Hud hud) { if ((Object)(object)hud == (Object)null) { return; } try { FieldInfo field = typeof(Hud).GetField("m_pieceCategoryTabs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return; } object value = field.GetValue(hud); if (value == null) { return; } if (value is GameObject[] array) { for (int i = 5; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { array[i].SetActive(false); } } } else if (value is IList list) { for (int j = 5; j < list.Count; j++) { object obj = list[j]; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null) { val.SetActive(false); continue; } Component val2 = (Component)((obj is Component) ? obj : null); if (val2 != null) { val2.gameObject.SetActive(false); } } } FieldInfo field2 = typeof(Hud).GetField("m_pieceCategoryRoot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field2 != null)) { return; } object value2 = field2.GetValue(hud); Transform val3 = null; GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null); if (val4 != null) { val3 = val4.transform; } else { Transform val5 = (Transform)((value2 is Transform) ? value2 : null); if (val5 != null) { val3 = val5; } } if (!((Object)(object)val3 != (Object)null)) { return; } for (int k = 5; k < val3.childCount; k++) { Transform child = val3.GetChild(k); if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeSelf) { ((Component)child).gameObject.SetActive(false); } } } catch { } } [HarmonyPatch(typeof(Piece), "SetCreator")] [HarmonyFinalizer] public static Exception SetCreator_Finalizer(Exception __exception) { if (__exception is NullReferenceException && BlueprintManager.HasActiveBlueprint) { return null; } return __exception; } [HarmonyPatch(typeof(Player), "PlacePiece")] [HarmonyPostfix] public static void PlacePiece_Postfix(Player __instance, Piece piece) { if (!BlueprintManager.HasActiveBlueprint || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } BlueprintInfo activeBlueprint = BlueprintManager.ActiveBlueprint; object obj; if (activeBlueprint == null) { obj = null; } else { GameObject piecePrefab = activeBlueprint.PiecePrefab; obj = ((piecePrefab != null) ? piecePrefab.GetComponent<Piece>() : null); } Piece val = (Piece)obj; if ((Object)(object)val == (Object)null || (Object)(object)piece != (Object)(object)val) { BlueprintManager.OnPlacementCancelled(); return; } BlueprintManager.OnPlacementSuccess(__instance); MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, "<color=#b5651d>Blueprint used!</color>", 0, (Sprite)null, false); } } [HarmonyPatch(typeof(Player), "SetPlaceMode")] [HarmonyPostfix] public static void SetPlaceMode_Postfix(Player __instance, PieceTable buildPieces) { if (!((Object)(object)buildPieces != (Object)null) && BlueprintManager.HasActiveBlueprint) { BlueprintManager.OnPlacementCancelled(); } } [HarmonyPatch(typeof(Player), "Update")] [HarmonyPostfix] public static void Player_Update_Postfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !BlueprintManager.HasActiveBlueprint) { return; } ItemData val = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem").Invoke((Humanoid)(object)__instance); if (val == null || (!(val.m_shared?.m_name == "$item_hammer") && (!((Object)(object)val.m_dropPrefab != (Object)null) || !(((Object)val.m_dropPrefab).name == "Hammer")))) { BlueprintManager.OnPlacementCancelled(); return; } PieceTable val2 = val.m_shared?.m_buildPieces; if ((Object)(object)val2 != (Object)null) { GameObject val3 = BlueprintManager.ActiveBlueprint?.PiecePrefab; if (val2.m_pieces.Count != 1 || !((Object)(object)val3 != (Object)null) || !((Object)(object)val2.m_pieces[0] == (Object)(object)val3)) { BlueprintManager.OnPlacementCancelled(); } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] [HarmonyPrefix] public static bool HaveRequirements_Prefix(Piece piece, ref bool __result) { if (!BlueprintManager.HasActiveBlueprint) { return true; } BlueprintInfo activeBlueprint = BlueprintManager.ActiveBlueprint; object obj; if (activeBlueprint == null) { obj = null; } else { GameObject piecePrefab = activeBlueprint.PiecePrefab; obj = ((piecePrefab != null) ? piecePrefab.GetComponent<Piece>() : null); } Piece val = (Piece)obj; if ((Object)(object)val == (Object)null || (Object)(object)piece != (Object)(object)val) { return true; } __result = true; return false; } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] [HarmonyPrefix] public static bool CheckCanRemovePiece_Prefix() { return true; } } [BepInPlugin("aurora.blueprints", "Aurora Blueprints", "1.0.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "aurora.blueprints"; public const string PluginName = "Aurora Blueprints"; public const string PluginVersion = "1.0.0"; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> MobDropChance; public static ConfigEntry<float> BossDropChance; public static ConfigEntry<string> ExcludePrefabs; private static readonly string[] _vanillaPieceArray = new string[316] { "piece_repair", "wood_stack", "wood_fine_stack", "wood_core_stack", "wood_yggdrasil_stack", "blackwood_stack", "stone_pile", "coal_pile", "blackmarble_pile", "grausten_pile", "skull_pile", "bone_stack", "fire_pit", "fire_pit_iron", "bonfire", "hearth", "portal_wood", "portal_stone", "guard_stone", "Cart", "Raft", "Karve", "VikingShip", "VikingShip_Ashlands", "BatteringRam", "Catapult", "piece_shieldgenerator", "piece_ArcheryTarget", "piece_TrainingDummy", "Placeable_HardRock", "piece_asksvinskeleton", "piece_beehive", "piece_sapcollector", "incinerator", "piece_wisplure", "piece_cartographytable", "piece_bathtub", "piece_barber", "fermenter", "piece_turret", "piece_trap_troll", "piece_gift1", "piece_gift2", "piece_gift3", "piece_xmastree", "piece_xmasgarland", "piece_xmascrown", "piece_mistletoe", "piece_jackoturnip", "piece_maypole", "piece_CelebrationGarland", "piece_FairylightGarland", "wood_wall_quarter", "wood_wall_half", "woodwall", "wood_wall_roof", "wood_wall_roof_upsidedown", "wood_wall_roof_top", "wood_wall_roof_45", "wood_wall_roof_45_upsidedown", "wood_wall_roof_top_45", "wood_window", "wood_floor_1x1", "wood_floor", "wood_stair", "wood_stepladder", "wood_roof", "wood_roof_top", "wood_roof_ocorner", "wood_roof_icorner", "wood_roof_45", "wood_roof_top_45", "wood_roof_ocorner_45", "wood_roof_icorner_45", "wood_pole", "wood_pole2", "wood_beam_1", "wood_beam", "wood_beam_26", "wood_beam_45", "wood_door", "wood_gate", "wood_dragon1", "wood_fence", "stake_wall", "piece_sharpstakes", "wood_pole_log", "wood_pole_log_4", "wood_wall_log", "wood_wall_log_4x0.5", "wood_log_26", "wood_log_45", "darkwood_roof", "darkwood_roof_top", "darkwood_roof_ocorner", "darkwood_roof_icorner", "darkwood_roof_45", "darkwood_roof_top_45", "darkwood_roof_ocorner_45", "darkwood_roof_icorner_45", "darkwood_pole", "darkwood_pole4", "darkwood_beam", "darkwood_beam_26", "darkwood_beam_45", "darkwood_beam4x4", "darkwood_gate", "darkwood_decowall", "darkwood_arch", "darkwood_raven", "darkwood_wolf", "piece_dvergr_stake_wall", "piece_dvergr_sharpstakes", "piece_dvergr_spiralstair", "piece_dvergr_spiralstair_right", "piece_hexagonal_door", "iron_floor_1x1_v2", "iron_floor_2x2", "iron_wall_1x1", "iron_wall_2x2", "piece_dvergr_metal_wall_2x2", "woodiron_pole", "woodiron_beam", "woodiron_beam_26", "woodiron_beam_45", "iron_grate", "crystal_wall_1x1", "ashwood_wall_2x2", "ashwood_halfwall_1x2", "ashwood_quarterwall_1x1", "ashwood_wall_arch", "ashwood_decowall_2x2", "ashwood_decowall_tree", "ashwood_decowall_divider", "ashwood_floor_2x2", "ashwood_floor_1x1", "ashwood_deco_floor", "ashwood_arch_big", "ashwood_beam_1m", "ashwood_beam_2m", "ashwood_pole_1m", "ashwood_pole_2m", "ashwood_wall_beam_26", "ashwood_wall_cross_26", "ashwood_wall_beam_45", "ashwood_wall_cross_45", "ashwood_wall_roof_26", "ashwood_wall_roof_26_upsidedown", "ashwood_wall_roof_45", "ashwood_wall_roof_45_upsidedown", "ashwood_stair", "ashwood_door", "piece_stakewall_blackwood", "stone_wall_1x1", "stone_wall_2x1", "stone_wall_4x2", "stone_pillar", "stone_arch", "stone_floor_2x2", "stone_stair", "blackmarble_1x1", "blackmarble_2x1x1", "blackmarble_2x2x2", "blackmarble_floor", "blackmarble_floor_triangle", "blackmarble_stair", "blackmarble_tip", "blackmarble_base_1", "blackmarble_basecorner", "blackmarble_out_1", "blackmarble_outcorner", "blackmarble_arch", "blackmarble_column_1", "blackmarble_column_2", "Piece_grausten_stone_ladder", "piece_grausten_stonestair", "Piece_grausten_floor_1x1", "Piece_grausten_floor_2x2", "Piece_grausten_floor_4x4", "Piece_grausten_pillarbase_small", "Piece_grausten_pillarbase_medium", "Piece_grausten_pillarbase_tapered", "Piece_grausten_pillarbase_tapered_inverted", "Piece_grausten_pillarbeam_small", "Piece_grausten_pillarbeam_medium", "Piece_grausten_pillar_arch_small", "Piece_grausten_pillar_arch", "Piece_grausten_wall_arch", "Piece_grausten_wall_arch_inverted", "Piece_grausten_wall_1x2", "Piece_grausten_wall_2x2", "Piece_grausten_wall_4x2", "Piece_grausten_window_2x2", "Piece_grausten_window_4x2", "piece_grausten_roof_45", "piece_grausten_roof_45_corner", "piece_grausten_roof_45_corner2", "piece_grausten_roof_45_arch", "piece_grausten_roof_45_arch_corner", "piece_grausten_roof_45_arch_corner2", "flametal_gate", "Piece_flametal_pillar", "Piece_flametal_beam", "raise", "paved_road", "mud_road", "bed", "piece_bed02", "ashwood_bed", "piece_chest_wood", "piece_chest", "piece_chest_private", "piece_chest_blackmetal", "piece_chest_barrel", "piece_chest_treasure", "treasure_pile", "treasure_stack", "piece_chair", "piece_chair02", "piece_chair03", "piece_bench01", "piece_logbench01", "piece_blackmarble_bench", "piece_blackwood_bench01", "piece_throne01", "piece_throne02", "piece_blackmarble_throne", "piece_bone_throne", "piece_table", "piece_table_round", "piece_table_oak", "piece_blackmarble_table", "piece_walltorch", "piece_groundtorch", "piece_groundtorch_wood", "piece_groundtorch_green", "piece_groundtorch_blue", "piece_groundtorch_mist", "piece_brazierfloor01", "piece_brazierfloor02", "piece_brazierceiling01", "Candle_resin", "piece_Lavalantern", "piece_dvergr_lantern", "piece_dvergr_lantern_pole", "itemstand", "itemstandh", "ArmorStand", "sign", "rug_Bjorn", "rug_wolf", "rug_deer", "rug_fur", "rug_hare", "rug_asksvin", "rug_straw", "jute_carpet", "jute_carpet_blue", "piece_banner01", "piece_banner02", "piece_banner03", "piece_banner04", "piece_banner05", "piece_banner06", "piece_banner07", "piece_banner08", "piece_banner09", "piece_banner10", "piece_banner11", "piece_cloth_hanging_door", "piece_cloth_hanging_door_blue", "piece_cloth_hanging_door_blue2", "piece_pot1", "piece_pot2", "piece_pot3", "piece_workbench", "piece_workbench_ext1", "piece_workbench_ext2", "piece_workbench_ext3", "piece_workbench_ext4", "forge", "forge_ext1", "forge_ext2", "forge_ext3", "forge_ext4", "forge_ext5", "forge_ext6", "piece_cookingstation", "piece_cookingstation_iron", "piece_cauldron", "cauldron_ext1_spice", "cauldron_ext3_butchertable", "cauldron_ext4_pots", "cauldron_ext5_mortarandpestle", "cauldron_ext6_rollingpins", "piece_oven", "piece_preptable", "piece_MeadCauldron", "smelter", "blastfurnace", "charcoal_kiln", "windmill", "piece_spinningwheel", "eitrrefinery", "piece_artisanstation", "artisan_ext1", "blackforge", "blackforge_ext1", "blackforge_ext2_vise", "blackforge_ext3_metalcutter", "blackforge_ext4_gemcutter", "piece_stonecutter", "piece_magetable", "piece_magetable_ext", "piece_magetable_ext2", "piece_magetable_ext3" }; public static readonly HashSet<string> VanillaPieceNames = new HashSet<string>(_vanillaPieceArray, StringComparer.OrdinalIgnoreCase); private Harmony _harmony; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; if (ServerGuard.Init(this)) { Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for the mod."); ExcludePrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExcludePrefabs", "piece_aurora_sacrificial_altar,woodfrozen_beam*", "Comma-separated prefab names that should NEVER be converted to blueprints, even if modded. Use trailing * for prefix match (e.g., 'woodfrozen_beam*' matches woodfrozen_beam, woodfrozen_beam2, etc.). Use leading * for suffix match (e.g., '*_bench' matches iron_bench, wood_bench, etc.)."); MobDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Drops", "MobDropChance", 1f, "Percent chance (0-100) for a regular monster to drop a random blueprint on death."); BossDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Drops", "BossDropChance", 10f, "Percent chance (0-100) for a boss to drop a random blueprint on death."); if (!Enabled.Value) { Log.LogInfo((object)"AuroraBlueprints disabled via config."); return; } _harmony = new Harmony("aurora.blueprints"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"Aurora Blueprints v1.0.0 loaded."); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public static class ServerGuard { private const string PasswordHash = "e7aab22a4200ed38c615552e666633ba96140d314df8e1c00d08b886527a1dd4"; private const string ConfigSection = "Protection"; private const string ConfigKey = "password"; private static ConfigEntry<string> _cfgPassword; public static bool Init(Plugin plugin) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 _cfgPassword = ((BaseUnityPlugin)plugin).Config.Bind<string>("Protection", "password", "enter_password_here", "Server password required to run Aurora Blueprints on a dedicated server. Leave as-is on game clients — this check is ignored there."); if ((int)SystemInfo.graphicsDeviceType != 4) { Plugin.Log.LogInfo((object)"[ServerGuard] Running on client - auth skipped"); return true; } if (HashPassword(_cfgPassword.Value?.Trim() ?? string.Empty) == "e7aab22a4200ed38c615552e666633ba96140d314df8e1c00d08b886527a1dd4") { Plugin.Log.Log