Decompiled source of CozyHearth v0.1.0

CozyHearth.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GoblinStudio")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Warm, rustic decoration pieces for Valheim.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("CozyHearth")]
[assembly: AssemblyTitle("CozyHearth")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 GoblinStudio.CozyHearth
{
	[BepInPlugin("GoblinStudio.CozyHearth", "Cozy Hearth", "0.1.0")]
	public sealed class CozyHearthPlugin : BaseUnityPlugin
	{
		private enum ObjectDbLifecycle
		{
			Awake,
			CopyOtherDB
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class ZNetSceneAwakePatch
		{
			[HarmonyPrefix]
			private static void Prefix(ZNetScene __instance)
			{
				if (!PrefabValid || (Object)(object)CushionPrefab == (Object)null)
				{
					return;
				}
				try
				{
					RegisterZNetScenePrefab(__instance);
				}
				catch (Exception ex)
				{
					PrefabValid = false;
					ManualLogSource? log = Log;
					if (log != null)
					{
						log.LogError((object)("ZNetScene-Registrierung fail-closed abgebrochen: " + ex.Message));
					}
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDbAwakePatch
		{
			[HarmonyPostfix]
			private static void Postfix(ObjectDB __instance)
			{
				RegisterHammerAndLocalization(__instance, ObjectDbLifecycle.Awake);
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		private static class ObjectDbCopyOtherDbPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ObjectDB __instance)
			{
				RegisterHammerAndLocalization(__instance, ObjectDbLifecycle.CopyOtherDB);
			}
		}

		[HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })]
		private static class PlayerLoadDiscoveryPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Player __instance)
			{
				if (PlayerLoadDiscoveryLogged || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !PrefabValid || (Object)(object)CushionPrefab == (Object)null || (Object)(object)BlanketPrefab == (Object)null || UpdateKnownRecipesListMethod == null)
				{
					return;
				}
				try
				{
					UpdateKnownRecipesListMethod.Invoke(__instance, null);
					PlayerLoadDiscoveryLogged = true;
				}
				catch (Exception ex)
				{
					ManualLogSource? log = Log;
					if (log != null)
					{
						log.LogError((object)("Player.Load Known-Piece-Discovery fail-closed abgebrochen: " + ex.Message));
					}
				}
			}
		}

		public const string PluginId = "GoblinStudio.CozyHearth";

		public const string PluginName = "Cozy Hearth";

		public const string PluginVersion = "0.1.0";

		private const string BundleResourceName = "CozyHearth.assets.goblinstudio_cozyhearth";

		private const string PrefabAssetPath = "Assets/CozyHearth/Prefabs/GoblinStudio_CozyCushion.prefab";

		private const string BlanketPrefabAssetPath = "Assets/CozyHearth/Prefabs/GoblinStudio_FoldedBlanket.prefab";

		private const string PrefabName = "GoblinStudio_CozyCushion";

		private const string BlanketPrefabName = "GoblinStudio_FoldedBlanket";

		private const string PieceName = "$piece_goblinstudio_cozycushion";

		private const string PieceDescription = "$piece_goblinstudio_cozycushion_description";

		private const string BlanketPieceName = "$piece_goblinstudio_foldedblanket";

		private const string BlanketPieceDescription = "$piece_goblinstudio_foldedblanket_description";

		private const string HammerName = "Hammer";

		private const string HammerPieceTableName = "_HammerPieceTable";

		private const string DeerHideName = "DeerHide";

		private const string LeatherScrapsName = "LeatherScraps";

		private static ManualLogSource? Log;

		private static AssetBundle? Bundle;

		private static GameObject? CushionPrefab;

		private static GameObject? BlanketPrefab;

		private static bool LocalizationSubscribed;

		private static bool BundleLoadAttempted;

		private static bool PrefabValid;

		private static bool ObjectDbAwakeNotReadyLogged;

		private static bool PlayerLoadDiscoveryLogged;

		private static MethodInfo? UpdateKnownRecipesListMethod;

		private static bool HammerRegistrationSuccessLogged;

		private void Awake()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			if (!LoadAndValidatePrefab())
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Cozy Hearth wird fail-closed nicht registriert.");
				return;
			}
			RegisterLocalizationIfReady();
			UpdateKnownRecipesListMethod = typeof(Player).GetMethod("UpdateKnownRecipesList", BindingFlags.Instance | BindingFlags.NonPublic);
			if (UpdateKnownRecipesListMethod == null || UpdateKnownRecipesListMethod.GetParameters().Length != 0)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Player.UpdateKnownRecipesList wurde nicht mit der erwarteten Signatur gefunden; Load-Discovery-Fix bleibt fail-closed deaktiviert.");
			}
			new Harmony("GoblinStudio.CozyHearth").PatchAll(typeof(CozyHearthPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Cozy Hearth 0.1.0: Cozy-Cushion-Runtime-Candidate bereit.");
		}

		private static bool LoadAndValidatePrefab()
		{
			if (BundleLoadAttempted)
			{
				return PrefabValid;
			}
			BundleLoadAttempted = true;
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CozyHearth.assets.goblinstudio_cozyhearth");
				if (stream == null || stream.Length <= 0)
				{
					throw new InvalidDataException("EmbeddedResource 'CozyHearth.assets.goblinstudio_cozyhearth' fehlt oder ist leer.");
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						throw new EndOfStreamException("Embedded AssetBundle wurde nicht vollstaendig gelesen.");
					}
				}
				Bundle = AssetBundle.LoadFromMemory(array);
				if ((Object)(object)Bundle == (Object)null)
				{
					throw new InvalidDataException("Embedded AssetBundle konnte nicht geladen werden.");
				}
				CushionPrefab = Bundle.LoadAsset<GameObject>("Assets/CozyHearth/Prefabs/GoblinStudio_CozyCushion.prefab");
				BlanketPrefab = Bundle.LoadAsset<GameObject>("Assets/CozyHearth/Prefabs/GoblinStudio_FoldedBlanket.prefab");
				ValidatePrefab(CushionPrefab);
				ValidateBlanketPrefab(BlanketPrefab);
				PrefabValid = true;
				ManualLogSource? log = Log;
				if (log != null)
				{
					log.LogInfo((object)"Embedded AssetBundle und GoblinStudio_CozyCushion statisch validiert.");
				}
				return true;
			}
			catch (Exception ex)
			{
				PrefabValid = false;
				CushionPrefab = null;
				BlanketPrefab = null;
				if ((Object)(object)Bundle != (Object)null)
				{
					Bundle.Unload(false);
				}
				Bundle = null;
				ManualLogSource? log2 = Log;
				if (log2 != null)
				{
					log2.LogError((object)("AssetBundle-/Prefab-Validierung fehlgeschlagen: " + ex.Message));
				}
				return false;
			}
		}

		private static void ValidateBlanketPrefab(GameObject? prefab)
		{
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Invalid comparison between Unknown and I4
			Require((Object)(object)prefab != (Object)null && ((Object)prefab).name == "GoblinStudio_FoldedBlanket", "Folded-Blanket-Prefabname oder Assetpfad ist ungueltig.");
			Require(prefab.layer == 10, "Folded-Blanket-Root-Layer muss 10 sein.");
			Piece[] componentsInChildren = prefab.GetComponentsInChildren<Piece>(true);
			ZNetView[] componentsInChildren2 = prefab.GetComponentsInChildren<ZNetView>(true);
			BoxCollider[] componentsInChildren3 = prefab.GetComponentsInChildren<BoxCollider>(true);
			Require(componentsInChildren.Length == 1 && (Object)(object)((Component)componentsInChildren[0]).gameObject == (Object)(object)prefab, "Folded Blanket benoetigt exakt eine Root-Piece-Komponente.");
			Require(componentsInChildren2.Length == 1 && (Object)(object)((Component)componentsInChildren2[0]).gameObject == (Object)(object)prefab, "Folded Blanket benoetigt exakt eine Root-ZNetView-Komponente.");
			Require(componentsInChildren3.Length == 1 && !((Collider)componentsInChildren3[0]).isTrigger, "Folded Blanket benoetigt exakt einen nicht-ausloesenden BoxCollider.");
			Require(prefab.GetComponentsInChildren<WearNTear>(true).Length == 0, "Folded Blanket WearNTear ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<Rigidbody>(true).Length == 0, "Folded Blanket Rigidbody ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<ZSyncTransform>(true).Length == 0, "Folded Blanket ZSyncTransform ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<ZSyncAnimation>(true).Length == 0, "Folded Blanket ZSyncAnimation ist nicht erlaubt.");
			Transform val = prefab.transform.Find("Visual");
			Transform val2 = ((val != null) ? val.Find("BlanketMesh") : null);
			Transform val3 = prefab.transform.Find("Collider");
			Require((Object)(object)val != (Object)null && ((Component)val).gameObject.layer == 10, "Folded-Blanket-Visual-Layer muss 10 sein.");
			Require((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.layer == 10, "Folded-Blanket-Mesh-Layer muss 10 sein.");
			Require((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.layer == 16 && (Object)(object)((Component)componentsInChildren3[0]).transform == (Object)(object)val3, "Folded-Blanket-Collider-Layer muss 16 sein.");
			Component[] componentsInChildren4 = prefab.GetComponentsInChildren<Component>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Require((Object)(object)componentsInChildren4[i] != (Object)null, "Folded Blanket Missing Script gefunden.");
			}
			Piece val4 = componentsInChildren[0];
			Require((Object)(object)val4.m_icon != (Object)null, "Folded-Blanket-Piece-Icon fehlt.");
			Require(val4.m_name == "$piece_goblinstudio_foldedblanket", "Folded-Blanket-Piece.m_name ist ungueltig.");
			Require(val4.m_description == "$piece_goblinstudio_foldedblanket_description", "Folded-Blanket-Piece.m_description ist ungueltig.");
			Require((int)val4.m_category == 4, "Folded Blanket Kategorie muss Furniture sein.");
			Require(val4.m_comfort == 0 && val4.m_canRotate && val4.m_canBeRemoved, "Folded Blanket Piece-Werte sind ungueltig.");
			Require((Object)(object)val4.m_craftingStation == (Object)null, "Folded Blanket darf keine Crafting Station verlangen.");
			Require(val4.m_resources != null && val4.m_resources.Length == 0, "Folded-Blanket-Requirements muessen initial leer sein.");
		}

		private static void ValidatePrefab(GameObject? prefab)
		{
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Invalid comparison between Unknown and I4
			Require((Object)(object)prefab != (Object)null && ((Object)prefab).name == "GoblinStudio_CozyCushion", "Prefabname oder Assetpfad ist ungueltig.");
			Require(prefab.layer == 10, "Root-Layer muss 10 sein.");
			Piece[] componentsInChildren = prefab.GetComponentsInChildren<Piece>(true);
			ZNetView[] componentsInChildren2 = prefab.GetComponentsInChildren<ZNetView>(true);
			BoxCollider[] componentsInChildren3 = prefab.GetComponentsInChildren<BoxCollider>(true);
			Require(componentsInChildren.Length == 1 && (Object)(object)((Component)componentsInChildren[0]).gameObject == (Object)(object)prefab, "Exakt eine Root-Piece-Komponente erforderlich.");
			Require(componentsInChildren2.Length == 1 && (Object)(object)((Component)componentsInChildren2[0]).gameObject == (Object)(object)prefab, "Exakt eine Root-ZNetView-Komponente erforderlich.");
			Require(componentsInChildren3.Length == 1 && !((Collider)componentsInChildren3[0]).isTrigger, "Exakt ein nicht-ausloesender BoxCollider erforderlich.");
			Require(prefab.GetComponentsInChildren<WearNTear>(true).Length == 0, "WearNTear ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<Rigidbody>(true).Length == 0, "Rigidbody ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<ZSyncTransform>(true).Length == 0, "ZSyncTransform ist nicht erlaubt.");
			Require(prefab.GetComponentsInChildren<ZSyncAnimation>(true).Length == 0, "ZSyncAnimation ist nicht erlaubt.");
			Transform val = prefab.transform.Find("Visual");
			Transform val2 = ((val != null) ? val.Find("CushionMesh") : null);
			Transform val3 = prefab.transform.Find("Collider");
			Require((Object)(object)val != (Object)null && ((Component)val).gameObject.layer == 10, "Visual-Layer muss 10 sein.");
			Require((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.layer == 10, "CushionMesh-Layer muss 10 sein.");
			Require((Object)(object)val3 != (Object)null && ((Component)val3).gameObject.layer == 16 && (Object)(object)((Component)componentsInChildren3[0]).transform == (Object)(object)val3, "Collider-Layer muss 16 sein.");
			Component[] componentsInChildren4 = prefab.GetComponentsInChildren<Component>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Require((Object)(object)componentsInChildren4[i] != (Object)null, "Missing Script gefunden.");
			}
			Piece val4 = componentsInChildren[0];
			Require((Object)(object)val4.m_icon != (Object)null, "Piece-Icon fehlt.");
			Require(val4.m_name == "$piece_goblinstudio_cozycushion", "Piece.m_name ist ungueltig.");
			Require(val4.m_description == "$piece_goblinstudio_cozycushion_description", "Piece.m_description ist ungueltig.");
			Require((int)val4.m_category == 4, "Piece-Kategorie muss Furniture sein.");
			Require(val4.m_comfort == 0, "Comfort muss 0 sein.");
			Require(val4.m_canRotate, "Piece muss rotierbar sein.");
			Require(val4.m_canBeRemoved, "Piece muss entfernbar sein.");
			Require(val4.m_resources != null && val4.m_resources.Length == 0, "Requirements muessen nicht-null und leer sein.");
		}

		private static void Require(bool condition, string message)
		{
			if (!condition)
			{
				throw new InvalidDataException(message);
			}
		}

		private static void RegisterZNetScenePrefab(ZNetScene scene)
		{
			Require(scene.m_prefabs != null, "ZNetScene.m_prefabs fehlt.");
			Require(scene.m_nonNetViewPrefabs != null, "ZNetScene.m_nonNetViewPrefabs fehlt.");
			RegisterOneZNetScenePrefab(scene, CushionPrefab, "GoblinStudio_CozyCushion", "Cozy Cushion");
			RegisterOneZNetScenePrefab(scene, BlanketPrefab, "GoblinStudio_FoldedBlanket", "Folded Blanket");
		}

		private static void RegisterOneZNetScenePrefab(ZNetScene scene, GameObject prefab, string prefabName, string label)
		{
			int stableHashCode = StringExtensionMethods.GetStableHashCode(prefabName);
			bool exactReferenceFound = false;
			CheckPrefabList(scene.m_prefabs, stableHashCode, netViewList: true, prefab, prefabName, ref exactReferenceFound);
			CheckPrefabList(scene.m_nonNetViewPrefabs, stableHashCode, netViewList: false, prefab, prefabName, ref exactReferenceFound);
			if (exactReferenceFound)
			{
				ManualLogSource? log = Log;
				if (log != null)
				{
					log.LogInfo((object)(label + " ist bereits idempotent in ZNetScene vorhanden."));
				}
				return;
			}
			scene.m_prefabs.Add(prefab);
			ManualLogSource? log2 = Log;
			if (log2 != null)
			{
				log2.LogInfo((object)(label + " vor ZNetScene.Awake genau einmal zu m_prefabs hinzugefuegt."));
			}
		}

		private static void CheckPrefabList(List<GameObject> prefabs, int wantedHash, bool netViewList, GameObject wantedPrefab, string wantedName, ref bool exactReferenceFound)
		{
			foreach (GameObject prefab in prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					bool num = prefab == wantedPrefab;
					bool flag = ((Object)prefab).name == wantedName;
					bool flag2 = StringExtensionMethods.GetStableHashCode(((Object)prefab).name) == wantedHash;
					if (num)
					{
						Require(netViewList, "Das CozyHearth-Prefab steht ungueltig in m_nonNetViewPrefabs.");
						exactReferenceFound = true;
					}
					else if (flag || flag2)
					{
						throw new InvalidDataException("Prefabname-/Stable-Hash-Konflikt mit '" + ((Object)prefab).name + "'.");
					}
				}
			}
		}

		private static void RegisterHammerAndLocalization(ObjectDB? objectDb, ObjectDbLifecycle lifecycle)
		{
			if (!PrefabValid || (Object)(object)CushionPrefab == (Object)null)
			{
				return;
			}
			RegisterLocalizationIfReady();
			if ((Object)(object)objectDb == (Object)null)
			{
				ManualLogSource? log = Log;
				if (log != null)
				{
					log.LogError((object)$"ObjectDB.{lifecycle}: ObjectDB-Instanz fehlt; Hammer-PieceTable-Registrierung fail-closed abgebrochen.");
				}
				return;
			}
			try
			{
				GameObject val = null;
				if (lifecycle == ObjectDbLifecycle.Awake && (Object)(object)((Component)objectDb).gameObject != (Object)null && ((Object)((Component)objectDb).gameObject).name == "StartGui")
				{
					bool num = objectDb.m_items != null && objectDb.m_items.Exists((GameObject item) => (Object)(object)item != (Object)null && ((Object)item).name == "Hammer");
					val = objectDb.GetItemPrefab("Hammer");
					if (!num && (Object)(object)val == (Object)null)
					{
						if (!ObjectDbAwakeNotReadyLogged)
						{
							ObjectDbAwakeNotReadyLogged = true;
							ManualLogSource? log2 = Log;
							if (log2 != null)
							{
								log2.LogInfo((object)"ObjectDB.Awake/StartGui: Vanilla-Daten noch nicht vollstaendig uebernommen; Hammer-PieceTable-Registrierung wird nach CopyOtherDB erneut versucht.");
							}
						}
						return;
					}
				}
				if (val == null)
				{
					val = objectDb.GetItemPrefab("Hammer");
				}
				Require((Object)(object)val != (Object)null, "Vanilla-Hammer fehlt.");
				ItemDrop component = val.GetComponent<ItemDrop>();
				Require((Object)(object)component != (Object)null, "Vanilla-Hammer ItemDrop fehlt.");
				Require(component.m_itemData != null, "Vanilla-Hammer ItemData fehlt.");
				Require(component.m_itemData.m_shared != null, "Vanilla-Hammer SharedData fehlt.");
				PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
				Require((Object)(object)buildPieces != (Object)null, "Vanilla-Hammer PieceTable fehlt.");
				Require(((Object)buildPieces).name == "_HammerPieceTable", "Vanilla-Hammer PieceTable ist nicht '_HammerPieceTable'.");
				Require(buildPieces.m_pieces != null, "Hammer PieceTable.m_pieces fehlt.");
				Piece component2 = CushionPrefab.GetComponent<Piece>();
				Piece component3 = BlanketPrefab.GetComponent<Piece>();
				if (lifecycle == ObjectDbLifecycle.CopyOtherDB)
				{
					ConfigureDeerRequirements(objectDb, component2, 2, 1, "Cozy Cushion");
					ConfigureDeerRequirements(objectDb, component3, 4, 2, "Folded Blanket");
				}
				RequireDeerRequirements(component2, 2, 1, "Cozy Cushion");
				RequireDeerRequirements(component3, 4, 2, "Folded Blanket");
				Require((Object)(object)component2.m_craftingStation == (Object)null && (Object)(object)component3.m_craftingStation == (Object)null, "Cozy Hearth Pieces duerfen keine Crafting Station verlangen.");
				RegisterHammerPiece(buildPieces, CushionPrefab, "GoblinStudio_CozyCushion", "$piece_goblinstudio_cozycushion", "Cozy Cushion");
				RegisterHammerPiece(buildPieces, BlanketPrefab, "GoblinStudio_FoldedBlanket", "$piece_goblinstudio_foldedblanket", "Folded Blanket");
			}
			catch (Exception ex)
			{
				ManualLogSource? log3 = Log;
				if (log3 != null)
				{
					log3.LogError((object)$"ObjectDB.{lifecycle}: Hammer-PieceTable-Registrierung fail-closed abgebrochen: {ex.Message}");
				}
			}
		}

		private static void RegisterHammerPiece(PieceTable table, GameObject prefab, string prefabName, string pieceName, string label)
		{
			foreach (GameObject piece in table.m_pieces)
			{
				if (piece == prefab)
				{
					return;
				}
				if (!((Object)(object)piece == (Object)null))
				{
					Piece component = piece.GetComponent<Piece>();
					if (((Object)piece).name == prefabName || component?.m_name == pieceName)
					{
						throw new InvalidDataException("Hammer-PieceTable-Konflikt mit '" + ((Object)piece).name + "'.");
					}
				}
			}
			table.m_pieces.Add(prefab);
			ManualLogSource? log = Log;
			if (log != null)
			{
				log.LogInfo((object)(label + " genau einmal zu _HammerPieceTable.m_pieces hinzugefuegt."));
			}
		}

		private static void ConfigureDeerRequirements(ObjectDB objectDb, Piece cushionPiece, int deerAmount, int scrapsAmount, string label)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			Require((Object)(object)cushionPiece.m_craftingStation == (Object)null, "Cozy Cushion darf keine Crafting Station verlangen.");
			Require(cushionPiece.m_resources != null, "Piece.m_resources fehlt.");
			if (cushionPiece.m_resources.Length == 2)
			{
				RequireDeerRequirements(cushionPiece, deerAmount, scrapsAmount, label);
				return;
			}
			Require(cushionPiece.m_resources.Length == 0, "Requirements enthalten einen unerwarteten Zwischenzustand.");
			GameObject itemPrefab = objectDb.GetItemPrefab("DeerHide");
			GameObject itemPrefab2 = objectDb.GetItemPrefab("LeatherScraps");
			Require((Object)(object)itemPrefab != (Object)null, "Vanilla-Material 'DeerHide' fehlt.");
			Require((Object)(object)itemPrefab2 != (Object)null, "Vanilla-Material 'LeatherScraps' fehlt.");
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			ItemDrop component2 = itemPrefab2.GetComponent<ItemDrop>();
			Require((Object)(object)component != (Object)null, "Vanilla-Material 'DeerHide' besitzt kein ItemDrop.");
			Require((Object)(object)component2 != (Object)null, "Vanilla-Material 'LeatherScraps' besitzt kein ItemDrop.");
			Requirement[] resources = (Requirement[])(object)new Requirement[2]
			{
				new Requirement
				{
					m_resItem = component,
					m_amount = deerAmount,
					m_extraAmountOnlyOneIngredient = 0,
					m_amountPerLevel = 0,
					m_recover = true
				},
				new Requirement
				{
					m_resItem = component2,
					m_amount = scrapsAmount,
					m_extraAmountOnlyOneIngredient = 0,
					m_amountPerLevel = 0,
					m_recover = true
				}
			};
			cushionPiece.m_resources = resources;
			RequireDeerRequirements(cushionPiece, deerAmount, scrapsAmount, label);
			ManualLogSource? log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"{label} Requirements atomar gesetzt: {deerAmount} DeerHide, {scrapsAmount} LeatherScraps, beide recoverable.");
			}
		}

		private static void RequireDeerRequirements(Piece cushionPiece, int deerAmount, int scrapsAmount, string label)
		{
			Require(cushionPiece.m_resources != null && cushionPiece.m_resources.Length == 2, label + " muss exakt zwei Requirements besitzen.");
			Requirement val = cushionPiece.m_resources[0];
			Requirement val2 = cushionPiece.m_resources[1];
			Require(val != null && (Object)(object)val.m_resItem != (Object)null && ((Object)((Component)val.m_resItem).gameObject).name == "DeerHide", "Requirement 1 muss DeerHide sein.");
			Require(val.m_amount == deerAmount && val.m_amountPerLevel == 0 && val.m_extraAmountOnlyOneIngredient == 0 && val.m_recover, label + " DeerHide-Requirement ist ungueltig.");
			Require(val2 != null && (Object)(object)val2.m_resItem != (Object)null && ((Object)((Component)val2.m_resItem).gameObject).name == "LeatherScraps", "Requirement 2 muss LeatherScraps sein.");
			Require(val2.m_amount == scrapsAmount && val2.m_amountPerLevel == 0 && val2.m_extraAmountOnlyOneIngredient == 0 && val2.m_recover, label + " LeatherScraps-Requirement ist ungueltig.");
		}

		private static void RegisterLocalizationIfReady()
		{
			Localization instance = Localization.instance;
			if (instance != null)
			{
				if (!LocalizationSubscribed)
				{
					Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnLanguageChange));
					LocalizationSubscribed = true;
				}
				AddLocalizationWords(instance);
			}
		}

		private static void OnLanguageChange()
		{
			RegisterLocalizationIfReady();
		}

		private static void AddLocalizationWords(Localization localization)
		{
			MethodInfo method = typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				ManualLogSource? log = Log;
				if (log != null)
				{
					log.LogError((object)"Localization.AddWord wurde lokal nicht gefunden.");
				}
				return;
			}
			method.Invoke(localization, new object[2] { "piece_goblinstudio_cozycushion", "Cozy Cushion" });
			method.Invoke(localization, new object[2] { "piece_goblinstudio_cozycushion_description", "A soft handmade cushion for a warmer, cozier home." });
			method.Invoke(localization, new object[2] { "piece_goblinstudio_foldedblanket", "Folded Blanket" });
			method.Invoke(localization, new object[2] { "piece_goblinstudio_foldedblanket_description", "A neatly folded blanket for a warm and welcoming home." });
		}
	}
}