Decompiled source of Glitnir extras v2.2.4

GlitnirExtras.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HarmonyLibs;
using ItemManager;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using PieceManager;
using ServerSync;
using SoftReferenceableAssets;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("GlitnirExtras")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("GlitnirExtras")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E74EB49A-461D-48EA-85BC-F462D60C98C4")]
[assembly: AssemblyFileVersion("0.2.4")]
[assembly: AssemblyCompany("Marlthon")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.4.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<92c6dbc7-da49-44ae-87bf-d2be53fb2bac>Embedded]
	internal sealed class <92c6dbc7-da49-44ae-87bf-d2be53fb2bac>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	[<92c6dbc7-da49-44ae-87bf-d2be53fb2bac>Embedded]
	internal sealed class <7de5f404-617b-498f-94c8-3c81d5a82a72>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <7de5f404-617b-498f-94c8-3c81d5a82a72>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <7de5f404-617b-498f-94c8-3c81d5a82a72>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[<92c6dbc7-da49-44ae-87bf-d2be53fb2bac>Embedded]
	[CompilerGenerated]
	internal sealed class <bb937bf9-9174-4794-9b96-8c95c0931223>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <bb937bf9-9174-4794-9b96-8c95c0931223>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace GlitnirExtras
{
	[HarmonyPatch(typeof(SE_Rested), "GetNearbyComfortPieces")]
	public static class SE_Rested_GetNearbyComfortPieces_Patch
	{
		[CompilerGenerated]
		private sealed class <Transpiler>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
		{
			private int <>1__state;

			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(1)]
			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(new byte[] { 0, 1 })]
			private IEnumerable<CodeInstruction> instructions;

			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(new byte[] { 0, 1 })]
			public IEnumerable<CodeInstruction> <>3__instructions;

			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(new byte[] { 0, 1 })]
			private IEnumerator<CodeInstruction> <>s__1;

			private CodeInstruction <instruction>5__2;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				[return: <7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(1)]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Transpiler>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = null;
				<instruction>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<instruction>5__2 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						<instruction>5__2 = <>s__1.Current;
						if (<instruction>5__2.opcode == OpCodes.Ldc_R4 && (float)<instruction>5__2.operand == 10f)
						{
							<instruction>5__2.operand = 20f;
						}
						<>2__current = <instruction>5__2;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__1 != null)
				{
					<>s__1.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<Transpiler>d__0 <Transpiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<Transpiler>d__ = this;
				}
				else
				{
					<Transpiler>d__ = new <Transpiler>d__0(0);
				}
				<Transpiler>d__.instructions = <>3__instructions;
				return <Transpiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
		[IteratorStateMachine(typeof(<Transpiler>d__0))]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Transpiler>d__0(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[HarmonyPatch(typeof(EffectArea), "Awake")]
	public static class EffectArea_Awake_Patch
	{
		private static void Postfix(EffectArea __instance)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if ((__instance.m_type & 1) > 0)
			{
				UpdateFireEffectRadius(__instance, 20f);
			}
		}

		private static void UpdateFireEffectRadius(EffectArea area, float newRadius)
		{
			SphereCollider component = ((Component)area).GetComponent<SphereCollider>();
			if ((Object)(object)component != (Object)null)
			{
				component.radius = newRadius;
			}
		}
	}
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public static class Patch_PvPBiome
	{
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		public enum BiomeMode
		{
			PvE,
			PvP
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		[HarmonyPatch]
		private static class Patch_PlayerUpdate
		{
			[HarmonyPostfix]
			[HarmonyPatch(typeof(Player), "Update")]
			[HarmonyPatch(typeof(InventoryGui), "UpdateCharacterStats")]
			public static void Postfix()
			{
				if (Object.op_Implicit((Object)(object)ZNetScene.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)InventoryGui.instance))
				{
					bool pvp = GetCurrentBiomeMode() == BiomeMode.PvP;
					((Selectable)InventoryGui.instance.m_pvp).interactable = false;
					ApplyWithDelay(pvp);
				}
			}
		}

		private static ConfigEntry<BiomeMode> _meadows;

		private static ConfigEntry<BiomeMode> _blackForest;

		private static ConfigEntry<BiomeMode> _swamp;

		private static ConfigEntry<BiomeMode> _mountain;

		private static ConfigEntry<BiomeMode> _plains;

		private static ConfigEntry<BiomeMode> _ocean;

		private static ConfigEntry<BiomeMode> _mistlands;

		private static ConfigEntry<BiomeMode> _ashLands;

		private static ConfigEntry<BiomeMode> _deepNorth;

		private static ConfigEntry<float> _delay;

		private static ConfigEntry<string> _msgPvP;

		private static ConfigEntry<string> _msgPvE;

		private static ConfigEntry<string> _msgPvPTitleColor;

		private static ConfigEntry<string> _msgPvPBodyColor;

		private static ConfigEntry<string> _msgPvETitleColor;

		private static ConfigEntry<string> _msgPvEBodyColor;

		private static ConfigEntry<string> _msgPvPTitle;

		private static ConfigEntry<string> _msgPvETitle;

		private static bool? _lastPvPState;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			_meadows = plugin.config("PvP por Bioma", "Meadows", BiomeMode.PvE, "Prados — PvP ou PvE");
			_blackForest = plugin.config("PvP por Bioma", "BlackForest", BiomeMode.PvE, "Floresta Negra — PvP ou PvE");
			_swamp = plugin.config("PvP por Bioma", "Swamp", BiomeMode.PvE, "Pântano — PvP ou PvE");
			_mountain = plugin.config("PvP por Bioma", "Mountain", BiomeMode.PvE, "Montanha — PvP ou PvE");
			_plains = plugin.config("PvP por Bioma", "Plains", BiomeMode.PvE, "Planícies — PvP ou PvE");
			_ocean = plugin.config("PvP por Bioma", "Ocean", BiomeMode.PvE, "Oceano — PvP ou PvE");
			_mistlands = plugin.config("PvP por Bioma", "Mistlands", BiomeMode.PvE, "Mistlands — PvP ou PvE");
			_ashLands = plugin.config("PvP por Bioma", "AshLands", BiomeMode.PvE, "AshLands — PvP ou PvE");
			_deepNorth = plugin.config("PvP por Bioma", "DeepNorth", BiomeMode.PvE, "Deep North — PvP ou PvE");
			_delay = plugin.config("PvP por Bioma", "DelaySeconds", 0f, "Segundos de espera antes de aplicar a regra ao entrar num novo bioma (0 = imediato)");
			_msgPvPTitle = plugin.config("PvP por Bioma", "MessagePvPTitle", "ÁREA PVP", "Título da mensagem PvP");
			_msgPvPTitleColor = plugin.config("PvP por Bioma", "MessagePvPTitleColor", "#FF0000", "Cor do título da mensagem PvP (hex)");
			_msgPvP = plugin.config("PvP por Bioma", "MessagePvP", "Você entrou em um bioma PvP!", "Mensagem ao entrar em bioma PvP");
			_msgPvPBodyColor = plugin.config("PvP por Bioma", "MessagePvPBodyColor", "#FFFF00", "Cor do corpo da mensagem PvP (hex)");
			_msgPvETitle = plugin.config("PvP por Bioma", "MessagePvETitle", "ÁREA PVE", "Título da mensagem PvE");
			_msgPvETitleColor = plugin.config("PvP por Bioma", "MessagePvETitleColor", "#00FF00", "Cor do título da mensagem PvE (hex, true)");
			_msgPvE = plugin.config("PvP por Bioma", "MessagePvE", "Você entrou em um bioma PvE!", "Mensagem ao entrar em bioma PvE");
			_msgPvEBodyColor = plugin.config("PvP por Bioma", "MessagePvEBodyColor", "#FFFF00", "Cor do corpo da mensagem PvE (hex)");
		}

		private static BiomeMode GetCurrentBiomeMode()
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected I4, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Invalid comparison between Unknown and I4
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)EnvMan.instance))
			{
				return BiomeMode.PvE;
			}
			Biome currentBiome = EnvMan.instance.GetCurrentBiome();
			if (1 == 0)
			{
			}
			BiomeMode result;
			if ((int)currentBiome <= 16)
			{
				switch (currentBiome - 1)
				{
				case 0:
					goto IL_0084;
				case 1:
					goto IL_009e;
				case 3:
					goto IL_00ab;
				case 2:
					goto IL_00f9;
				}
				if ((int)currentBiome != 8)
				{
					if ((int)currentBiome != 16)
					{
						goto IL_00f9;
					}
					result = _plains.Value;
				}
				else
				{
					result = _blackForest.Value;
				}
			}
			else if ((int)currentBiome <= 64)
			{
				if ((int)currentBiome != 32)
				{
					if ((int)currentBiome != 64)
					{
						goto IL_00f9;
					}
					result = _deepNorth.Value;
				}
				else
				{
					result = _ashLands.Value;
				}
			}
			else if ((int)currentBiome != 256)
			{
				if ((int)currentBiome != 512)
				{
					goto IL_00f9;
				}
				result = _mistlands.Value;
			}
			else
			{
				result = _ocean.Value;
			}
			goto IL_00fd;
			IL_009e:
			result = _swamp.Value;
			goto IL_00fd;
			IL_00fd:
			if (1 == 0)
			{
			}
			return result;
			IL_00f9:
			result = BiomeMode.PvE;
			goto IL_00fd;
			IL_00ab:
			result = _mountain.Value;
			goto IL_00fd;
			IL_0084:
			result = _meadows.Value;
			goto IL_00fd;
		}

		private static async Task ApplyWithDelay(bool pvp)
		{
			int ms = (int)(Math.Max(0f, _delay.Value) * 1000f);
			if (ms > 0)
			{
				await Task.Delay(ms);
			}
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)InventoryGui.instance) && (!_lastPvPState.HasValue || _lastPvPState.Value != pvp))
			{
				Player.m_localPlayer.SetPVP(pvp);
				InventoryGui.instance.m_pvp.isOn = pvp;
				_lastPvPState = pvp;
				ShowMessage(pvp);
			}
		}

		private static void ShowMessage(bool pvp)
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				string value;
				string value2;
				string value3;
				string value4;
				if (pvp)
				{
					value = _msgPvPTitle.Value;
					value2 = _msgPvPTitleColor.Value;
					value3 = _msgPvPBodyColor.Value;
					value4 = _msgPvP.Value;
				}
				else
				{
					value = _msgPvETitle.Value;
					value2 = _msgPvETitleColor.Value;
					value3 = _msgPvEBodyColor.Value;
					value4 = _msgPvE.Value;
				}
				string text = "<color=" + value2 + ">" + value + "</color>\n<color=" + value3 + ">" + value4 + "</color>";
				((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null);
			}
		}
	}
	[HarmonyPatch(typeof(Smelter), "Awake")]
	public static class Smelter_Awake_Patch
	{
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
		private static void Postfix(Smelter __instance)
		{
			switch (__instance.m_name)
			{
			case "$piece_smelter":
			case "$piece_blastfurnace":
			case "$piece_eitrrefinery":
				__instance.m_maxOre = 100;
				__instance.m_maxFuel = 200;
				break;
			case "$piece_charcoalkiln":
				__instance.m_maxOre = 200;
				break;
			case "$piece_windmill":
			case "$piece_spinningwheel":
				__instance.m_maxOre = 100;
				break;
			case "$piece_bathtub":
				__instance.m_maxFuel = 50;
				break;
			}
		}
	}
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[BepInPlugin("marlthon.GlitnirExtras", "GlitnirExtras", "0.2.4")]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public class GlitnirExtrasPlugin : BaseUnityPlugin
	{
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			public bool? Browsable = false;
		}

		internal const string ModName = "GlitnirExtras";

		internal const string ModVersion = "0.2.4";

		internal const string Author = "marlthon";

		private const string ModGUID = "marlthon.GlitnirExtras";

		private static string ConfigFileName = "marlthon.GlitnirExtras.cfg";

		private static string ConfigFileFullPath;

		private readonly Harmony _harmony = new Harmony("marlthon.GlitnirExtras");

		public static readonly ManualLogSource GlitnirExtras;

		private static readonly ConfigSync ConfigSync;

		private static ConfigEntry<bool> _serverConfigLocked;

		public static bool IsLocalPlayerAdmin()
		{
			return ConfigSync != null && ConfigSync.IsAdmin;
		}

		public void Awake()
		{
			HarmonyCore.Instance.Init("GlitnirExtras");
			HarmonyCore.Instance.Ciano("Marlthon Mods");
			HarmonyCore.Instance.Verde("Download more mods at marlthon.com");
			_serverConfigLocked = config("General", "Force Server Config", value: true, "Force Server Config");
			ConfigSync.AddLockingConfigEntry<bool>(_serverConfigLocked);
			Patch_PvPBiome.InitConfig(this);
			Patch_WearNTear.InitConfig(this);
			Patch_Base.InitConfig(this);
			Patch_ItemBalance.InitConfig(this);
			Patch_Clock.InitConfig(this);
			Patch_Workbench.InitConfig(this);
			Patch_Container.InitConfig(this);
			Patch_DeleteItem.InitConfig(this);
			MenuLogoReplace.InitConfig(this);
			Item item = new Item("mar_glitnirextras", "Glitnir_ADMCape");
			item.Name.English("Glitnir Adm Cape");
			item.Name.Portuguese_Brazilian("Capa de ADM Glitnir.");
			item.Description.English("ADM Glitnir Server Cover.");
			item.Description.Portuguese_Brazilian("Capa de uso exclusivo dos Adms Glitnir Server.");
			item.Configurable = Configurability.Disabled;
			MaterialReplacer.RegisterGameObjectForShaderSwap(item.Prefab, MaterialReplacer.ShaderType.UseUnityShader);
			Item item2 = new Item("mar_glitnirextras", "GlitnirCoin");
			item2.Name.English("Glitnir Coin");
			item2.Name.Portuguese_Brazilian("Glitnir Coin");
			item2.Description.English("Official Currency of Glitnir Server");
			item2.Description.Portuguese_Brazilian("Moeda Oficial do Glitnir Server");
			item2.Configurable = Configurability.Disabled;
			Item item3 = new Item("mar_glitnirextras", "GlitnirBloodCoin");
			item3.Name.English("Glitnir Blood Coin");
			item3.Name.Portuguese_Brazilian("Moeda Sangrenta Glitnir");
			item3.Description.English("Official Blood Currency of Glitnir Server");
			item3.Description.Portuguese_Brazilian("Moeda Sangrenta do Glitnir Server");
			item3.Configurable = Configurability.Disabled;
			BuildPiece buildPiece = new BuildPiece("mar_glitnirextras", "GlitnirBanner");
			buildPiece.Crafting.Set(PieceManager.CraftingTable.Workbench);
			buildPiece.Category.Set("Glitnir");
			buildPiece.SpecialProperties.AdminOnly = false;
			buildPiece.Name.Portuguese_Brazilian("Banner Glitnir");
			buildPiece.Name.English("Glitnir Banner");
			buildPiece.Description.Portuguese_Brazilian("Banner Glitnir");
			buildPiece.Description.English("Glitnir Banner");
			buildPiece.RequiredItems.Add("SwordCheat", 1, recover: false);
			BuildPiece buildPiece2 = new BuildPiece("mar_glitnirextras", "GlitnirBannerPole");
			buildPiece2.Crafting.Set(PieceManager.CraftingTable.Workbench);
			buildPiece2.Category.Set("Glitnir");
			buildPiece2.SpecialProperties.AdminOnly = false;
			buildPiece2.Name.Portuguese_Brazilian("Estandarte Glitnir");
			buildPiece2.Name.English("Glitnir Banner Pole");
			buildPiece2.Description.Portuguese_Brazilian("Estandarte Glitnir");
			buildPiece2.Description.English("Glitnir Banner Pole");
			buildPiece2.RequiredItems.Add("SwordCheat", 1, recover: false);
			BuildPiece buildPiece3 = new BuildPiece("mar_glitnirextras", "GlitnirFlag");
			buildPiece3.Crafting.Set(PieceManager.CraftingTable.Workbench);
			buildPiece3.Category.Set("Glitnir");
			buildPiece3.SpecialProperties.AdminOnly = false;
			buildPiece3.Name.Portuguese_Brazilian("Bandeira Glitnir");
			buildPiece3.Name.English("Glitnir Flag");
			buildPiece3.Description.Portuguese_Brazilian("Bandeira Glitnir");
			buildPiece3.Description.English("Glitnir Flag");
			buildPiece3.RequiredItems.Add("SwordCheat", 1, recover: false);
			BuildPiece buildPiece4 = new BuildPiece("mar_glitnirextras", "Piece_NizeraX");
			buildPiece4.Crafting.Set(PieceManager.CraftingTable.Workbench);
			buildPiece4.Category.Set("Glitnir");
			buildPiece4.SpecialProperties.AdminOnly = false;
			buildPiece4.Name.Portuguese_Brazilian("NizeraX");
			buildPiece4.Name.English("NizeraX");
			buildPiece4.Description.Portuguese_Brazilian("NizeraX");
			buildPiece4.Description.English("NizeraX");
			buildPiece4.RequiredItems.Add("SwordCheat", 1, recover: false);
			GameObject val = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_blacksmith");
			GameObject val2 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_butcher1");
			GameObject val3 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_butcher2");
			GameObject val4 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_craftsman");
			GameObject val5 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_farmer_01");
			GameObject val6 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_idle_01");
			GameObject val7 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_idle_02");
			GameObject val8 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_idle_03");
			GameObject val9 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_patrol_01");
			GameObject val10 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_patrol_02");
			GameObject val11 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_guard_patrol_03");
			GameObject val12 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_hunter");
			GameObject val13 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_king_idle");
			GameObject val14 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_kingthrone");
			GameObject val15 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_laborer_idle");
			GameObject val16 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_laborer_walk");
			GameObject val17 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_lumberjack1");
			GameObject val18 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_lumberjack2");
			GameObject val19 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_mage");
			GameObject val20 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_miner1");
			GameObject val21 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_miner2");
			GameObject val22 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_miner3");
			GameObject val23 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_monk");
			GameObject val24 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_idle01");
			GameObject val25 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_idle02");
			GameObject val26 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_idle03");
			GameObject val27 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_idle04");
			GameObject val28 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_walk01");
			GameObject val29 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_walk02");
			GameObject val30 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_walk03");
			GameObject val31 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_peasant_walk04");
			GameObject val32 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_trader1_idle");
			GameObject val33 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_trader1_walk");
			GameObject val34 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_trader2_idle");
			GameObject val35 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_trader2_walk");
			GameObject val36 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_warrior");
			GameObject val37 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_womanwar_01");
			GameObject val38 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_womanwar_02");
			GameObject val39 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_womanwar_03");
			GameObject val40 = PiecePrefabManager.RegisterPrefab("mar_glitnirextras", "ms_npc_noticeboard");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "sfx_build_hammer_metal_glitnirextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "sfx_build_hammer_wood_glitnirextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "sfx_build_hammer_wood_nizeraextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "sfx_wood_destroyed_glitnirextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "vfx_Place_wood_pole_glitnirextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "vfx_Place_wood_pole_nizeraextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "vfx_SawDust_glitnirextras");
			PrefabManager.RegisterPrefab("mar_glitnirextras", "vfx_SawDust_nizeraextras");
			SetupWatcher();
			_harmony.PatchAll();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				GlitnirExtras.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				GlitnirExtras.LogError((object)("There was an issue loading your " + ConfigFileName));
				GlitnirExtras.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		public ConfigEntry<T> config<[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			SyncedConfigEntry<T> syncedConfigEntry = ConfigSync.AddConfigEntry<T>(val2);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		public ConfigEntry<T> config<[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static GlitnirExtrasPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			GlitnirExtras = Logger.CreateLogSource("GlitnirExtras");
			ConfigSync = new ConfigSync("marlthon.GlitnirExtras")
			{
				DisplayName = "GlitnirExtras",
				CurrentVersion = "0.2.4",
				MinimumRequiredVersion = "0.2.4",
				ModRequired = true
			};
			_serverConfigLocked = null;
		}
	}
	[HarmonyPatch]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public static class Patch_Base
	{
		private static ConfigEntry<float> CarryWeightBase;

		private static ConfigEntry<float> MegingjordBonus;

		private static ConfigEntry<float> BuildDistance;

		private static ConfigEntry<float> AutoPickupRange;

		private static ConfigEntry<float> InteractDistance;

		private static bool _appliedRuntimeTuningOnce;

		private const string MegingjordPrefab = "BeltStrength";

		private const string MegingjordToken = "$item_beltstrength";

		private const float VanillaCarryBase = 300f;

		private const float VanillaMegiBonus = 150f;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			CarryWeightBase = plugin.config("BaseTweaks", "CarryWeightBase", 300f, "Base carry weight for the player.");
			MegingjordBonus = plugin.config("BaseTweaks", "MegingjordBonus", 150f, "Carry weight bonus given by Megingjord.");
			BuildDistance = plugin.config("BaseTweaks", "BuildDistance", 5f, "Max distance to place pieces (build range).");
			AutoPickupRange = plugin.config("BaseTweaks", "AutoPickupRange", 2f, "Auto-pickup item radius.");
			InteractDistance = plugin.config("BaseTweaks", "InteractDistance", 2.5f, "Interaction distance for use/open.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "GetMaxCarryWeight")]
		private static void Player_GetMaxCarryWeight_Postfix(Player __instance, ref float __result)
		{
			float num = CarryWeightBase.Value - 300f;
			__result += num;
			if (HasMegingjordEquipped(__instance))
			{
				float num2 = MegingjordBonus.Value - 150f;
				__result += num2;
			}
		}

		[HarmonyPatch(typeof(Player), "Awake")]
		[HarmonyPostfix]
		private static void Player_Awake_Postfix(Player __instance)
		{
			TrySetFloatField(__instance, new string[3] { "m_maxPlaceDistance", "m_buildDistance", "m_placeDistance" }, BuildDistance.Value);
			TrySetFloatField(__instance, new string[2] { "m_autoPickupRange", "m_autoPickupDistance" }, AutoPickupRange.Value);
			TrySetFloatField(__instance, new string[2] { "m_maxInteractDistance", "m_interactDistance" }, InteractDistance.Value);
			if (!_appliedRuntimeTuningOnce && (Object)(object)Player.m_localPlayer == (Object)(object)__instance)
			{
				_appliedRuntimeTuningOnce = true;
				((Character)Player.m_localPlayer).Message((MessageType)1, $"CarryWeight base: {CarryWeightBase.Value:0.#}  |  Megingjord: {MegingjordBonus.Value:0.#}", 0, (Sprite)null);
				((Character)Player.m_localPlayer).Message((MessageType)1, $"Build distance: {BuildDistance.Value:0.#}  |  Auto-pickup: {AutoPickupRange.Value:0.#}  |  Interact: {InteractDistance.Value:0.#}", 0, (Sprite)null);
			}
		}

		private static bool HasMegingjordEquipped(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return false;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			foreach (ItemData item in allItems)
			{
				if (item != null && item.m_equipped)
				{
					if ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "BeltStrength")
					{
						return true;
					}
					if (!string.IsNullOrEmpty(item.m_shared?.m_name) && string.Equals(item.m_shared.m_name, "$item_beltstrength", StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
					if (!string.IsNullOrEmpty(item.m_shared?.m_name) && item.m_shared.m_name.IndexOf("belt", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void TrySetFloatField(object instance, string[] candidateFieldNames, float value)
		{
			Type type = instance.GetType();
			foreach (string text in candidateFieldNames)
			{
				FieldInfo fieldInfo = AccessTools.Field(type, text);
				if (fieldInfo != null && fieldInfo.FieldType == typeof(float))
				{
					fieldInfo.SetValue(instance, value);
					break;
				}
			}
		}
	}
	[HarmonyPatch]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public static class Patch_Clock
	{
		private static ConfigEntry<bool> ClockEnabled;

		private static ConfigEntry<float> ClockUpdateInterval;

		private static ConfigEntry<int> ClockFontSize;

		private static ConfigEntry<bool> ShowRealTime;

		private static ConfigEntry<bool> RealTimeUse24H;

		private static ConfigEntry<int> RealTimeFontSize;

		private static float _nextUpdateTime;

		private static GameObject _clockRoot;

		private static TextMeshProUGUI _timeText;

		private static TextMeshProUGUI _realText;

		private const float ROOT_OFFSET_Y = -60f;

		private const float ROOT_WIDTH = 600f;

		private const float ROOT_HEIGHT = 120f;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			ClockEnabled = plugin.config("Clock", "ClockEnabled", value: true, "Show the in-game clock.");
			ClockUpdateInterval = plugin.config("Clock", "ClockUpdateInterval", 1f, "Seconds between updates.");
			ClockFontSize = plugin.config("Clock", "ClockFontSize", 40, "Font size for the in-game clock.");
			ShowRealTime = plugin.config("Clock", "ShowRealTime", value: true, "Show the real-world time below the in-game clock.");
			RealTimeUse24H = plugin.config("Clock", "RealTimeUse24H", value: true, "Use 24-hour time format for real-world time.");
			RealTimeFontSize = plugin.config("Clock", "RealTimeFontSize", 28, "Font size for the real-world time text.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "Update")]
		private static void Hud_Update_Postfix(Hud __instance)
		{
			if (!ClockEnabled.Value)
			{
				if ((Object)(object)_clockRoot != (Object)null)
				{
					Object.Destroy((Object)(object)_clockRoot);
				}
				return;
			}
			if ((Object)(object)_clockRoot == (Object)null)
			{
				CreateClock(__instance);
			}
			if (!(Time.unscaledTime < _nextUpdateTime))
			{
				_nextUpdateTime = Time.unscaledTime + Mathf.Max(0.2f, ClockUpdateInterval.Value);
				UpdateClockTexts();
			}
		}

		private static void CreateClock(Hud hud)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_004a: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			_clockRoot = new GameObject("MarlthonClockRoot");
			_clockRoot.transform.SetParent(hud.m_rootObject.transform, false);
			RectTransform val = _clockRoot.AddComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.anchoredPosition = new Vector2(0f, -60f);
			val.sizeDelta = new Vector2(600f, 120f);
			TMP_FontAsset font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (TMP_FontAsset f) => ((Object)f).name.ToLower().Contains("norsebold"))) ?? TMP_Settings.defaultFontAsset;
			_timeText = CreateTMP("ClockTime", font, ClockFontSize.Value, new Color(1f, 0.85f, 0.2f));
			((TMP_Text)_timeText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_timeText).transform.SetParent(_clockRoot.transform, false);
			((TMP_Text)_timeText).rectTransform.anchoredPosition = new Vector2(0f, 10f);
			_realText = CreateTMP("ClockReal", font, RealTimeFontSize.Value, new Color(0.8f, 0.8f, 0.8f));
			((TMP_Text)_realText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_realText).transform.SetParent(_clockRoot.transform, false);
			((TMP_Text)_realText).rectTransform.anchoredPosition = new Vector2(0f, -30f);
		}

		private static TextMeshProUGUI CreateTMP(string name, TMP_FontAsset font, int size, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).font = font ?? TMP_Settings.defaultFontAsset;
			((TMP_Text)val2).fontSize = size;
			((Graphic)val2).color = color;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).richText = true;
			Material val3 = new Material(((TMP_Text)val2).fontSharedMaterial);
			val3.SetFloat("_OutlineWidth", 0.1f);
			val3.SetColor("_OutlineColor", new Color(0f, 0f, 0f, 0.6f));
			((TMP_Text)val2).fontSharedMaterial = val3;
			return val2;
		}

		private static void UpdateClockTexts()
		{
			if (!((Object)(object)EnvMan.instance == (Object)null))
			{
				float num = EnvMan.instance.GetDay();
				float dayFraction = EnvMan.instance.GetDayFraction();
				int num2 = Mathf.FloorToInt(dayFraction * 24f);
				int num3 = Mathf.FloorToInt((dayFraction * 24f - (float)num2) * 60f);
				((TMP_Text)_timeText).text = $"Dia {num} - {num2:00}:{num3:00}";
				if (ShowRealTime.Value)
				{
					DateTime now = DateTime.Now;
					string text = (RealTimeUse24H.Value ? now.ToString("HH:mm") : now.ToString("hh:mm tt"));
					((TMP_Text)_realText).text = "<color=#CCCCCC>Vida Real: " + text + "</color>";
				}
				else
				{
					((TMP_Text)_realText).text = "";
				}
			}
		}
	}
	[HarmonyPatch]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public static class Patch_Container
	{
		private static ConfigEntry<bool> ChestControl;

		private static ConfigEntry<int> PrivateRows;

		private static ConfigEntry<int> PrivateCols;

		private static ConfigEntry<int> WoodRows;

		private static ConfigEntry<int> WoodCols;

		private static ConfigEntry<int> IronRows;

		private static ConfigEntry<int> IronCols;

		private static ConfigEntry<int> BlackmetalRows;

		private static ConfigEntry<int> BlackmetalCols;

		private static ConfigEntry<int> BarrelRows;

		private static ConfigEntry<int> BarrelCols;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			ChestControl = plugin.config("ContainerControl", "EnableChestControl", value: true, "Enable server control over vanilla chest sizes (private, wood, iron, blackmetal, barrel).");
			PrivateRows = plugin.config("Chests", "PrivateChestRows", 2, new ConfigDescription("Rows for personal chest (piece_chest_private)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), Array.Empty<object>()));
			PrivateCols = plugin.config("Chests", "PrivateChestCols", 3, new ConfigDescription("Cols for personal chest (piece_chest_private)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 8), Array.Empty<object>()));
			WoodRows = plugin.config("Chests", "WoodChestRows", 2, new ConfigDescription("Rows for wood chest (piece_chest_wood)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>()));
			WoodCols = plugin.config("Chests", "WoodChestCols", 5, new ConfigDescription("Cols for wood chest (piece_chest_wood)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 8), Array.Empty<object>()));
			IronRows = plugin.config("Chests", "IronChestRows", 4, new ConfigDescription("Rows for iron chest (piece_chest)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), Array.Empty<object>()));
			IronCols = plugin.config("Chests", "IronChestCols", 6, new ConfigDescription("Cols for iron chest (piece_chest)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 8), Array.Empty<object>()));
			BlackmetalRows = plugin.config("Chests", "BlackmetalChestRows", 4, new ConfigDescription("Rows for blackmetal chest (piece_chest_blackmetal)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 20), Array.Empty<object>()));
			BlackmetalCols = plugin.config("Chests", "BlackmetalChestCols", 8, new ConfigDescription("Cols for blackmetal chest (piece_chest_blackmetal)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(6, 8), Array.Empty<object>()));
			BarrelRows = plugin.config("Chests", "BarrelChestRows", 3, new ConfigDescription("Rows for barrel chest (piece_chest_barrel)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>()));
			BarrelCols = plugin.config("Chests", "BarrelChestCols", 3, new ConfigDescription("Cols for barrel chest (piece_chest_barrel)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 8), Array.Empty<object>()));
			SubscribeChanges();
		}

		private static void SubscribeChanges()
		{
			Watch<bool>(ChestControl);
			Watch<int>(PrivateRows);
			Watch<int>(PrivateCols);
			Watch<int>(WoodRows);
			Watch<int>(WoodCols);
			Watch<int>(IronRows);
			Watch<int>(IronCols);
			Watch<int>(BlackmetalRows);
			Watch<int>(BlackmetalCols);
			Watch<int>(BarrelRows);
			Watch<int>(BarrelCols);
			static void Watch<T>([<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(new byte[] { 1, 0 })] ConfigEntry<T> entry)
			{
				if (entry != null)
				{
					entry.SettingChanged += [<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (object _, EventArgs _) =>
					{
						UpdateAllChests();
					};
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Container), "Awake")]
		private static void Container_Awake_Postfix(Container __instance)
		{
			TryResize(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Container), "Interact")]
		private static void Container_Interact_Prefix(Container __instance, Humanoid character, bool hold, bool alt)
		{
			TryResize(__instance);
		}

		private static void TryResize(Container container)
		{
			if (!ChestControl.Value || (Object)(object)container == (Object)null || ((Object)container).name.StartsWith("Treasure"))
			{
				return;
			}
			ZNetView nview = container.m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) == 0)
			{
				return;
			}
			Inventory inventory = container.GetInventory();
			if (inventory != null)
			{
				switch (((Object)((Component)container).transform.root).name.Trim().Replace("(Clone)", ""))
				{
				case "piece_chest_private":
					inventory.m_height = PrivateRows.Value;
					inventory.m_width = PrivateCols.Value;
					break;
				case "piece_chest_wood":
					inventory.m_height = WoodRows.Value;
					inventory.m_width = WoodCols.Value;
					break;
				case "piece_chest":
					inventory.m_height = IronRows.Value;
					inventory.m_width = IronCols.Value;
					break;
				case "piece_chest_blackmetal":
					inventory.m_height = BlackmetalRows.Value;
					inventory.m_width = BlackmetalCols.Value;
					break;
				case "piece_chest_barrel":
					inventory.m_height = BarrelRows.Value;
					inventory.m_width = BarrelCols.Value;
					break;
				}
			}
		}

		private static void UpdateAllChests()
		{
			if (!ChestControl.Value)
			{
				return;
			}
			Container[] array = Resources.FindObjectsOfTypeAll<Container>();
			foreach (Container val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)val).name.StartsWith("Treasure"))
				{
					ZNetView nview = val.m_nview;
					if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0)
					{
						TryResize(val);
					}
				}
			}
			GlitnirExtrasPlugin.GlitnirExtras.LogInfo((object)"[SagaHeim/Container] Chest sizes updated.");
		}
	}
	[HarmonyPatch]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public static class Patch_DeleteItem
	{
		private static ConfigEntry<KeyCode> DeleteKey;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			DeleteKey = plugin.config<KeyCode>("DeleteItem", "DeleteKey", (KeyCode)127, "Key used to delete the selected item in the inventory (default: Delete)");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "Update")]
		private static void PlayerUpdate_Postfix(Player __instance)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)InventoryGui.instance == (Object)null) && Input.GetKeyDown(DeleteKey.Value))
			{
				TryDeleteSelectedItem();
			}
		}

		private static void TryDeleteSelectedItem()
		{
			InventoryGui instance = InventoryGui.instance;
			object? value = AccessTools.Field(typeof(InventoryGui), "m_dragItem").GetValue(instance);
			ItemData val = (ItemData)((value is ItemData) ? value : null);
			object? value2 = AccessTools.Field(typeof(InventoryGui), "m_dragInventory").GetValue(instance);
			Inventory val2 = (Inventory)((value2 is Inventory) ? value2 : null);
			object? value3 = AccessTools.Field(typeof(InventoryGui), "m_dragGo").GetValue(instance);
			GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null);
			if (val == null || val2 == null)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)1, "No item selected.", 0, (Sprite)null);
				}
				return;
			}
			if (val.m_equipped)
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null)
				{
					((Character)localPlayer2).Message((MessageType)1, "Cannot delete equipped item!", 0, (Sprite)null);
				}
				return;
			}
			val2.RemoveItem(val);
			if ((Object)(object)val3 != (Object)null)
			{
				Object.Destroy((Object)(object)val3);
			}
			AccessTools.Field(typeof(InventoryGui), "m_dragGo").SetValue(instance, null);
			AccessTools.Field(typeof(InventoryGui), "m_dragItem").SetValue(instance, null);
			AccessTools.Field(typeof(InventoryGui), "m_dragInventory").SetValue(instance, null);
			Player localPlayer3 = Player.m_localPlayer;
			if (localPlayer3 != null)
			{
				((Character)localPlayer3).Message((MessageType)1, "Deleted: " + val.m_shared.m_name, 0, (Sprite)null);
			}
			instance.m_playerGrid.UpdateInventory(((Humanoid)Player.m_localPlayer).GetInventory(), Player.m_localPlayer, (ItemData)null);
		}
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[HarmonyPatch]
	public static class Patch_ItemBalance
	{
		private static ConfigEntry<float> GlobalWeightMultiplier;

		private static ConfigEntry<float> GlobalStackMultiplier;

		private static ConfigEntry<float> CoinWeight;

		private static ConfigEntry<int> CoinStackMax;

		private static ConfigEntry<bool> EnableFloatingItems;

		private static ConfigEntry<string> NoFloatItems;

		private static readonly HashSet<SharedData> _patchedShared = new HashSet<SharedData>();

		private static readonly HashSet<string> NoFloatSet = new HashSet<string>();

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			GlobalWeightMultiplier = plugin.config("ItemBalance", "GlobalWeightMultiplier", 1f, "Multiplier applied to item weight.");
			GlobalStackMultiplier = plugin.config("ItemBalance", "GlobalStackMultiplier", 1f, "Multiplier applied to item max stack size.");
			CoinWeight = plugin.config("ItemBalance", "CoinWeight", 0.01f, "Weight of a single coin.");
			CoinStackMax = plugin.config("ItemBalance", "CoinStackMax", 9999, "Max stack size for coins.");
			EnableFloatingItems = plugin.config("FloatingItems", "EnableFloatingItems", value: true, "If true, dropped items will float on water.");
			NoFloatItems = plugin.config("FloatingItems", "NoFloatItems", "Obsidian,BlackMetalScrap,IronScrap,CopperOre,TinOre,SilverOre,FlametalOre,BlackMetal,Iron,Copper,Tin,Silver,Flametal,Crystal,Chitin,SurtlingCore,Eitr,Softtissue,Tar,StoneBlock,SharpeningStone,DragonEgg", "Comma-separated prefab names that should NOT float.");
			RebuildNoFloatList();
		}

		private static void RebuildNoFloatList()
		{
			NoFloatSet.Clear();
			string[] array = NoFloatItems.Value.Split(new char[1] { ',' });
			foreach (string text in array)
			{
				if (!string.IsNullOrWhiteSpace(text))
				{
					NoFloatSet.Add(text.Trim().ToLowerInvariant());
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemDrop), "Awake")]
		private static void ItemDrop_Awake_Postfix(ItemDrop __instance)
		{
			if (GlobalWeightMultiplier == null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			SharedData val = __instance.m_itemData?.m_shared;
			if (val == null || _patchedShared.Contains(val))
			{
				return;
			}
			_patchedShared.Add(val);
			string text = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "").ToLowerInvariant();
			string text2 = (val.m_name ?? "").ToLowerInvariant();
			if (text == "coins" || text2.Contains("coin"))
			{
				val.m_weight = Mathf.Max(0.0001f, CoinWeight.Value);
				val.m_maxStackSize = Mathf.Clamp(CoinStackMax.Value, 1, 999999);
				return;
			}
			if (!Mathf.Approximately(GlobalWeightMultiplier.Value, 1f))
			{
				val.m_weight = Mathf.Max(0.0001f, val.m_weight * GlobalWeightMultiplier.Value);
			}
			if (!Mathf.Approximately(GlobalStackMultiplier.Value, 1f) && val.m_maxStackSize > 1)
			{
				val.m_maxStackSize = Mathf.Clamp((int)((float)val.m_maxStackSize * GlobalStackMultiplier.Value), 1, 999999);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemDrop), "Start")]
		private static void ItemDrop_Start_Postfix(ItemDrop __instance)
		{
			if (!EnableFloatingItems.Value || (Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)__instance.m_nview) || !__instance.m_nview.IsValid())
			{
				return;
			}
			string item = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "").ToLowerInvariant();
			if (!NoFloatSet.Contains(item) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Floating>()))
			{
				Floating val = ((Component)__instance).gameObject.AddComponent<Floating>();
				val.m_waterLevelOffset = 0.5f;
				val.m_forceDistance = 1f;
				val.m_force = 0.5f;
				val.m_balanceForceFraction = 0.02f;
				val.m_damping = 0.05f;
				Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					component = ((Component)__instance).gameObject.AddComponent<Rigidbody>();
					component.mass = 0.5f;
					component.linearDamping = 0.1f;
					component.angularDamping = 0.05f;
				}
			}
		}
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[HarmonyPatch]
	internal static class MenuLogoReplace
	{
		private const string BundleName = "mar_glitnirextras";

		private const string SpriteName = "Logoglitnirmenu";

		private const string MusicName = "glitnirtheme";

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static Sprite _cachedSprite;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static AudioClip _cachedClip;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static AudioSource _menuSource;

		private static float _originalMusicVolume = -1f;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		internal static ConfigEntry<bool> UseCustomMenuMusic;

		internal static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			UseCustomMenuMusic = plugin.config("Menu", "Música Customizada no Menu", value: true, new ConfigDescription("Ativa a música temática Glitnir no menu principal. false = usa a música vanilla do Valheim.", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting: false);
		}

		[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
		[HarmonyPostfix]
		private static void SetupGui_Postfix(FejdStartup __instance)
		{
			TryReplaceLogo(__instance);
			ConfigEntry<bool> useCustomMenuMusic = UseCustomMenuMusic;
			if (useCustomMenuMusic != null && useCustomMenuMusic.Value)
			{
				TryPlayCustomMusic();
			}
			else
			{
				StopCustomMusic();
			}
		}

		[HarmonyPatch(typeof(Game), "Start")]
		[HarmonyPrefix]
		private static void Game_Start_Prefix()
		{
			StopCustomMusic();
			if (_originalMusicVolume >= 0f)
			{
				MusicMan.m_masterMusicVolume = _originalMusicVolume;
				_originalMusicVolume = -1f;
			}
		}

		[HarmonyPatch(typeof(MusicMan), "Awake")]
		[HarmonyPostfix]
		private static void MusicMan_Awake_Postfix(MusicMan __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "start")
			{
				return;
			}
			ConfigEntry<bool> useCustomMenuMusic = UseCustomMenuMusic;
			if (useCustomMenuMusic != null && useCustomMenuMusic.Value)
			{
				if (_originalMusicVolume < 0f)
				{
					_originalMusicVolume = MusicMan.m_masterMusicVolume;
				}
				MusicMan.m_masterMusicVolume = 0f;
				AudioSource[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val in componentsInChildren)
				{
					val.Stop();
				}
				Debug.Log((object)"[GlitnirExtras] MusicMan silenciado no menu.");
			}
		}

		[HarmonyPatch(typeof(MusicMan), "Update")]
		[HarmonyPrefix]
		private static bool MusicMan_Update_Prefix()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "start")
			{
				return true;
			}
			ConfigEntry<bool> useCustomMenuMusic = UseCustomMenuMusic;
			return useCustomMenuMusic == null || !useCustomMenuMusic.Value;
		}

		private static void TryReplaceLogo(FejdStartup fs)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fs == (Object)null || (Object)(object)fs.m_mainMenu == (Object)null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "start")
			{
				return;
			}
			Sprite val = LoadSprite();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"[GlitnirExtras] Sprite não encontrada: Logoglitnirmenu");
				return;
			}
			Transform val2 = fs.m_mainMenu.transform.Find("Logo/LOGO");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Image component = ((Component)val2).GetComponent<Image>();
			if (!((Object)(object)component == (Object)null))
			{
				component.sprite = val;
				((Behaviour)component).enabled = true;
				component.preserveAspect = true;
				RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Transform)component2).localScale = Vector3.one;
					component2.SetSizeWithCurrentAnchors((Axis)0, 900f);
					component2.SetSizeWithCurrentAnchors((Axis)1, 350f);
				}
				Debug.Log((object)"[GlitnirExtras] Logo substituída com sucesso.");
			}
		}

		private static void TryPlayCustomMusic()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0061: Expected O, but got Unknown
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "start")
			{
				return;
			}
			AudioClip val = LoadClip();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"[GlitnirExtras] AudioClip não encontrado: glitnirtheme");
				return;
			}
			if ((Object)(object)_menuSource == (Object)null)
			{
				GameObject val2 = new GameObject("GlitnirMenuMusic");
				Object.DontDestroyOnLoad((Object)(object)val2);
				_menuSource = val2.AddComponent<AudioSource>();
			}
			if (!_menuSource.isPlaying)
			{
				_menuSource.clip = val;
				_menuSource.loop = true;
				_menuSource.volume = 1f;
				_menuSource.spatialBlend = 0f;
				_menuSource.Play();
				Debug.Log((object)"[GlitnirExtras] Tema do menu tocando.");
			}
		}

		private static void StopCustomMusic()
		{
			if ((Object)(object)_menuSource != (Object)null && _menuSource.isPlaying)
			{
				_menuSource.Stop();
				Debug.Log((object)"[GlitnirExtras] Música customizada parada — usando música vanilla.");
			}
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(2)]
		private static Sprite LoadSprite()
		{
			if ((Object)(object)_cachedSprite != (Object)null)
			{
				return _cachedSprite;
			}
			AssetBundle val = FindBundle();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			_cachedSprite = val.LoadAsset<Sprite>("Logoglitnirmenu");
			return _cachedSprite;
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(2)]
		private static AudioClip LoadClip()
		{
			if ((Object)(object)_cachedClip != (Object)null)
			{
				return _cachedClip;
			}
			AssetBundle val = FindBundle();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			_cachedClip = val.LoadAsset<AudioClip>("glitnirtheme");
			return _cachedClip;
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(2)]
		private static AssetBundle FindBundle()
		{
			foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
			{
				if ((Object)(object)allLoadedAssetBundle != (Object)null && ((Object)allLoadedAssetBundle).name.Equals("mar_glitnirextras", StringComparison.OrdinalIgnoreCase))
				{
					return allLoadedAssetBundle;
				}
			}
			return null;
		}
	}
	[HarmonyPatch]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	internal static class MenuQuickJoin
	{
		private const bool Enabled = true;

		private const string ButtonText = "Glitnir Origins";

		private const string IP = "177.54.147.114";

		private const int Port = 24444;

		private const string Password = "12457800";

		private static readonly Color VikingsGreen = new Color(0.55f, 1f, 0.55f, 1f);

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
		private static void SetupGui_Postfix(FejdStartup __instance)
		{
			bool flag = false;
			TryApply(__instance);
		}

		private static void TryApply(FejdStartup fs)
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			if ((Object)(object)fs == (Object)null || (Object)(object)fs.m_menuList == (Object)null || fs.m_menuList.GetComponentsInChildren<Button>(true).Any([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Button b) => (Object)(object)b != (Object)null && ((Object)b).name == "Glitnir_QuickJoin"))
			{
				return;
			}
			Button val = ((IEnumerable<Button>)fs.m_menuList.GetComponentsInChildren<Button>(true)).FirstOrDefault((Func<Button, bool>)([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Button b) => (Object)(object)b != (Object)null));
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform.parent == (Object)null))
			{
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent, false);
				((Object)val2).name = "Glitnir_QuickJoin";
				val2.transform.SetSiblingIndex(0);
				SetText(val2, "Glitnir Origins");
				Button component = val2.GetComponent<Button>();
				if (!((Object)(object)component == (Object)null))
				{
					((UnityEventBase)component.onClick).RemoveAllListeners();
					((UnityEvent)component.onClick).AddListener(new UnityAction(OnClick));
				}
			}
		}

		private static void OnClick()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			FejdStartup instance = FejdStartup.m_instance;
			if (!((Object)(object)instance == (Object)null))
			{
				FejdStartup.ServerPassword = "12457800";
				ServerJoinData val = default(ServerJoinData);
				((ServerJoinData)(ref val))..ctor(new ServerJoinDataDedicated(string.Format("{0}:{1}", "177.54.147.114", 24444)));
				AccessTools.Field(typeof(FejdStartup), "m_queuedJoinServer")?.SetValue(instance, val);
				AccessTools.Method(typeof(FejdStartup), "HideAll", (Type[])null, (Type[])null)?.Invoke(instance, Array.Empty<object>());
				AccessTools.Method(typeof(FejdStartup), "ShowCharacterSelection", (Type[])null, (Type[])null)?.Invoke(instance, Array.Empty<object>());
			}
		}

		private static void SetText(GameObject go, string text)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			Text[] componentsInChildren = go.GetComponentsInChildren<Text>(true);
			foreach (Text val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.text = text;
					((Graphic)val).color = VikingsGreen;
				}
			}
			Component[] componentsInChildren2 = go.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Type type = ((object)val2).GetType();
				string text2 = type.FullName ?? "";
				if (text2.StartsWith("TMPro.", StringComparison.Ordinal))
				{
					PropertyInfo property = type.GetProperty("text");
					if (property != null && property.CanWrite)
					{
						property.SetValue(val2, text);
					}
					PropertyInfo property2 = type.GetProperty("color");
					if (property2 != null && property2.CanWrite && property2.PropertyType == typeof(Color))
					{
						property2.SetValue(val2, VikingsGreen);
					}
				}
			}
		}
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	internal static class TP_OnlyOwner_Indestructible_Terrain
	{
		[HarmonyPatch(typeof(ZRoutedRpc), "InvokeRoutedRPC", new Type[]
		{
			typeof(long),
			typeof(string),
			typeof(object[])
		})]
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		internal static class TP_BlockChangeModeRpc
		{
			[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
			private static bool Prefix(string methodName, object[] parameters)
			{
				if (methodName != "TargetPortals ChangePortalMode")
				{
					return true;
				}
				if (parameters == null || parameters.Length == 0)
				{
					return true;
				}
				ZNetView val = FindNviewFromZdoid(parameters[0]);
				if ((Object)(object)val == (Object)null || !val.IsValid())
				{
					return true;
				}
				if (!IsTargetPortal(val))
				{
					return true;
				}
				if (!IsOwnerOrAdmin(val))
				{
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "Este portal está protegido", 0, (Sprite)null);
					}
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(WearNTear), "Damage")]
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		internal static class TP_Indestructible_NoDamage
		{
			[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
			private static bool Prefix(WearNTear __instance)
			{
				return (Object)(object)((Component)__instance).GetComponent<TeleportWorld>() == (Object)null;
			}
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		[HarmonyPatch(typeof(WearNTear), "Remove")]
		internal static class TP_Indestructible_NoRemove
		{
			[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
			private static bool Prefix(WearNTear __instance)
			{
				TeleportWorld component = ((Component)__instance).GetComponent<TeleportWorld>();
				if ((Object)(object)component == (Object)null)
				{
					return true;
				}
				if ((Object)(object)component.m_nview == (Object)null || !component.m_nview.IsValid())
				{
					return true;
				}
				if (!IsTargetPortal(component.m_nview))
				{
					return true;
				}
				return IsOwnerOrAdmin(component.m_nview);
			}
		}

		[HarmonyPatch(typeof(PrivateArea), "CheckAccess")]
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		internal static class TP_Terrain_PrivateArea
		{
			private static void Postfix(Vector3 point, bool flash, ref bool __result)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (__result && IsNearProtectedTargetPortal(point))
				{
					if (flash && (Object)(object)Player.m_localPlayer != (Object)null)
					{
						((Character)Player.m_localPlayer).Message((MessageType)2, "O Terreno está protegido.", 0, (Sprite)null);
					}
					__result = false;
				}
			}
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		[HarmonyPatch(typeof(Location), "IsInsideNoBuildLocation")]
		internal static class TP_Terrain_NoBuildLocation
		{
			private static void Postfix(Vector3 point, ref bool __result)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				if (!__result && IsNearProtectedTargetPortal(point))
				{
					__result = true;
				}
			}
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		[HarmonyPatch(typeof(TerrainComp), "ApplyOperation")]
		internal static class TP_Terrain_BlockTerraform
		{
			[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
			private static bool Prefix(TerrainOp modifier)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)modifier == (Object)null)
				{
					return true;
				}
				Vector3 position = ((Component)modifier).transform.position;
				if (IsNearProtectedTargetPortal(position))
				{
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "O Terreno está protegido.", 0, (Sprite)null);
					}
					return false;
				}
				return true;
			}
		}

		private const float TERRAIN_PROTECTION_RADIUS = 4f;

		private const float SEARCH_RADIUS = 30f;

		private const string ZdoOwnerKey = "TargetPortal PortalOwnerId";

		private const string RpcChangeMode = "TargetPortals ChangePortalMode";

		private const string MsgProtected = "Este portal está protegido";

		private const string MsgTerrain = "O Terreno está protegido.";

		private static string Norm(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return "";
			}
			return s.Replace("Steam_", "");
		}

		private static bool IsOwnerOrAdmin(ZNetView nview)
		{
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid())
			{
				return false;
			}
			if (GlitnirExtrasPlugin.IsLocalPlayerAdmin())
			{
				return true;
			}
			ZDO zDO = nview.GetZDO();
			if (zDO == null)
			{
				return false;
			}
			string text = Norm(zDO.GetString("TargetPortal PortalOwnerId", ""));
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string text2 = "";
			try
			{
				text2 = Norm(((object)(PlatformUserID)(ref UserInfo.GetLocalUser().UserId)).ToString());
			}
			catch
			{
				text2 = "";
			}
			if (!string.IsNullOrEmpty(text2) && text == text2)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				long @long = zDO.GetLong(ZDOVars.s_creator, 0L);
				if (@long != 0L && @long == localPlayer.GetPlayerID())
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsTargetPortal(ZNetView nview)
		{
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid())
			{
				return false;
			}
			ZDO zDO = nview.GetZDO();
			if (zDO == null)
			{
				return false;
			}
			int @int = zDO.GetInt("TargetPortal PortalMode", -1);
			string @string = zDO.GetString("TargetPortal PortalOwnerId", "");
			return @int != -1 || !string.IsNullOrEmpty(@string);
		}

		[return: <7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static ZNetView FindNviewFromZdoid(object firstParam)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!(firstParam is ZDOID key) || 1 == 0)
			{
				return null;
			}
			if (ZDOMan.instance == null || ZDOMan.instance.m_objectsByID == null)
			{
				return null;
			}
			if (!ZDOMan.instance.m_objectsByID.TryGetValue(key, out var value))
			{
				return null;
			}
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			return ZNetScene.instance.FindInstance(value);
		}

		private static bool IsNearProtectedTargetPortal(Vector3 point)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			Collider[] array = Physics.OverlapSphere(point, 30f);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				TeleportWorld componentInParent = ((Component)val).GetComponentInParent<TeleportWorld>();
				if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.m_nview == (Object)null) && componentInParent.m_nview.IsValid() && IsTargetPortal(componentInParent.m_nview))
				{
					float num = Vector3.Distance(point, ((Component)componentInParent).transform.position);
					if (!(num > 4f) && !IsOwnerOrAdmin(componentInParent.m_nview))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public static class Patch_WearNTear
	{
		private static ConfigEntry<bool> DisableWearNTear;

		private static ConfigEntry<bool> DisableRainDamage;

		private static ConfigEntry<bool> DisableOceanDamage;

		private static ConfigEntry<bool> DisableFireDamage;

		private static ConfigEntry<bool> DisableStructuralIntegrity;

		private static ConfigEntry<float> StructuralIntegrityMultiplier;

		private static readonly FieldInfo FI_m_support = AccessTools.Field(typeof(WearNTear), "m_support");

		private static readonly FieldInfo FI_m_nview = AccessTools.Field(typeof(WearNTear), "m_nview");

		private static readonly MethodInfo MI_GetMaxSupport = AccessTools.Method(typeof(WearNTear), "GetMaxSupport", (Type[])null, (Type[])null);

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			DisableWearNTear = plugin.config("WearNTear", "DisableWearNTear", value: true, "Completely disable weather/time wear (skips WearNTear.UpdateWear).");
			DisableRainDamage = plugin.config("WearNTear", "DisableRainDamage", value: true, "Placeholder. Global wear toggle already disables rain wear.");
			DisableOceanDamage = plugin.config("WearNTear", "DisableOceanDamage", value: true, "Placeholder. Global wear toggle already disables ocean wear.");
			DisableFireDamage = plugin.config("WearNTear", "DisableFireDamage", value: true, "Blocks fire damage to structures (handled in RPC_Damage).");
			DisableStructuralIntegrity = plugin.config("WearNTear", "DisableStructuralIntegrity", value: false, "Completely disable structural integrity (everything is fully supported).");
			StructuralIntegrityMultiplier = plugin.config("WearNTear", "StructuralIntegrityMultiplier", 1f, "Support multiplier (1.0 = vanilla, 1.5 = +50% stronger). Only used when integrity is enabled.");
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, "WearNTear patches active (no auto-repair).", 0, (Sprite)null);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(WearNTear), "UpdateWear")]
		private static bool WearNTear_UpdateWear_Prefix()
		{
			return !DisableWearNTear.Value;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(WearNTear), "RPC_Damage")]
		private static bool WearNTear_RPC_Damage_Prefix(WearNTear __instance, HitData hit)
		{
			if (!DisableFireDamage.Value || hit == null)
			{
				return true;
			}
			if (hit.m_damage.m_fire > 0f)
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
		private static bool WearNTear_UpdateSupport_Prefix(WearNTear __instance)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			if (!DisableStructuralIntegrity.Value)
			{
				return true;
			}
			if (MI_GetMaxSupport != null && FI_m_support != null && FI_m_nview != null)
			{
				float num = (float)MI_GetMaxSupport.Invoke(__instance, null);
				FI_m_support.SetValue(__instance, num);
				ZNetView val = (ZNetView)FI_m_nview.GetValue(__instance);
				if ((Object)(object)val != (Object)null && val.IsValid())
				{
					val.GetZDO().Set(ZDOVars.s_support, num);
				}
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
		private static void WearNTear_UpdateSupport_Postfix(WearNTear __instance)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (!DisableStructuralIntegrity.Value && !Mathf.Approximately(StructuralIntegrityMultiplier.Value, 1f) && FI_m_support != null && FI_m_nview != null)
			{
				float num = (float)FI_m_support.GetValue(__instance);
				num *= StructuralIntegrityMultiplier.Value;
				FI_m_support.SetValue(__instance, num);
				ZNetView val = (ZNetView)FI_m_nview.GetValue(__instance);
				if ((Object)(object)val != (Object)null && val.IsValid())
				{
					val.GetZDO().Set(ZDOVars.s_support, num);
				}
			}
		}
	}
	[HarmonyPatch]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public static class Patch_Workbench
	{
		private static ConfigEntry<float> WorkBenchRange;

		private static ConfigEntry<float> WorkBenchPlayerBase;

		private static ConfigEntry<bool> NoRoofRequirement;

		private static ConfigEntry<float> WorkBenchExtensionRange;

		private static ConfigEntry<bool> AutoRepairWorkbench;

		public static void InitConfig(GlitnirExtrasPlugin plugin)
		{
			WorkBenchRange = plugin.config("Workbench", "WorkBenchRange", 20f, "Range (in meters) you can build from the workbench.");
			WorkBenchPlayerBase = plugin.config("Workbench", "WorkBenchPlayerBase", 20f, "Workbench player base radius (affects enemy spawn distance).");
			NoRoofRequirement = plugin.config("Workbench", "NoRoofRequirement", value: false, "Removes the need for a roof or exposure for the workbench to function.");
			WorkBenchExtensionRange = plugin.config("Workbench", "WorkBenchExtensionRange", 5f, "Range for workbench extensions.");
			AutoRepairWorkbench = plugin.config("Workbench", "AutoRepairWorkbench", value: true, "If true, automatically repairs all items when interacting with a workbench.");
		}

		[HarmonyPatch(typeof(CraftingStation), "Start")]
		[HarmonyPostfix]
		private static void CraftingStation_Start_Postfix(CraftingStation __instance)
		{
			if (WorkBenchRange.Value > 0f)
			{
				__instance.m_rangeBuild = WorkBenchRange.Value;
			}
			if (WorkBenchPlayerBase.Value > 0f && (Object)(object)__instance.m_areaMarkerCircle != (Object)null)
			{
				__instance.m_areaMarkerCircle.m_radius = WorkBenchPlayerBase.Value;
			}
			if (WorkBenchExtensionRange.Value > 0f && WorkBenchRange.Value >= 5f)
			{
				__instance.m_extraRangePerLevel = WorkBenchExtensionRange.Value;
			}
			if (NoRoofRequirement.Value)
			{
				__instance.m_craftRequireRoof = false;
			}
		}

		[HarmonyPatch(typeof(CraftingStation), "CheckUsable")]
		[HarmonyPrefix]
		private static bool CraftingStation_CheckUsable_Prefix(CraftingStation __instance, Player player, bool showMessage, ref bool __result)
		{
			if (!NoRoofRequirement.Value)
			{
				return true;
			}
			__result = true;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InventoryGui), "UpdateRepair")]
		private static void InventoryGui_UpdateRepair_Prefix(InventoryGui __instance)
		{
			//IL_0071: 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)
			if (AutoRepairWorkbench == null || !AutoRepairWorkbench.Value)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			CraftingStation val = ((localPlayer != null) ? localPlayer.GetCurrentCraftingStation() : null);
			if (!((Object)(object)val == (Object)null))
			{
				int num = 0;
				while (__instance.HaveRepairableItems())
				{
					__instance.RepairOneItem();
					num++;
				}
				if (num > 0)
				{
					val.m_repairItemDoneEffects.Create(((Component)val).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
		private static IEnumerable<CodeInstruction> InventoryGui_RepairOneItem_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(EffectList), "Create", (Type[])null, (Type[])null);
			MethodInfo operand = AccessTools.Method(typeof(Patch_Workbench), "NoopEffect", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					list[i].opcode = OpCodes.Call;
					list[i].operand = operand;
				}
			}
			return list.AsEnumerable();
		}

		private static GameObject[] NoopEffect(Vector3 pos, Quaternion rot, Transform parent, float scale, int variant)
		{
			return null;
		}
	}
}
namespace PieceManager
{
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[PublicAPI]
	public static class MaterialReplacer
	{
		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		public enum ShaderType
		{
			PieceShader,
			VegetationShader,
			RockShader,
			RugShader,
			GrassShader,
			CustomCreature,
			UseUnityShader
		}

