Please disclose if your mod was created primarily 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.0.7
plugins/AuroraBlueprints.dll
Decompiled 16 minutes agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("aurora")] [assembly: AssemblyConfiguration("Debug")] [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 { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__9_0; internal void <AddCommands>b__9_0(ConsoleEventArgs args) { //IL_0051: 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."); } } 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_00d0: 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)) { SpawnRandomBlueprint(((Component)__instance).transform.position, prefabName); } } } public static void SpawnRandomBlueprint(Vector3 position, string sourceName = "admin") { //IL_0065: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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 { GameObject val2 = Object.Instantiate<GameObject>(blueprintInfo.BlueprintPrefab, val, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ItemDrop component = val2.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { component.m_itemData.m_stack = 1; component.m_itemData.m_dropPrefab = blueprintInfo.BlueprintPrefab; } val2.SetActive(true); string displayName = blueprintInfo.DisplayName; BroadcastAnnouncement("<color=#b5651d>A Blueprint: " + displayName + " has dropped!</color>"); Plugin.Log.LogInfo((object)("BlueprintDrop: " + sourceName + " dropped " + text)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("BlueprintDrop: Failed to drop " + text + ": " + ex.Message)); } } [HarmonyPatch(typeof(ZRoutedRpc), "SetUID")] [HarmonyPostfix] public static void ZRoutedRpc_SetUID() { TryRegisterRPC(); } [HarmonyPatch(typeof(Terminal), "InitTerminal")] [HarmonyPostfix] public static void AddCommands() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown object obj = <>c.<>9__9_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0051: 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__9_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 class BlueprintInfo { public GameObject PiecePrefab; public string OriginalPieceName; public string DisplayName; public Requirement[] OriginalRequirements; public CraftingStation OriginalCraftingStation; public GameObject BlueprintPrefab; } public static class BlueprintManager { [CompilerGenerated] private sealed class <UnequipHammerDelayed>d__26 : 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__26(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 HashSet<string> _vanillaPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly List<GameObject> _removedPieces = new List<GameObject>(); public static BlueprintInfo ActiveBlueprint; public static ItemData ActiveBlueprintItem; public static List<GameObject> OriginalHammerPieces; public static bool HasActiveBlueprint => ActiveBlueprint != null; public static void CaptureVanillaPrefabs(ZNetScene zNetScene) { if (_vanillaPrefabs.Count > 0) { return; } foreach (GameObject prefab in zNetScene.m_prefabs) { if ((Object)(object)prefab != (Object)null) { _vanillaPrefabs.Add(((Object)prefab).name); } } Plugin.Log.LogInfo((object)$"[VanillaCapture] Captured {_vanillaPrefabs.Count} vanilla prefab names."); } public static void ScanAndCreateBlueprints() { //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Invalid comparison between Unknown and I4 //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected I4, but got Unknown if (_scanned || (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; HashSet<string> hashSet = 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 || hashSet.Contains(((Object)piece).name)) { continue; } string name = Enum.GetName(typeof(PieceCategory), component2.m_category); int num = (int)component2.m_category; if (name == "Crafting" || num == 1) { continue; } bool flag; if (_vanillaPrefabs.Count > 0) { flag = _vanillaPrefabs.Contains(((Object)piece).name); } else { int num2; switch (name) { default: num2 = ((name == "Max") ? 1 : 0); break; case "Misc": case "Crafting": case "BuildingWorkbench": case "BuildingStonecutter": case "Furniture": case "All": case "ComfortGroup": num2 = 1; break; case null: num2 = 0; break; } bool flag2 = (byte)num2 != 0; flag = flag2; } if (flag || 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")) { continue; } StationExtension component3 = piece.GetComponent<StationExtension>(); if ((Object)(object)component3 != (Object)null) { continue; } Collider[] componentsInChildren = piece.GetComponentsInChildren<Collider>(true); if (componentsInChildren != null && componentsInChildren.Length != 0) { string text3 = "ABP_" + ((Object)piece).name; if (!Blueprints.ContainsKey(text3)) { BlueprintInfo obj = new BlueprintInfo { PiecePrefab = piece, OriginalPieceName = ((Object)piece).name }; Localization instance = Localization.instance; obj.DisplayName = ((instance != null) ? instance.Localize(component2.m_name) : null) ?? component2.m_name; obj.OriginalRequirements = component2.m_resources; obj.OriginalCraftingStation = component2.m_craftingStation; BlueprintInfo blueprintInfo = obj; Plugin.Log.LogInfo((object)("[SCAN] Blueprinting: " + ((Object)piece).name + " (category=" + (name ?? ("custom_" + num)) + ", display=" + blueprintInfo.DisplayName + ")")); CreateBlueprintItem(blueprintInfo, text3, itemPrefab); list.Add(piece); } } } if ((int)SystemInfo.graphicsDeviceType != 4) { foreach (GameObject item in list) { buildPieces.m_pieces.Remove(item); _removedPieces.Add(item); } } _scanned = true; if (Blueprints.Count > 0) { Plugin.Log.LogInfo((object)$"Created {Blueprints.Count} blueprints from custom-category pieces."); RegisterAll(); } else { Plugin.Log.LogInfo((object)"No custom-category pieces found in hammer."); } } private static HashSet<string> BuildExcludeSet() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); string text = Plugin.ExcludePrefabs?.Value ?? ""; string[] array = text.Split(new char[1] { ',' }); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length > 0) { hashSet.Add(text3); } } return hashSet; } private static void CreateBlueprintItem(BlueprintInfo info, string bpName, GameObject hammerPrefab) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Invalid comparison between Unknown and I4 //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown //IL_01a1: 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 flag = (int)SystemInfo.graphicsDeviceType == 4; Piece component2 = info.PiecePrefab.GetComponent<Piece>(); if (!flag && (Object)(object)component2 != (Object)null && (Object)(object)component2.m_icon != (Object)null) { Sprite val2 = CreateBorderedIcon(component2.m_icon); shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 ?? component2.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 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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 ((Object)(object)value2.PiecePrefab == (Object)null) { return false; } ActiveBlueprint = value2; ActiveBlueprintItem = blueprintItem; ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("Hammer") : null); if ((Object)(object)val == (Object)null) { ClearState(); return false; } PieceTable val2 = val.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val2 == (Object)null) { ClearState(); return false; } OriginalHammerPieces = new List<GameObject>(val2.m_pieces); Piece component = value2.PiecePrefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_resources = (Requirement[])(object)new Requirement[0]; component.m_craftingStation = null; } val2.m_pieces.Clear(); val2.m_pieces.Add(value2.PiecePrefab); if ((Object)(object)component != (Object)null) { component.m_category = (PieceCategory)0; } ItemData val3 = FindHammerInInventory(player); if (val3 != null) { ((Humanoid)player).EquipItem(val3, true); player.SetSelectedPiece(new Vector2Int(0, 0)); return true; } Plugin.Log.LogWarning((object)"Player has no hammer in inventory! Cannot place blueprint."); ClearState(); return false; } public static void OnPlacementSuccess(Player player) { 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); } } } RestoreAndClear(); ((MonoBehaviour)player).StartCoroutine(UnequipHammerDelayed(player)); } public static void OnPlacementCancelled() { if (HasActiveBlueprint) { RestoreAndClear(); } } private static void RestoreAndClear() { 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; } } 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(); } 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__26))] private static IEnumerator UnequipHammerDelayed(Player player) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UnequipHammerDelayed>d__26(0) { player = player }; } private static Sprite CreateBorderedIcon(Sprite original) { //IL_002e: 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_003f: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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(ZNetScene), "Awake")] [HarmonyPrefix] public static void ZNetScene_Awake_Prefix(ZNetScene __instance) { if (__instance?.m_prefabs != null) { BlueprintManager.CaptureVanillaPrefabs(__instance); } } [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.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) { _hasScanned = true; BlueprintManager.ScanAndCreateBlueprints(); } if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { return; } Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory == null) { return; } foreach (ItemData allItem in inventory.GetAllItems()) { BlueprintManager.FixDropPrefab(allItem); } } [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_0019: 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" })); Collider[] array2 = array; foreach (Collider val in array2) { 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(Player), "ConsumeItem")] [HarmonyPrefix] public static bool ConsumeItem_Prefix(Player __instance, ItemData item, ref bool __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (item?.m_shared == null) { return true; } string text = item.m_shared.m_name ?? ""; if (!text.StartsWith("$ABP_")) { return true; } __result = true; if (!BlueprintManager.StartPlacement(__instance, 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(Player), "PlacePiece")] [HarmonyPostfix] public static void PlacePiece_Postfix(Player __instance, Piece piece) { if (BlueprintManager.HasActiveBlueprint && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { 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) { 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(); } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] [HarmonyPrefix] public static bool HaveRequirements_Prefix(ref bool __result) { if (!BlueprintManager.HasActiveBlueprint) { 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[] _unused = new string[52] { "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" }; public static readonly string[] DefaultVanillaBuilding = new string[154] { "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" }; public static readonly string[] DefaultVanillaFurniture = new string[69] { "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" }; private Harmony _harmony; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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", "Comma-separated prefab names that should NEVER be converted to blueprints, even if modded."); 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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; } string input = _cfgPassword.Value?.Trim() ?? string.Empty; if (HashPassword(input) == "e7aab22a4200ed38c615552e666633ba96140d314df8e1c00d08b886527a1dd4") { Plugin.Log.LogInfo((object)"[ServerGuard] Server auth OK."); return true; } Plugin.Log.LogError((object)"══════════════════════════════════════════════════\n INVALID PASSWORD — Aurora Blueprints will not load.\n Set the correct password in:\n BepInEx/config/aurora.blueprints.cfg\n under [Protection] > password\n══════════════════════════════════════════════════"); return false; } private static string HashPassword(string input) { using SHA256 sHA = SHA256.Create(); byte[] bytes = Encoding.UTF8.GetBytes(input); byte[] array = sHA.ComputeHash(bytes); StringBuilder stringBuilder = new StringBuilder(64); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } } }