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