		private static readonly Dictionary<GameObject, bool> ObjectToSwap;

		private static readonly Dictionary<string, Material> OriginalMaterials;

		private static readonly Dictionary<GameObject, ShaderType> ObjectsForShaderReplace;

		private static readonly HashSet<Shader> CachedShaders;

		private static bool hasRun;

		static MaterialReplacer()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			CachedShaders = new HashSet<Shader>();
			hasRun = false;
			OriginalMaterials = new Dictionary<string, Material>();
			ObjectToSwap = new Dictionary<GameObject, bool>();
			ObjectsForShaderReplace = new Dictionary<GameObject, ShaderType>();
			Harmony val = new Harmony("org.bepinex.helpers.PieceManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaterialReplacer), "ReplaceAllMaterialsWithOriginal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void RegisterGameObjectForShaderSwap(GameObject go, ShaderType type)
		{
			if (!ObjectsForShaderReplace.ContainsKey(go))
			{
				ObjectsForShaderReplace.Add(go, type);
			}
		}

		public static void RegisterGameObjectForMatSwap(GameObject go, bool isJotunnMock = false)
		{
			if (!ObjectToSwap.ContainsKey(go))
			{
				ObjectToSwap.Add(go, isJotunnMock);
			}
		}

		private static void GetAllMaterials()
		{
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val in array)
			{
				OriginalMaterials[((Object)val).name] = val;
			}
		}

		[HarmonyPriority(700)]
		private static void ReplaceAllMaterialsWithOriginal()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)SystemInfo.graphicsDeviceType == 4 || hasRun)
			{
				return;
			}
			if (OriginalMaterials.Count == 0)
			{
				GetAllMaterials();
			}
			foreach (KeyValuePair<GameObject, bool> item in ObjectToSwap)
			{
				GameObject key = item.Key;
				bool value = item.Value;
				ProcessGameObjectMaterials(key, value);
			}
			AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>();
			AssetBundle[] array2 = array;
			foreach (AssetBundle val in array2)
			{
				IEnumerable<Shader> enumerable3;
				try
				{
					IEnumerable<Shader> enumerable2;
					if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val))
					{
						IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>();
						enumerable2 = enumerable;
					}
					else
					{
						enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>)
							where (Object)(object)shader != (Object)null
							select shader;
					}
					enumerable3 = enumerable2;
				}
				catch (Exception)
				{
					continue;
				}
				if (enumerable3 == null)
				{
					continue;
				}
				foreach (Shader item2 in enumerable3)
				{
					CachedShaders.Add(item2);
				}
			}
			foreach (KeyValuePair<GameObject, ShaderType> item3 in ObjectsForShaderReplace)
			{
				GameObject key2 = item3.Key;
				ShaderType value2 = item3.Value;
				ProcessGameObjectShaders(key2, value2);
			}
			hasRun = true;
		}

		private static void ProcessGameObjectMaterials(GameObject go, bool isJotunnMock)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] sharedMaterials = val.sharedMaterials.Select([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Material material) => ReplaceMaterial(material, isJotunnMock)).ToArray();
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static Material ReplaceMaterial(Material originalMaterial, bool isJotunnMock)
		{
			string text = (isJotunnMock ? "JVLmock_" : "_REPLACE_");
			if (!((Object)originalMaterial).name.StartsWith(text, StringComparison.Ordinal))
			{
				return originalMaterial;
			}
			string text2 = ((Object)originalMaterial).name.Replace(" (Instance)", "").Replace(text, "");
			if (OriginalMaterials.TryGetValue(text2, out var value))
			{
				return value;
			}
			Debug.LogWarning((object)("No suitable material found to replace: " + text2));
			return originalMaterial;
		}

		private static void ProcessGameObjectShaders(GameObject go, ShaderType shaderType)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.shader = GetShaderForType(val2.shader, shaderType, ((Object)val2.shader).name);
					}
				}
			}
		}

		private static Shader GetShaderForType(Shader orig, ShaderType shaderType, string originalShaderName)
		{
			return (Shader)(shaderType switch
			{
				ShaderType.PieceShader => FindShaderWithName(orig, "Custom/Piece"), 
				ShaderType.VegetationShader => FindShaderWithName(orig, "Custom/Vegetation"), 
				ShaderType.RockShader => FindShaderWithName(orig, "Custom/StaticRock"), 
				ShaderType.RugShader => FindShaderWithName(orig, "Custom/Rug"), 
				ShaderType.GrassShader => FindShaderWithName(orig, "Custom/Grass"), 
				ShaderType.CustomCreature => FindShaderWithName(orig, "Custom/Creature"), 
				ShaderType.UseUnityShader => FindShaderWithName(orig, ((Object)(object)FindShaderWithName(orig, originalShaderName) != (Object)null) ? originalShaderName : "ToonDeferredShading2017"), 
				_ => FindShaderWithName(orig, "Standard"), 
			});
		}

		public static Shader FindShaderWithName(Shader origShader, string name)
		{
			foreach (Shader cachedShader in CachedShaders)
			{
				if (((Object)cachedShader).name == name)
				{
					return cachedShader;
				}
			}
			return origShader;
		}
	}
	[PublicAPI]
	public enum CraftingTable
	{
		None,
		[InternalName("piece_workbench")]
		Workbench,
		[InternalName("piece_cauldron")]
		Cauldron,
		[InternalName("forge")]
		Forge,
		[InternalName("piece_artisanstation")]
		ArtisanTable,
		[InternalName("piece_stonecutter")]
		StoneCutter,
		[InternalName("piece_magetable")]
		MageTable,
		[InternalName("blackforge")]
		BlackForge,
		[InternalName("piece_preptable")]
		FoodPreparationTable,
		[InternalName("piece_MeadCauldron")]
		MeadKetill,
		Custom
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[PublicAPI]
	public class ExtensionList
	{
		public readonly List<ExtensionConfig> ExtensionStations = new List<ExtensionConfig>();

		public void Set(CraftingTable table, int maxStationDistance = 5)
		{
			ExtensionStations.Add(new ExtensionConfig
			{
				Table = table,
				maxStationDistance = maxStationDistance
			});
		}

		public void Set(string customTable, int maxStationDistance = 5)
		{
			ExtensionStations.Add(new ExtensionConfig
			{
				Table = CraftingTable.Custom,
				custom = customTable,
				maxStationDistance = maxStationDistance
			});
		}
	}
	public struct ExtensionConfig
	{
		public CraftingTable Table;

		public float maxStationDistance;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		public string custom;
	}
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[PublicAPI]
	public class CraftingStationList
	{
		public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>();

		public void Set(CraftingTable table)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = table
			});
		}

		public void Set(string customTable)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = CraftingTable.Custom,
				custom = customTable
			});
		}
	}
	public struct CraftingStationConfig
	{
		public CraftingTable Table;

		public int level;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		public string custom;
	}
	[PublicAPI]
	public enum BuildPieceCategory
	{
		Misc = 0,
		Crafting = 1,
		BuildingWorkbench = 2,
		BuildingStonecutter = 3,
		Furniture = 4,
		All = 100,
		Custom = 99
	}
	[PublicAPI]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	public class RequiredResourcesList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public void Add(string item, int amount, bool recover)
		{
			Requirements.Add(new Requirement
			{
				itemName = item,
				amount = amount,
				recover = recover
			});
		}
	}
	public struct Requirement
	{
		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(1)]
		public string itemName;

		public int amount;

		public bool recover;
	}
	public struct SpecialProperties
	{
		[Description("Admins should be the only ones that can build this piece.")]
		public bool AdminOnly;

		[Description("Turns off generating a config for this build piece.")]
		public bool NoConfig;
	}
	[PublicAPI]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public class BuildingPieceCategory
	{
		public BuildPieceCategory Category;

		public string custom = "";

		public void Set(BuildPieceCategory category)
		{
			Category = category;
		}

		public void Set(string customCategory)
		{
			Category = BuildPieceCategory.Custom;
			custom = customCategory;
		}
	}
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[PublicAPI]
	public class PieceTool
	{
		public readonly HashSet<string> Tools = new HashSet<string>();

		public void Add(string tool)
		{
			Tools.Add(tool);
		}
	}
	[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
	[PublicAPI]
	[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(1)]
	public class BuildPiece
	{
		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
		internal class PieceConfig
		{
			public ConfigEntry<string> craft = null;

			public ConfigEntry<BuildPieceCategory> category = null;

			public ConfigEntry<string> customCategory = null;

			public ConfigEntry<string> tools = null;

			public ConfigEntry<CraftingTable> extensionTable = null;

			public ConfigEntry<string> customExtentionTable = null;

			public ConfigEntry<float> maxStationDistance = null;

			public ConfigEntry<CraftingTable> table = null;

			public ConfigEntry<string> customTable = null;
		}

		[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
			public string Category;

			[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(0)]
		private class SerializedRequirements
		{
			public readonly List<Requirement> Reqs;

			public SerializedRequirements(List<Requirement> reqs)
			{
				Reqs = reqs;
			}

			public SerializedRequirements(string reqs)
			{
				Reqs = reqs.Split(new char[1] { ',' }).Select([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (string r) =>
				{
					string[] array = r.Split(new char[1] { ':' });
					Requirement result = default(Requirement);
					result.itemName = array[0];
					result.amount = ((array.Length <= 1 || !int.TryParse(array[1], out var result2)) ? 1 : result2);
					bool result3 = default(bool);
					result.recover = array.Length <= 2 || !bool.TryParse(array[2], out result3) || result3;
					return result;
				}).ToList();
			}

			public override string ToString()
			{
				return string.Join(",", Reqs.Select([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}:{r.recover}"));
			}

			[return: <7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
			public static ItemDrop fetchByName(ObjectDB objectDB, string name)
			{
				GameObject itemPrefab = objectDB.GetItemPrefab(name);
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)(((!string.IsNullOrWhiteSpace(((Object)plugin).name)) ? ("[" + ((Object)plugin).name + "]") : "") + " The required item '" + name + "' does not exist."));
				}
				return val;
			}

			public static Requirement[] toPieceReqs(SerializedRequirements craft)
			{
				Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Requirement r) => r.itemName), (Func<Requirement, Requirement>)([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Requirement r) =>
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: 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_0025: Unknown result type (might be due to invalid IL or missing references)
					ItemDrop val = ResItem(r);
					return (val == null) ? ((Requirement)null) : new Requirement
					{
						m_amount = r.amount,
						m_resItem = val,
						m_recover = r.recover
					};
				}));
				return dictionary.Values.Where([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (Requirement v) => v != null).ToArray();
				[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(2)]
				static ItemDrop ResItem(Requirement r)
				{
					return fetchByName(ObjectDB.instance, r.itemName);
				}
			}
		}

		internal static readonly List<BuildPiece> registeredPieces = new List<BuildPiece>();

		private static readonly Dictionary<Piece, BuildPiece> pieceMap = new Dictionary<Piece, BuildPiece>();

		internal static Dictionary<BuildPiece, PieceConfig> pieceConfigs = new Dictionary<BuildPiece, PieceConfig>();

		internal List<Conversion> Conversions = new List<Conversion>();

		internal List<ItemConversion> conversions = new List<ItemConversion>();

		[Description("Disables generation of the configs for your pieces. This is global, this turns it off for all pieces in your mod.")]
		public static bool ConfigurationEnabled = true;

		public readonly GameObject Prefab;

		[Description("Specifies the resources needed to craft the piece.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the building piece should need.")]
		public readonly RequiredResourcesList RequiredItems = new RequiredResourcesList();

		[Description("Sets the category for the building piece.")]
		public readonly BuildingPieceCategory Category = new BuildingPieceCategory();

		[Description("Specifies the tool needed to build your piece.\nUse .Add to add a tool.")]
		public readonly PieceTool Tool = new PieceTool();

		[Description("Specifies the crafting station needed to build your piece.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.")]
		public CraftingStationList Crafting = new CraftingStationList();

		[Description("Makes this piece a station extension")]
		public ExtensionList Extension = new ExtensionList();

		[Description("Change the extended/special properties of your build piece.")]
		public SpecialProperties SpecialProperties;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		[Description("Specifies a config entry which toggles whether a recipe is active.")]
		public ConfigEntryBase RecipeIsActive = null;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private LocalizeKey _name;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private LocalizeKey _description;

		internal string[] activeTools = null;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static object configManager;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static Localization _english;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		internal static BaseUnityPlugin _plugin = null;

		private static bool hasConfigSync = true;

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static object _configSync;

		public LocalizeKey Name
		{
			get
			{
				LocalizeKey name = _name;
				if (name != null)
				{
					return name;
				}
				Piece component = Prefab.GetComponent<Piece>();
				if (component.m_name.StartsWith("$"))
				{
					_name = new LocalizeKey(component.m_name);
				}
				else
				{
					string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_");
					_name = new LocalizeKey(text).English(component.m_name);
					component.m_name = text;
				}
				return _name;
			}
		}

		public LocalizeKey Description
		{
			get
			{
				LocalizeKey description = _description;
				if (description != null)
				{
					return description;
				}
				Piece component = Prefab.GetComponent<Piece>();
				if (component.m_description.StartsWith("$"))
				{
					_description = new LocalizeKey(component.m_description);
				}
				else
				{
					string text = "$piece_" + ((Object)Prefab).name.Replace(" ", "_") + "_description";
					_description = new LocalizeKey(text).English(component.m_description);
					component.m_description = text;
				}
				return _description;
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		internal static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Expected O, but got Unknown
				if (_plugin != null)
				{
					return _plugin;
				}
				IEnumerable<TypeInfo> source;
				try
				{
					source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
				}
				catch (ReflectionTypeLoadException ex)
				{
					source = from t in ex.Types
						where t != null
						select t.GetTypeInfo();
				}
				_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				return _plugin;
			}
		}

		[<7de5f404-617b-498f-94c8-3c81d5a82a72>Nullable(2)]
		private static object configSync
		{
			[<bb937bf9-9174-4794-9b96-8c95c0931223>NullableContext(2)]
			get
			{
				if (_configSync != null || !hasConfigSync)
				{
					return _configSync;
				}
				Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
				if ((object)type != null)
				{
					_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " PieceManager");
					type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
					type.GetProperty("IsLocked").SetValue(_configSync, true);
				}
				else
				{
					hasConfigSync = false;
				}
				return _configSync;
			}
		}

		public BuildPiece(string assetBundleFileName, string prefabName, string folderName = "assets")
			: this(PiecePrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName)
		{
		}

		public BuildPiece(AssetBundle bundle, string prefabName)
		{
			Prefab = PiecePrefabManager.RegisterPrefab(bundle, prefabName);
			registeredPieces.Add(this);
		}

		internal static void Patch_FejdStartup(FejdStartup __instance)
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to inval