Decompiled source of Captain territorial v1.0.87

Captain_territorial.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Captain_territorial
{
	public static class SimpleVFX
	{
		private class AutoCleanup : MonoBehaviour
		{
			private float _delay;

			public static void Schedule(GameObject target, float delay)
			{
				if (!((Object)(object)target == (Object)null))
				{
					target.AddComponent<AutoCleanup>()._delay = delay;
				}
			}

			private void Start()
			{
				((MonoBehaviour)this).StartCoroutine(Run());
			}

			private IEnumerator Run()
			{
				yield return (object)new WaitForSeconds(_delay);
				((Component)this).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private static GameObject _cachedAuraPrefab;

		private static bool _initialized;

		public static void Initialize()
		{
			if (!_initialized)
			{
				_initialized = true;
				_cachedAuraPrefab = LoadEmbeddedPrefab("buff_03a_aura");
			}
		}

		private static GameObject LoadEmbeddedPrefab(string vfxName)
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = null;
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text2 in manifestResourceNames)
				{
					if (text2.EndsWith("." + vfxName))
					{
						text = text2;
						break;
					}
				}
				if (text == null)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("[SimpleVFX] '" + vfxName + "' 리소스 없음"));
					}
					return null;
				}
				AssetBundle val;
				using (Stream stream = executingAssembly.GetManifestResourceStream(text))
				{
					if (stream == null)
					{
						return null;
					}
					val = AssetBundle.LoadFromStream(stream);
				}
				GameObject[] array = (((Object)(object)val != (Object)null) ? val.LoadAllAssets<GameObject>() : null);
				return (array != null && array.Length != 0) ? array[0] : null;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[SimpleVFX] '" + vfxName + "' 로드 실패: " + ex.Message));
				}
				return null;
			}
		}

		public static GameObject PlayAura(Vector3 position, float duration)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cachedAuraPrefab == (Object)null)
			{
				return null;
			}
			GameObject val = InstantiateWithoutNetworking(_cachedAuraPrefab, position);
			AutoCleanup.Schedule(val, duration);
			return val;
		}

		public static void PlaySound(string sfxName, Vector3 position, float duration)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayZNetScenePrefab(sfxName, position, duration, "sfx");
		}

		public static void PlayVFX(string vfxName, Vector3 position, float duration)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayZNetScenePrefab(vfxName, position, duration, "vfx");
		}

		private static void PlayZNetScenePrefab(string prefabName, Vector3 position, float duration, string logTag)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(prefabName) || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[SimpleVFX] " + logTag + " '" + prefabName + "' 프리팹 없음"));
				}
			}
			else
			{
				GameObject target = InstantiateWithoutNetworking(prefab, position);
				AutoCleanup.Schedule(target, duration);
			}
		}

		private static GameObject InstantiateWithoutNetworking(GameObject prefab, Vector3 position)
		{
			//IL_0011: 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)
			bool activeSelf = prefab.activeSelf;
			prefab.SetActive(false);
			GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
			prefab.SetActive(activeSelf);
			ZNetView component = val.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			ZSyncTransform component2 = val.GetComponent<ZSyncTransform>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
			val.SetActive(true);
			return val;
		}
	}
	public static class VFXManager
	{
		public static bool VFX_ENABLED = true;

		private static readonly Vector3[] ConsumeAuraOffsets = (Vector3[])(object)new Vector3[3]
		{
			new Vector3(-0.3f, 1.5f, 0f),
			new Vector3(0f, 1.8f, 0f),
			new Vector3(0.3f, 1.5f, 0f)
		};

		private const float ConsumeEffectDuration = 3f;

		private const float UpgradeEffectDuration = 3f;

		public static void Initialize()
		{
			SimpleVFX.Initialize();
		}

		public static void PlayVFXMultiplayer(string vfxName, string soundName, Vector3 position, float destroyAfter = 3f)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (VFX_ENABLED)
			{
				if (!string.IsNullOrEmpty(vfxName))
				{
					SimpleVFX.PlayAura(position, destroyAfter);
				}
				if (!string.IsNullOrEmpty(soundName))
				{
					SimpleVFX.PlaySound(soundName, position, destroyAfter);
				}
			}
		}

		public static void PlayIntrusionAlert(Vector3 position)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (VFX_ENABLED)
			{
				SimpleVFX.PlaySound("sfx_morgen_alert", position, 2f);
			}
		}

		public static void PlayWardConsumeEffect(Transform wardTransform)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (VFX_ENABLED && !((Object)(object)wardTransform == (Object)null))
			{
				Vector3[] consumeAuraOffsets = ConsumeAuraOffsets;
				foreach (Vector3 val in consumeAuraOffsets)
				{
					SimpleVFX.PlayAura(wardTransform.TransformPoint(val), 3f);
				}
				SimpleVFX.PlaySound("sfx_dverger_heal_finish", wardTransform.position, 3f);
			}
		}

		public static void PlayUpgradeEffect(Vector3 position)
		{
			//IL_0014: 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)
			if (VFX_ENABLED)
			{
				SimpleVFX.PlayVFX("vfx_shieldgenerator_refuel", position, 3f);
				SimpleVFX.PlaySound("sfx_fader_bell", position, 3f);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "TryPlacePiece")]
	public static class Patch_Player_TryPlacePiece
	{
		private static readonly string[] s_alwaysAllowedPieces = new string[8] { "piece_workbench", "portal_wood", "Cart", "Raft", "Karve", "VikingShip", "VikingShip_Ashlands", "piece_sapcollector" };

		private static bool Prefix(Player __instance, ref bool __result)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			GameObject placementGhost = __instance.m_placementGhost;
			if ((Object)(object)placementGhost == (Object)null)
			{
				return true;
			}
			Vector3 position = placementGhost.transform.position;
			string name = ((Object)placementGhost).name;
			string[] array = s_alwaysAllowedPieces;
			foreach (string value in array)
			{
				if (name.Contains(value))
				{
					return true;
				}
			}
			if (TerritoryWard.IsBasicCampfire(name))
			{
				return true;
			}
			if (TerritoryWard.IsTreeSapling(name))
			{
				return true;
			}
			if (TerritoryWard.IsInsideDungeon(position))
			{
				return true;
			}
			if (name.Contains("territoryward"))
			{
				if (!TerritoryConfig.Enabled.Value)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_disabled", 0, (Sprite)null);
					__result = false;
					return false;
				}
				if (!TerritoryConfig.IsAdminBypassActive() && CountPlayerWards() >= TerritoryConfig.WardLimit.Value)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_limit_reached", 0, (Sprite)null);
					__result = false;
					return false;
				}
				if (TerritoryWard.IsInsideActiveWard(position))
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_no_overlap", 0, (Sprite)null);
					__result = false;
					return false;
				}
				return true;
			}
			if (!TerritoryWard.IsInsideActiveWard(position))
			{
				string text = (TerritoryWard.IsInsideDeactivatedWard(position) ? "$territoryward_must_activate" : "$territoryward_no_build");
				((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null);
				__result = false;
				return false;
			}
			return true;
		}

		private static int CountPlayerWards()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return 0;
			}
			long playerID = Player.m_localPlayer.GetPlayerID();
			int num = 0;
			foreach (PrivateArea s_ward in TerritoryWard.s_wards)
			{
				if (!((Object)(object)s_ward == (Object)null))
				{
					ZNetView component = ((Component)s_ward).GetComponent<ZNetView>();
					if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetLong("creator", 0L) == playerID)
					{
						num++;
					}
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(Player), "RemovePiece")]
	public static class Patch_Player_RemovePiece_WardCreatorOnly
	{
		private static bool Prefix(Player __instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val, 50f, __instance.m_removeRayMask))
			{
				return true;
			}
			if (Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)__instance).m_eye.position) >= __instance.m_maxPlaceDistance)
			{
				return true;
			}
			Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
			if ((Object)(object)componentInParent == (Object)null || !((Object)((Component)componentInParent).gameObject).name.Contains("territoryward"))
			{
				return true;
			}
			if (componentInParent.IsCreator())
			{
				return true;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.LocalPlayerIsAdminOrHost())
			{
				return true;
			}
			((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_remove_creator_only", 0, (Sprite)null);
			return false;
		}
	}
	public static class TerritoryConfig
	{
		public struct WardSize
		{
			public float Width;

			public float Depth;
		}

		public struct FuelTier
		{
			public int Level;

			public string ItemA;

			public int AmountA;

			public string ItemB;

			public int AmountB;

			public string ItemC;

			public int AmountC;

			public float IntervalSeconds;
		}

		public struct UpgradeCostInfo
		{
			public string ItemA;

			public int ItemAAmount;

			public string ItemB;

			public int ItemBAmount;

			public int Coins;
		}

		public static ConfigEntry<bool> AdminBypass;

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<int> WardLimit;

		public static ConfigEntry<KeyCode> UpgradeKey;

		public static ConfigEntry<KeyCode> ShieldKey;

		public static ConfigEntry<KeyCode> RangeRingKey;

		public static ConfigEntry<KeyCode> FuelStorageKey;

		public static ConfigEntry<float> Lv1Width;

		public static ConfigEntry<float> Lv1Depth;

		public static ConfigEntry<string> Lv1FuelA;

		public static ConfigEntry<int> Lv1FuelAAmount;

		public static ConfigEntry<string> Lv1FuelB;

		public static ConfigEntry<int> Lv1FuelBAmount;

		public static ConfigEntry<float> Lv1IntervalMinutes;

		public static ConfigEntry<float> Lv1ShieldMaxHP;

		public static ConfigEntry<float> Lv2Width;

		public static ConfigEntry<float> Lv2Depth;

		public static ConfigEntry<string> Lv2FuelA;

		public static ConfigEntry<int> Lv2FuelAAmount;

		public static ConfigEntry<string> Lv2FuelB;

		public static ConfigEntry<int> Lv2FuelBAmount;

		public static ConfigEntry<float> Lv2IntervalMinutes;

		public static ConfigEntry<float> Lv2ShieldMaxHP;

		public static ConfigEntry<float> Lv3Width;

		public static ConfigEntry<float> Lv3Depth;

		public static ConfigEntry<string> Lv3FuelA;

		public static ConfigEntry<int> Lv3FuelAAmount;

		public static ConfigEntry<string> Lv3FuelB;

		public static ConfigEntry<int> Lv3FuelBAmount;

		public static ConfigEntry<float> Lv3IntervalMinutes;

		public static ConfigEntry<float> Lv3ShieldMaxHP;

		public static ConfigEntry<float> Lv4Width;

		public static ConfigEntry<float> Lv4Depth;

		public static ConfigEntry<string> Lv4FuelA;

		public static ConfigEntry<int> Lv4FuelAAmount;

		public static ConfigEntry<string> Lv4FuelB;

		public static ConfigEntry<int> Lv4FuelBAmount;

		public static ConfigEntry<float> Lv4IntervalMinutes;

		public static ConfigEntry<float> Lv4ShieldMaxHP;

		public static ConfigEntry<float> Lv5Width;

		public static ConfigEntry<float> Lv5Depth;

		public static ConfigEntry<string> Lv5FuelA;

		public static ConfigEntry<int> Lv5FuelAAmount;

		public static ConfigEntry<string> Lv5FuelB;

		public static ConfigEntry<int> Lv5FuelBAmount;

		public static ConfigEntry<float> Lv5IntervalMinutes;

		public static ConfigEntry<float> Lv5ShieldMaxHP;

		public static ConfigEntry<float> Lv6Width;

		public static ConfigEntry<float> Lv6Depth;

		public static ConfigEntry<string> Lv6FuelA;

		public static ConfigEntry<int> Lv6FuelAAmount;

		public static ConfigEntry<string> Lv6FuelB;

		public static ConfigEntry<int> Lv6FuelBAmount;

		public static ConfigEntry<string> Lv6FuelC;

		public static ConfigEntry<int> Lv6FuelCAmount;

		public static ConfigEntry<float> Lv6IntervalMinutes;

		public static ConfigEntry<float> Lv6ShieldMaxHP;

		public static ConfigEntry<float> Lv7Width;

		public static ConfigEntry<float> Lv7Depth;

		public static ConfigEntry<string> Lv7FuelA;

		public static ConfigEntry<int> Lv7FuelAAmount;

		public static ConfigEntry<string> Lv7FuelB;

		public static ConfigEntry<int> Lv7FuelBAmount;

		public static ConfigEntry<float> Lv7IntervalMinutes;

		public static ConfigEntry<float> Lv7ShieldMaxHP;

		public static ConfigEntry<float> Lv8Width;

		public static ConfigEntry<float> Lv8Depth;

		public static ConfigEntry<string> Lv8FuelA;

		public static ConfigEntry<int> Lv8FuelAAmount;

		public static ConfigEntry<string> Lv8FuelB;

		public static ConfigEntry<int> Lv8FuelBAmount;

		public static ConfigEntry<string> Lv8FuelC;

		public static ConfigEntry<int> Lv8FuelCAmount;

		public static ConfigEntry<float> Lv8IntervalMinutes;

		public static ConfigEntry<float> Lv8ShieldMaxHP;

		public static ConfigEntry<string> Lv2UpgradeItemA;

		public static ConfigEntry<int> Lv2UpgradeItemAAmount;

		public static ConfigEntry<string> Lv2UpgradeItemB;

		public static ConfigEntry<int> Lv2UpgradeItemBAmount;

		public static ConfigEntry<int> Lv2UpgradeCoins;

		public static ConfigEntry<string> Lv3UpgradeItemA;

		public static ConfigEntry<int> Lv3UpgradeItemAAmount;

		public static ConfigEntry<string> Lv3UpgradeItemB;

		public static ConfigEntry<int> Lv3UpgradeItemBAmount;

		public static ConfigEntry<int> Lv3UpgradeCoins;

		public static ConfigEntry<string> Lv4UpgradeItemA;

		public static ConfigEntry<int> Lv4UpgradeItemAAmount;

		public static ConfigEntry<string> Lv4UpgradeItemB;

		public static ConfigEntry<int> Lv4UpgradeItemBAmount;

		public static ConfigEntry<int> Lv4UpgradeCoins;

		public static ConfigEntry<string> Lv5UpgradeItemA;

		public static ConfigEntry<int> Lv5UpgradeItemAAmount;

		public static ConfigEntry<string> Lv5UpgradeItemB;

		public static ConfigEntry<int> Lv5UpgradeItemBAmount;

		public static ConfigEntry<int> Lv5UpgradeCoins;

		public static ConfigEntry<string> Lv6UpgradeItemA;

		public static ConfigEntry<int> Lv6UpgradeItemAAmount;

		public static ConfigEntry<string> Lv6UpgradeItemB;

		public static ConfigEntry<int> Lv6UpgradeItemBAmount;

		public static ConfigEntry<int> Lv6UpgradeCoins;

		public static ConfigEntry<string> Lv7UpgradeItemA;

		public static ConfigEntry<int> Lv7UpgradeItemAAmount;

		public static ConfigEntry<string> Lv7UpgradeItemB;

		public static ConfigEntry<int> Lv7UpgradeItemBAmount;

		public static ConfigEntry<int> Lv7UpgradeCoins;

		public static ConfigEntry<string> Lv8UpgradeItemA;

		public static ConfigEntry<int> Lv8UpgradeItemAAmount;

		public static ConfigEntry<string> Lv8UpgradeItemB;

		public static ConfigEntry<int> Lv8UpgradeItemBAmount;

		public static ConfigEntry<int> Lv8UpgradeCoins;

		public static ConfigEntry<bool> DoorAutoCloseEnabled;

		public static ConfigEntry<float> DoorAutoCloseDelay;

		public static ConfigEntry<string> ShieldItemName;

		public static ConfigEntry<bool> PassiveShieldEnabled;

		public static ConfigEntry<float> PassiveShieldRegenPerMinute;

		public static ConfigEntry<float> PassiveShieldContactDamagePerSecond;

		public static ConfigEntry<bool> ShieldDomeVisible;

		public static void Init(ConfigFile cfg)
		{
			AdminBypass = B<bool>("General", "admin_bypass", def: false, "관리자 전용: 켜면 설치 개수 제한·설치 재료비·업그레이드 재료/골드 비용을 모두 무시하고 즉시 설치·업그레이드할 수 있습니다 (연료 유지비는 그대로 적용됩니다).", 200);
			Enabled = B<bool>("General", "territorial_ward", def: true, "영토 와드 시스템 활성화 여부 (false = 비활성화)", 190);
			WardLimit = B<int>("General", "ward_limit", 2, "캐릭터 1명당 설치 가능한 영토 와드 수", 180);
			DoorAutoCloseEnabled = B<bool>("General", "door_auto_close", def: true, "와드 구역 내 문 자동 닫힘 활성화", 170);
			DoorAutoCloseDelay = B<float>("General", "door_auto_close_delay", 5f, "문 자동 닫힘 대기 시간 (초)", 160);
			ShieldItemName = B<string>("General", "shield_item", "SurtlingCore", "Lv5+ 데미지 보호 소모 아이템 (프리팹명)", 150);
			PassiveShieldEnabled = B<bool>("General", "passive_shield_enabled", def: false, "레벨1+ 항상 켜져 있는 패시브 체력형 보호막 기능 전체 활성화 여부 (기본 꺼짐) — 켜면 데미지 흡수, 몬스터 물리 차단, 돔 시각효과, 호버/HUD 수치 표시가 모두 함께 켜집니다. Lv5+ K키 완전무적 실드와는 별개이며 이 설정과 무관하게 항상 사용 가능합니다.", 146);
			PassiveShieldRegenPerMinute = B<float>("General", "passive_shield_regen_per_minute", 1f, "레벨1+ 패시브 보호막 실제 시간 1분당 회복량", 145);
			PassiveShieldContactDamagePerSecond = B<float>("General", "passive_shield_contact_damage_per_second", 15f, "몬스터가 보호막에 몸으로 부딪혀 밀쳐질 때 초당 보호막 소모량", 143);
			ShieldDomeVisible = B<bool>("General", "shield_dome_visible", def: true, "Lv5+ 완전무적/Lv1+ 패시브 보호막 활성 시 돔 시각효과(화면 표시) 표시 여부 — 꺼도 무적/보호막 효과 자체는 그대로 작동합니다", 144);
			UpgradeKey = B<KeyCode>("General", "upgrade_key", (KeyCode)117, "영토 와드 업그레이드 키", 140);
			ShieldKey = B<KeyCode>("General", "shield_key", (KeyCode)107, "Lv5+ 영토 보호 실드 활성화/비활성화 키", 130);
			RangeRingKey = B<KeyCode>("General", "range_ring_key", (KeyCode)114, "범위 링 수동 토글 키", 120);
			FuelStorageKey = B<KeyCode>("General", "fuel_storage_key", (KeyCode)113, "연료 창고 열기 키", 110);
			Lv1Width = B<float>("Level 1 - 초원", "width", 16.5f, "레벨 1 가로 크기 (미터)", 100);
			Lv1Depth = B<float>("Level 1 - 초원", "depth", 16.5f, "레벨 1 세로 크기 (미터)", 99);
			Lv1FuelA = B<string>("Level 1 - 초원", "fuel_primary", "Wood", "레벨 1 주 연료 — 나무 (프리팹명)", 90);
			Lv1FuelAAmount = B<int>("Level 1 - 초원", "fuel_primary_amount", 1, "레벨 1 주 연료 소모량", 89);
			Lv1FuelB = B<string>("Level 1 - 초원", "fuel_secondary", "Resin", "레벨 1 보조 연료 — 수지 (프리팹명)", 88);
			Lv1FuelBAmount = B<int>("Level 1 - 초원", "fuel_secondary_amount", 0, "레벨 1 보조 연료 소모량", 87);
			Lv1IntervalMinutes = B<float>("Level 1 - 초원", "fuel_interval_minutes", 5f, "레벨 1 연료 소모 간격 (분)", 80);
			Lv1ShieldMaxHP = B<float>("Level 1 - 초원", "shield_max_hp", 200f, "레벨 1 패시브 보호막 최대 수치", 75);
			Lv1Width.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1Depth.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1FuelA.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1FuelAAmount.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1FuelB.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1FuelBAmount.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv1IntervalMinutes.SettingChanged += delegate
			{
				TerritoryLocalization.RefreshWardDescription();
			};
			Lv2Width = B<float>("Level 2 - 검은숲", "width", 19.5f, "레벨 2 가로 크기 (미터)", 100);
			Lv2Depth = B<float>("Level 2 - 검은숲", "depth", 19.5f, "레벨 2 세로 크기 (미터)", 99);
			Lv2FuelA = B<string>("Level 2 - 검은숲", "fuel_primary", "RoundLog", "레벨 2 주 연료 — 원목 (프리팹명)", 90);
			Lv2FuelAAmount = B<int>("Level 2 - 검은숲", "fuel_primary_amount", 1, "레벨 2 주 연료 소모량", 89);
			Lv2FuelB = B<string>("Level 2 - 검은숲", "fuel_secondary", "Resin", "레벨 2 보조 연료 — 수지 (프리팹명)", 88);
			Lv2FuelBAmount = B<int>("Level 2 - 검은숲", "fuel_secondary_amount", 0, "레벨 2 보조 연료 소모량", 87);
			Lv2IntervalMinutes = B<float>("Level 2 - 검은숲", "fuel_interval_minutes", 7f, "레벨 2 연료 소모 간격 (분)", 80);
			Lv2ShieldMaxHP = B<float>("Level 2 - 검은숲", "shield_max_hp", 400f, "레벨 2 패시브 보호막 최대 수치", 75);
			Lv2UpgradeItemA = B<string>("Level 2 - 검은숲", "upgrade_item_primary", "RoundLog", "Lv2 업그레이드 주 재료 (원목)", 70);
			Lv2UpgradeItemAAmount = B<int>("Level 2 - 검은숲", "upgrade_item_primary_amount", 10, "Lv2 업그레이드 주 재료 수량", 69);
			Lv2UpgradeItemB = B<string>("Level 2 - 검은숲", "upgrade_item_secondary", "GreydwarfEye", "Lv2 업그레이드 보조 재료 (그레이드워프 눈)", 68);
			Lv2UpgradeItemBAmount = B<int>("Level 2 - 검은숲", "upgrade_item_secondary_amount", 5, "Lv2 업그레이드 보조 재료 수량", 67);
			Lv2UpgradeCoins = B<int>("Level 2 - 검은숲", "upgrade_coins", 0, "Lv2 업그레이드 골드(Coins) 비용", 60);
			Lv3Width = B<float>("Level 3 - 늪지", "width", 24f, "레벨 3 가로 크기 (미터)", 100);
			Lv3Depth = B<float>("Level 3 - 늪지", "depth", 24f, "레벨 3 세로 크기 (미터)", 99);
			Lv3FuelA = B<string>("Level 3 - 늪지", "fuel_primary", "ElderBark", "레벨 3 주 연료 — 고대나무껍질 (프리팹명)", 90);
			Lv3FuelAAmount = B<int>("Level 3 - 늪지", "fuel_primary_amount", 1, "레벨 3 주 연료 소모량", 89);
			Lv3FuelB = B<string>("Level 3 - 늪지", "fuel_secondary", "Resin", "레벨 3 보조 연료 — 수지 (프리팹명)", 88);
			Lv3FuelBAmount = B<int>("Level 3 - 늪지", "fuel_secondary_amount", 0, "레벨 3 보조 연료 소모량", 87);
			Lv3IntervalMinutes = B<float>("Level 3 - 늪지", "fuel_interval_minutes", 9f, "레벨 3 연료 소모 간격 (분)", 80);
			Lv3ShieldMaxHP = B<float>("Level 3 - 늪지", "shield_max_hp", 600f, "레벨 3 패시브 보호막 최대 수치", 75);
			Lv3UpgradeItemA = B<string>("Level 3 - 늪지", "upgrade_item_primary", "ElderBark", "Lv3 업그레이드 주 재료 (고대나무껍질)", 70);
			Lv3UpgradeItemAAmount = B<int>("Level 3 - 늪지", "upgrade_item_primary_amount", 15, "Lv3 업그레이드 주 재료 수량", 69);
			Lv3UpgradeItemB = B<string>("Level 3 - 늪지", "upgrade_item_secondary", "Entrails", "Lv3 업그레이드 보조 재료 (창자)", 68);
			Lv3UpgradeItemBAmount = B<int>("Level 3 - 늪지", "upgrade_item_secondary_amount", 8, "Lv3 업그레이드 보조 재료 수량", 67);
			Lv3UpgradeCoins = B<int>("Level 3 - 늪지", "upgrade_coins", 1000, "Lv3 업그레이드 골드(Coins) 비용", 60);
			Lv4Width = B<float>("Level 4 - 산", "width", 27.5f, "레벨 4 가로 크기 (미터)", 100);
			Lv4Depth = B<float>("Level 4 - 산", "depth", 27.5f, "레벨 4 세로 크기 (미터)", 99);
			Lv4FuelA = B<string>("Level 4 - 산", "fuel_primary", "Obsidian", "레벨 4 주 연료 — 흑요석 (산에는 지역 나무가 없어 대체) (프리팹명)", 90);
			Lv4FuelAAmount = B<int>("Level 4 - 산", "fuel_primary_amount", 1, "레벨 4 주 연료 소모량", 89);
			Lv4FuelB = B<string>("Level 4 - 산", "fuel_secondary", "Resin", "레벨 4 보조 연료 — 수지 (프리팹명)", 88);
			Lv4FuelBAmount = B<int>("Level 4 - 산", "fuel_secondary_amount", 0, "레벨 4 보조 연료 소모량", 87);
			Lv4IntervalMinutes = B<float>("Level 4 - 산", "fuel_interval_minutes", 11f, "레벨 4 연료 소모 간격 (분)", 80);
			Lv4ShieldMaxHP = B<float>("Level 4 - 산", "shield_max_hp", 800f, "레벨 4 패시브 보호막 최대 수치", 75);
			Lv4UpgradeItemA = B<string>("Level 4 - 산", "upgrade_item_primary", "FreezeGland", "Lv4 업그레이드 주 재료 (얼음 분비선)", 70);
			Lv4UpgradeItemAAmount = B<int>("Level 4 - 산", "upgrade_item_primary_amount", 20, "Lv4 업그레이드 주 재료 수량", 69);
			Lv4UpgradeItemB = B<string>("Level 4 - 산", "upgrade_item_secondary", "Obsidian", "Lv4 업그레이드 보조 재료 (흑요석)", 68);
			Lv4UpgradeItemBAmount = B<int>("Level 4 - 산", "upgrade_item_secondary_amount", 11, "Lv4 업그레이드 보조 재료 수량", 67);
			Lv4UpgradeCoins = B<int>("Level 4 - 산", "upgrade_coins", 2000, "Lv4 업그레이드 골드(Coins) 비용", 60);
			Lv5Width = B<float>("Level 5 - 평원", "width", 33f, "레벨 5 가로 크기 (미터)", 100);
			Lv5Depth = B<float>("Level 5 - 평원", "depth", 33f, "레벨 5 세로 크기 (미터)", 99);
			Lv5FuelA = B<string>("Level 5 - 평원", "fuel_primary", "Barley", "레벨 5 주 연료 — 보리 (프리팹명)", 90);
			Lv5FuelAAmount = B<int>("Level 5 - 평원", "fuel_primary_amount", 1, "레벨 5 주 연료 소모량", 89);
			Lv5FuelB = B<string>("Level 5 - 평원", "fuel_secondary", "Resin", "레벨 5 보조 연료 — 수지 (프리팹명)", 88);
			Lv5FuelBAmount = B<int>("Level 5 - 평원", "fuel_secondary_amount", 0, "레벨 5 보조 연료 소모량", 87);
			Lv5IntervalMinutes = B<float>("Level 5 - 평원", "fuel_interval_minutes", 13f, "레벨 5 연료 소모 간격 (분)", 80);
			Lv5ShieldMaxHP = B<float>("Level 5 - 평원", "shield_max_hp", 1000f, "레벨 5 패시브 보호막 최대 수치", 75);
			Lv5UpgradeItemA = B<string>("Level 5 - 평원", "upgrade_item_primary", "Barley", "Lv5 업그레이드 주 재료 (보리)", 70);
			Lv5UpgradeItemAAmount = B<int>("Level 5 - 평원", "upgrade_item_primary_amount", 25, "Lv5 업그레이드 주 재료 수량", 69);
			Lv5UpgradeItemB = B<string>("Level 5 - 평원", "upgrade_item_secondary", "Tar", "Lv5 업그레이드 보조 재료 (타르)", 68);
			Lv5UpgradeItemBAmount = B<int>("Level 5 - 평원", "upgrade_item_secondary_amount", 14, "Lv5 업그레이드 보조 재료 수량", 67);
			Lv5UpgradeCoins = B<int>("Level 5 - 평원", "upgrade_coins", 2500, "Lv5 업그레이드 골드(Coins) 비용", 60);
			Lv6Width = B<float>("Level 6 - 바다", "width", 37.5f, "레벨 6 가로 크기 (미터)", 100);
			Lv6Depth = B<float>("Level 6 - 바다", "depth", 37.5f, "레벨 6 세로 크기 (미터)", 99);
			Lv6FuelA = B<string>("Level 6 - 바다", "fuel_primary", "Wood", "레벨 6 주 연료 — 나무 (바다에는 지역 나무가 없어 나무+원목으로 대체) (프리팹명)", 90);
			Lv6FuelAAmount = B<int>("Level 6 - 바다", "fuel_primary_amount", 1, "레벨 6 주 연료 소모량", 89);
			Lv6FuelB = B<string>("Level 6 - 바다", "fuel_secondary", "Resin", "레벨 6 보조 연료 — 수지 (프리팹명)", 88);
			Lv6FuelBAmount = B<int>("Level 6 - 바다", "fuel_secondary_amount", 0, "레벨 6 보조 연료 소모량", 87);
			Lv6FuelC = B<string>("Level 6 - 바다", "fuel_tertiary", "RoundLog", "레벨 6 추가 연료 — 원목 (프리팹명, 비워두면 미사용)", 86);
			Lv6FuelCAmount = B<int>("Level 6 - 바다", "fuel_tertiary_amount", 1, "레벨 6 추가 연료 소모량", 85);
			Lv6IntervalMinutes = B<float>("Level 6 - 바다", "fuel_interval_minutes", 15f, "레벨 6 연료 소모 간격 (분)", 80);
			Lv6ShieldMaxHP = B<float>("Level 6 - 바다", "shield_max_hp", 1200f, "레벨 6 패시브 보호막 최대 수치", 75);
			Lv6UpgradeItemA = B<string>("Level 6 - 바다", "upgrade_item_primary", "Chitin", "Lv6 업그레이드 주 재료 (키틴)", 70);
			Lv6UpgradeItemAAmount = B<int>("Level 6 - 바다", "upgrade_item_primary_amount", 30, "Lv6 업그레이드 주 재료 수량", 69);
			Lv6UpgradeItemB = B<string>("Level 6 - 바다", "upgrade_item_secondary", "Ooze", "Lv6 업그레이드 보조 재료 (점액)", 68);
			Lv6UpgradeItemBAmount = B<int>("Level 6 - 바다", "upgrade_item_secondary_amount", 17, "Lv6 업그레이드 보조 재료 수량", 67);
			Lv6UpgradeCoins = B<int>("Level 6 - 바다", "upgrade_coins", 3000, "Lv6 업그레이드 골드(Coins) 비용", 60);
			Lv7Width = B<float>("Level 7 - 미스트랜드", "width", 42f, "레벨 7 가로 크기 (미터)", 100);
			Lv7Depth = B<float>("Level 7 - 미스트랜드", "depth", 42f, "레벨 7 세로 크기 (미터)", 99);
			Lv7FuelA = B<string>("Level 7 - 미스트랜드", "fuel_primary", "Wood", "레벨 7 주 연료 — 나무 (프리팹명)", 90);
			Lv7FuelAAmount = B<int>("Level 7 - 미스트랜드", "fuel_primary_amount", 1, "레벨 7 주 연료 소모량", 89);
			Lv7FuelB = B<string>("Level 7 - 미스트랜드", "fuel_secondary", "Resin", "레벨 7 보조 연료 — 수지 (프리팹명)", 88);
			Lv7FuelBAmount = B<int>("Level 7 - 미스트랜드", "fuel_secondary_amount", 0, "레벨 7 보조 연료 소모량", 87);
			Lv7IntervalMinutes = B<float>("Level 7 - 미스트랜드", "fuel_interval_minutes", 17f, "레벨 7 연료 소모 간격 (분)", 80);
			Lv7ShieldMaxHP = B<float>("Level 7 - 미스트랜드", "shield_max_hp", 1500f, "레벨 7 패시브 보호막 최대 수치", 75);
			Lv7UpgradeItemA = B<string>("Level 7 - 미스트랜드", "upgrade_item_primary", "YggdrasilWood", "Lv7 업그레이드 주 재료 (이그드라실 나무)", 70);
			Lv7UpgradeItemAAmount = B<int>("Level 7 - 미스트랜드", "upgrade_item_primary_amount", 35, "Lv7 업그레이드 주 재료 수량", 69);
			Lv7UpgradeItemB = B<string>("Level 7 - 미스트랜드", "upgrade_item_secondary", "JotunPuffs", "Lv7 업그레이드 보조 재료 (요툰 버섯)", 68);
			Lv7UpgradeItemBAmount = B<int>("Level 7 - 미스트랜드", "upgrade_item_secondary_amount", 20, "Lv7 업그레이드 보조 재료 수량", 67);
			Lv7UpgradeCoins = B<int>("Level 7 - 미스트랜드", "upgrade_coins", 4000, "Lv7 업그레이드 골드(Coins) 비용", 60);
			Lv8Width = B<float>("Level 8 - 애쉬랜드", "width", 45f, "레벨 8 가로 크기 (미터)", 100);
			Lv8Depth = B<float>("Level 8 - 애쉬랜드", "depth", 45f, "레벨 8 세로 크기 (미터)", 99);
			Lv8FuelA = B<string>("Level 8 - 애쉬랜드", "fuel_primary", "Wood", "레벨 8 주 연료 — 나무 (애쉬랜드에는 지역 나무가 없어 나무+이그드라실 나무로 대체) (프리팹명)", 90);
			Lv8FuelAAmount = B<int>("Level 8 - 애쉬랜드", "fuel_primary_amount", 1, "레벨 8 주 연료 소모량", 89);
			Lv8FuelB = B<string>("Level 8 - 애쉬랜드", "fuel_secondary", "Resin", "레벨 8 보조 연료 — 수지 (프리팹명)", 88);
			Lv8FuelBAmount = B<int>("Level 8 - 애쉬랜드", "fuel_secondary_amount", 0, "레벨 8 보조 연료 소모량", 87);
			Lv8FuelC = B<string>("Level 8 - 애쉬랜드", "fuel_tertiary", "YggdrasilWood", "레벨 8 추가 연료 — 이그드라실 나무 (프리팹명, 비워두면 미사용)", 86);
			Lv8FuelCAmount = B<int>("Level 8 - 애쉬랜드", "fuel_tertiary_amount", 1, "레벨 8 추가 연료 소모량", 85);
			Lv8IntervalMinutes = B<float>("Level 8 - 애쉬랜드", "fuel_interval_minutes", 20f, "레벨 8 연료 소모 간격 (분)", 80);
			Lv8ShieldMaxHP = B<float>("Level 8 - 애쉬랜드", "shield_max_hp", 2000f, "레벨 8 패시브 보호막 최대 수치", 75);
			Lv8UpgradeItemA = B<string>("Level 8 - 애쉬랜드", "upgrade_item_primary", "CharredBone", "Lv8 업그레이드 주 재료 (불탄 뼈)", 70);
			Lv8UpgradeItemAAmount = B<int>("Level 8 - 애쉬랜드", "upgrade_item_primary_amount", 40, "Lv8 업그레이드 주 재료 수량", 69);
			Lv8UpgradeItemB = B<string>("Level 8 - 애쉬랜드", "upgrade_item_secondary", "Grausten", "Lv8 업그레이드 보조 재료 (그라우스텐 돌)", 68);
			Lv8UpgradeItemBAmount = B<int>("Level 8 - 애쉬랜드", "upgrade_item_secondary_amount", 23, "Lv8 업그레이드 보조 재료 수량", 67);
			Lv8UpgradeCoins = B<int>("Level 8 - 애쉬랜드", "upgrade_coins", 5000, "Lv8 업그레이드 골드(Coins) 비용", 60);
			ConfigEntry<T> B<T>(string section, string key, T def, string desc, int order = 0)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				return cfg.Bind<T>(section, key, def, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = true,
					Order = order
				} }));
			}
		}

		public static WardSize GetSize(int level)
		{
			return level switch
			{
				2 => new WardSize
				{
					Width = Lv2Width.Value,
					Depth = Lv2Depth.Value
				}, 
				3 => new WardSize
				{
					Width = Lv3Width.Value,
					Depth = Lv3Depth.Value
				}, 
				4 => new WardSize
				{
					Width = Lv4Width.Value,
					Depth = Lv4Depth.Value
				}, 
				5 => new WardSize
				{
					Width = Lv5Width.Value,
					Depth = Lv5Depth.Value
				}, 
				6 => new WardSize
				{
					Width = Lv6Width.Value,
					Depth = Lv6Depth.Value
				}, 
				7 => new WardSize
				{
					Width = Lv7Width.Value,
					Depth = Lv7Depth.Value
				}, 
				8 => new WardSize
				{
					Width = Lv8Width.Value,
					Depth = Lv8Depth.Value
				}, 
				_ => new WardSize
				{
					Width = Lv1Width.Value,
					Depth = Lv1Depth.Value
				}, 
			};
		}

		public static float GetShieldMaxHP(int level)
		{
			return level switch
			{
				2 => Lv2ShieldMaxHP.Value, 
				3 => Lv3ShieldMaxHP.Value, 
				4 => Lv4ShieldMaxHP.Value, 
				5 => Lv5ShieldMaxHP.Value, 
				6 => Lv6ShieldMaxHP.Value, 
				7 => Lv7ShieldMaxHP.Value, 
				8 => Lv8ShieldMaxHP.Value, 
				_ => Lv1ShieldMaxHP.Value, 
			};
		}

		private static FuelTier GetTier(int level)
		{
			return level switch
			{
				2 => new FuelTier
				{
					Level = 2,
					ItemA = Lv2FuelA.Value,
					AmountA = Lv2FuelAAmount.Value,
					ItemB = Lv2FuelB.Value,
					AmountB = Lv2FuelBAmount.Value,
					IntervalSeconds = Lv2IntervalMinutes.Value * 60f
				}, 
				3 => new FuelTier
				{
					Level = 3,
					ItemA = Lv3FuelA.Value,
					AmountA = Lv3FuelAAmount.Value,
					ItemB = Lv3FuelB.Value,
					AmountB = Lv3FuelBAmount.Value,
					IntervalSeconds = Lv3IntervalMinutes.Value * 60f
				}, 
				4 => new FuelTier
				{
					Level = 4,
					ItemA = Lv4FuelA.Value,
					AmountA = Lv4FuelAAmount.Value,
					ItemB = Lv4FuelB.Value,
					AmountB = Lv4FuelBAmount.Value,
					IntervalSeconds = Lv4IntervalMinutes.Value * 60f
				}, 
				5 => new FuelTier
				{
					Level = 5,
					ItemA = Lv5FuelA.Value,
					AmountA = Lv5FuelAAmount.Value,
					ItemB = Lv5FuelB.Value,
					AmountB = Lv5FuelBAmount.Value,
					IntervalSeconds = Lv5IntervalMinutes.Value * 60f
				}, 
				6 => new FuelTier
				{
					Level = 6,
					ItemA = Lv6FuelA.Value,
					AmountA = Lv6FuelAAmount.Value,
					ItemB = Lv6FuelB.Value,
					AmountB = Lv6FuelBAmount.Value,
					ItemC = Lv6FuelC.Value,
					AmountC = Lv6FuelCAmount.Value,
					IntervalSeconds = Lv6IntervalMinutes.Value * 60f
				}, 
				7 => new FuelTier
				{
					Level = 7,
					ItemA = Lv7FuelA.Value,
					AmountA = Lv7FuelAAmount.Value,
					ItemB = Lv7FuelB.Value,
					AmountB = Lv7FuelBAmount.Value,
					IntervalSeconds = Lv7IntervalMinutes.Value * 60f
				}, 
				8 => new FuelTier
				{
					Level = 8,
					ItemA = Lv8FuelA.Value,
					AmountA = Lv8FuelAAmount.Value,
					ItemB = Lv8FuelB.Value,
					AmountB = Lv8FuelBAmount.Value,
					ItemC = Lv8FuelC.Value,
					AmountC = Lv8FuelCAmount.Value,
					IntervalSeconds = Lv8IntervalMinutes.Value * 60f
				}, 
				_ => new FuelTier
				{
					Level = 1,
					ItemA = Lv1FuelA.Value,
					AmountA = Lv1FuelAAmount.Value,
					ItemB = Lv1FuelB.Value,
					AmountB = Lv1FuelBAmount.Value,
					IntervalSeconds = Lv1IntervalMinutes.Value * 60f
				}, 
			};
		}

		public static List<FuelTier> GetFuelTiers(int uptoLevel)
		{
			List<FuelTier> list = new List<FuelTier>(2) { GetTier(1) };
			if (uptoLevel > 1)
			{
				list.Add(GetTier(uptoLevel));
			}
			return list;
		}

		public static UpgradeCostInfo GetUpgradeCost(int targetLevel)
		{
			return targetLevel switch
			{
				2 => new UpgradeCostInfo
				{
					ItemA = Lv2UpgradeItemA.Value,
					ItemAAmount = Lv2UpgradeItemAAmount.Value,
					ItemB = Lv2UpgradeItemB.Value,
					ItemBAmount = Lv2UpgradeItemBAmount.Value,
					Coins = Lv2UpgradeCoins.Value
				}, 
				3 => new UpgradeCostInfo
				{
					ItemA = Lv3UpgradeItemA.Value,
					ItemAAmount = Lv3UpgradeItemAAmount.Value,
					ItemB = Lv3UpgradeItemB.Value,
					ItemBAmount = Lv3UpgradeItemBAmount.Value,
					Coins = Lv3UpgradeCoins.Value
				}, 
				4 => new UpgradeCostInfo
				{
					ItemA = Lv4UpgradeItemA.Value,
					ItemAAmount = Lv4UpgradeItemAAmount.Value,
					ItemB = Lv4UpgradeItemB.Value,
					ItemBAmount = Lv4UpgradeItemBAmount.Value,
					Coins = Lv4UpgradeCoins.Value
				}, 
				5 => new UpgradeCostInfo
				{
					ItemA = Lv5UpgradeItemA.Value,
					ItemAAmount = Lv5UpgradeItemAAmount.Value,
					ItemB = Lv5UpgradeItemB.Value,
					ItemBAmount = Lv5UpgradeItemBAmount.Value,
					Coins = Lv5UpgradeCoins.Value
				}, 
				6 => new UpgradeCostInfo
				{
					ItemA = Lv6UpgradeItemA.Value,
					ItemAAmount = Lv6UpgradeItemAAmount.Value,
					ItemB = Lv6UpgradeItemB.Value,
					ItemBAmount = Lv6UpgradeItemBAmount.Value,
					Coins = Lv6UpgradeCoins.Value
				}, 
				7 => new UpgradeCostInfo
				{
					ItemA = Lv7UpgradeItemA.Value,
					ItemAAmount = Lv7UpgradeItemAAmount.Value,
					ItemB = Lv7UpgradeItemB.Value,
					ItemBAmount = Lv7UpgradeItemBAmount.Value,
					Coins = Lv7UpgradeCoins.Value
				}, 
				8 => new UpgradeCostInfo
				{
					ItemA = Lv8UpgradeItemA.Value,
					ItemAAmount = Lv8UpgradeItemAAmount.Value,
					ItemB = Lv8UpgradeItemB.Value,
					ItemBAmount = Lv8UpgradeItemBAmount.Value,
					Coins = Lv8UpgradeCoins.Value
				}, 
				_ => default(UpgradeCostInfo), 
			};
		}

		public static bool IsAdminBypassActive()
		{
			if (!AdminBypass.Value)
			{
				return false;
			}
			return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.LocalPlayerIsAdminOrHost();
		}
	}
	[HarmonyPatch(typeof(DamageText), "AddInworldText")]
	public static class Patch_DamageText_RichText
	{
		internal static readonly HashSet<TMP_Text> SlowRiseFields = new HashSet<TMP_Text>();

		private static void Postfix(DamageText __instance, string text)
		{
			if (!string.IsNullOrEmpty(text) && text.Contains("<color=") && __instance.m_worldTexts.Count != 0)
			{
				WorldTextInstance val = __instance.m_worldTexts[__instance.m_worldTexts.Count - 1];
				val.m_textField.richText = true;
				SlowRiseFields.Add(val.m_textField);
			}
		}
	}
	[HarmonyPatch(typeof(DamageText), "UpdateWorldTexts")]
	public static class Patch_DamageText_SlowRise
	{
		private const float SpeedFactor = 1f / 3f;

		private static void Postfix(DamageText __instance, float dt)
		{
			if (Patch_DamageText_RichText.SlowRiseFields.Count == 0)
			{
				return;
			}
			foreach (WorldTextInstance worldText in __instance.m_worldTexts)
			{
				if (Patch_DamageText_RichText.SlowRiseFields.Contains(worldText.m_textField))
				{
					worldText.m_worldPos.y -= dt * 0.6666666f;
					if (worldText.m_timer > __instance.m_textDuration)
					{
						Patch_DamageText_RichText.SlowRiseFields.Remove(worldText.m_textField);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Door), "Interact")]
	public static class Patch_Door_AutoClose
	{
		private static void Postfix(Door __instance)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (TerritoryConfig.DoorAutoCloseEnabled.Value && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsOwner() && __instance.m_nview.GetZDO().GetInt("state", 0) != 0 && TerritoryWard.IsInsideActiveWard(((Component)__instance).transform.position))
			{
				((MonoBehaviour)__instance).StartCoroutine(AutoCloseRoutine(__instance));
			}
		}

		private static IEnumerator AutoCloseRoutine(Door door)
		{
			yield return (object)new WaitForSeconds(TerritoryConfig.DoorAutoCloseDelay.Value);
			if (!((Object)(object)door == (Object)null) && !((Object)(object)door.m_nview == (Object)null) && door.m_nview.IsValid() && door.m_nview.GetZDO().GetInt("state", 0) != 0 && TerritoryWard.IsInsideActiveWard(((Component)door).transform.position))
			{
				door.m_nview.InvokeRPC(ZNetView.Everybody, "UseDoor", new object[1] { false });
			}
		}
	}
	internal static class DoorGuardStoneBypass
	{
		internal static void Suppress(Door door, out bool state)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			state = door.m_checkGuardStone;
			if (TerritoryWard.IsInsideActiveWard(((Component)door).transform.position))
			{
				door.m_checkGuardStone = false;
			}
		}

		internal static void Restore(Door door, bool state)
		{
			door.m_checkGuardStone = state;
		}
	}
	[HarmonyPatch(typeof(Door), "Interact")]
	public static class Patch_Door_GuardStoneBypass
	{
		private static void Prefix(Door __instance, out bool __state)
		{
			DoorGuardStoneBypass.Suppress(__instance, out __state);
		}

		private static void Postfix(Door __instance, bool __state)
		{
			DoorGuardStoneBypass.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Door), "GetHoverText")]
	public static class Patch_Door_GuardStoneBypass_HoverText
	{
		private static void Prefix(Door __instance, out bool __state)
		{
			DoorGuardStoneBypass.Suppress(__instance, out __state);
		}

		private static void Postfix(Door __instance, bool __state)
		{
			DoorGuardStoneBypass.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Door), "UseItem")]
	public static class Patch_Door_GuardStoneBypass_UseItem
	{
		private static void Prefix(Door __instance, out bool __state)
		{
			DoorGuardStoneBypass.Suppress(__instance, out __state);
		}

		private static void Postfix(Door __instance, bool __state)
		{
			DoorGuardStoneBypass.Restore(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Player), "Interact")]
	public static class Patch_Player_Interact
	{
		private static bool Prefix(Player __instance, GameObject go)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null)
			{
				return true;
			}
			Container componentInParent = go.GetComponentInParent<Container>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.m_name == "$territoryward_storage")
			{
				PrivateArea component = ((Component)componentInParent).GetComponent<PrivateArea>();
				if ((Object)(object)component != (Object)null && !component.HaveLocalAccess())
				{
					IntrusionAlert.CheckAndAlert(((Component)componentInParent).transform.position, (Humanoid)(object)__instance);
					((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_not_permitted", 0, (Sprite)null);
					return false;
				}
				return true;
			}
			if (((Object)((Component)go.transform.root).gameObject).name.Contains("territoryward"))
			{
				return true;
			}
			if (TerritoryWard.IsInsideDungeon(go.transform.position))
			{
				return true;
			}
			bool flag = (Object)(object)go.GetComponentInParent<Door>() != (Object)null;
			bool flag2 = TerritoryWard.IsBasicCampfire(((Object)((Component)go.transform.root).gameObject).name);
			Vector3 position = go.transform.position;
			if (TerritoryWard.IsInsideDeactivatedWard(position))
			{
				if (flag || flag2)
				{
					return true;
				}
				((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_off_blocked", 0, (Sprite)null);
				return false;
			}
			if (TerritoryWard.IsInsideActiveWardWithoutAccess(position))
			{
				if (flag || flag2)
				{
					return true;
				}
				IntrusionAlert.CheckAndAlert(position, (Humanoid)(object)__instance);
				((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_not_permitted", 0, (Sprite)null);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(int),
		typeof(int)
	})]
	public static class Patch_Inventory_AddItem_MaxStack
	{
		private static void Prefix(Inventory __instance, ItemData item, out int __state)
		{
			__state = item.m_shared.m_maxStackSize;
			if (WardInventoryHelper.IsWardStorage(__instance) && WardInventoryHelper.IsWardFuel(item.m_shared.m_name))
			{
				item.m_shared.m_maxStackSize = 999;
			}
		}

		private static void Postfix(ItemData item, int __state)
		{
			item.m_shared.m_maxStackSize = __state;
		}
	}
	[HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[]
	{
		typeof(ItemData),
		typeof(int)
	})]
	public static class Patch_Inventory_CanAddItem_MaxStack
	{
		private static void Prefix(Inventory __instance, ItemData item, out int __state)
		{
			__state = item.m_shared.m_maxStackSize;
			if (WardInventoryHelper.IsWardStorage(__instance) && WardInventoryHelper.IsWardFuel(item.m_shared.m_name))
			{
				item.m_shared.m_maxStackSize = 999;
			}
		}

		private static void Postfix(ItemData item, int __state)
		{
			item.m_shared.m_maxStackSize = __state;
		}
	}
	[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[]
	{
		typeof(string),
		typeof(int),
		typeof(int),
		typeof(bool)
	})]
	public static class Patch_Inventory_RemoveItem_ProtectWardStorage
	{
		private static bool Prefix(Inventory __instance)
		{
			if (!WardInventoryHelper.IsWardStorage(__instance))
			{
				return true;
			}
			return WardInventoryHelper.IsWithdrawAllowed(__instance);
		}
	}
	[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
	public static class Patch_Inventory_RemoveItemData_ProtectWardStorage
	{
		private static bool Prefix(Inventory __instance)
		{
			if (!WardInventoryHelper.IsWardStorage(__instance))
			{
				return true;
			}
			return WardInventoryHelper.IsWithdrawAllowed(__instance);
		}
	}
	[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[]
	{
		typeof(ItemData),
		typeof(int)
	})]
	public static class Patch_Inventory_RemoveItemDataAmount_ProtectWardStorage
	{
		private static bool Prefix(Inventory __instance)
		{
			if (!WardInventoryHelper.IsWardStorage(__instance))
			{
				return true;
			}
			return WardInventoryHelper.IsWithdrawAllowed(__instance);
		}
	}
	[HarmonyPatch(typeof(Inventory), "RemoveOneItem", new Type[] { typeof(ItemData) })]
	public static class Patch_Inventory_RemoveOneItem_ProtectWardStorage
	{
		private static bool Prefix(Inventory __instance)
		{
			if (!WardInventoryHelper.IsWardStorage(__instance))
			{
				return true;
			}
			return WardInventoryHelper.IsWithdrawAllowed(__instance);
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "Interact")]
	public static class Patch_PrivateArea_PermittedToggle
	{
		private static bool Prefix(PrivateArea __instance, Humanoid human, bool hold, bool alt)
		{
			if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward"))
			{
				return true;
			}
			if (hold)
			{
				return true;
			}
			if (alt || Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303))
			{
				return false;
			}
			if (__instance.m_piece.IsCreator())
			{
				return true;
			}
			Player val = (Player)(object)((human is Player) ? human : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			bool flag = __instance.IsPermitted(val.GetPlayerID());
			bool flag2 = __instance.IsEnabled();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[Territory] PermittedToggle Interact: player={val.GetPlayerName()}({val.GetPlayerID()}) permitted={flag} wardEnabled={flag2}");
			}
			if (flag)
			{
				__instance.m_nview.InvokeRPC("ToggleEnabled", new object[1] { val.GetPlayerID() });
			}
			else if (!flag2)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[Territory] PermittedToggle Interact: sending join RPC for {val.GetPlayerName()}({val.GetPlayerID()})");
				}
				__instance.m_nview.InvokeRPC("TogglePermitted", new object[2]
				{
					val.GetPlayerID(),
					val.GetPlayerName()
				});
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_join_blocked_while_active", 0, (Sprite)null);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "RPC_ToggleEnabled")]
	public static class Patch_PrivateArea_RPC_ToggleEnabled
	{
		private static bool Prefix(PrivateArea __instance, long uid, long playerID)
		{
			if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward"))
			{
				return true;
			}
			if (!__instance.m_nview.IsOwner())
			{
				return true;
			}
			if (__instance.m_piece.GetCreator() == playerID)
			{
				return true;
			}
			if (!__instance.IsPermitted(playerID))
			{
				return true;
			}
			__instance.SetEnabled(!__instance.IsEnabled());
			return false;
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "GetHoverText")]
	public static class Patch_PrivateArea_HoverText
	{
		private const string Cyan = "#00FFFF";

		private const string Yellow = "yellow";

		private const string Gray = "grey";

		private static void Postfix(PrivateArea __instance, ref string __result)
		{
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward"))
			{
				return;
			}
			TerritoryWardController component = ((Component)__instance).GetComponent<TerritoryWardController>();
			ZNetView val = component?.m_nview ?? ((Component)__instance).GetComponent<ZNetView>();
			int num = 1;
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				num = val.GetZDO().GetInt("tw_level", 1);
			}
			bool flag = __instance.IsEnabled();
			string arg = (flag ? "<color=green>$territoryward_status_enabled</color>" : "<color=red>$territoryward_status_disabled</color>");
			Player localPlayer = Player.m_localPlayer;
			bool flag2 = (Object)(object)localPlayer != (Object)null && __instance.m_piece.IsCreator();
			bool flag3 = (Object)(object)localPlayer != (Object)null && (Object)(object)val != (Object)null && val.IsValid() && __instance.IsPermitted(localPlayer.GetPlayerID());
			string text = Localization.instance.Localize("$KEY_Use");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(string.Format("<size=22><b>[ $territoryward_name <color={0}>Lv{1}</color>({2}) ]</b></size>", "#00FFFF", num, arg));
			if ((Object)(object)component != (Object)null)
			{
				stringBuilder.Append("\n<color=yellow>$territoryward_fuel_label</color> : " + component.GetFuelInfoText());
			}
			string text2 = (((Object)(object)component != (Object)null) ? $"{component.m_width:0.#}x{component.m_depth:0.#}m" : $"{__instance.m_radius:0}m");
			stringBuilder.Append("\n<color=yellow>$territoryward_range_label</color> : " + text2);
			if ((Object)(object)component != (Object)null && !component.IsShielded() && TerritoryConfig.PassiveShieldEnabled.Value)
			{
				float passiveShieldHP = component.GetPassiveShieldHP();
				float passiveShieldMaxHP = component.GetPassiveShieldMaxHP();
				stringBuilder.Append(string.Format("\n<color={0}>$territoryward_passive_shield_label</color> : {1:0} / {2:0}", "yellow", passiveShieldHP, passiveShieldMaxHP));
			}
			stringBuilder.Append("\n");
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				ZDO zDO = val.GetZDO();
				obj = ((zDO != null) ? zDO.GetString("creatorName", "???") : null);
			}
			if (obj == null)
			{
				obj = "???";
			}
			string text3 = (string)obj;
			string permittedNamesString = GetPermittedNamesString(__instance, val);
			stringBuilder.Append("\n<color=yellow>$territoryward_owner_label</color> : <color=green>" + text3 + "</color>");
			stringBuilder.Append("\n<color=yellow>$territoryward_permitted_label</color> : <color=#4FC3F7>" + permittedNamesString + "</color>");
			stringBuilder.Append("\n");
			if (flag2 || flag3)
			{
				if (flag2)
				{
					stringBuilder.Append("\n[<color=yellow><b>Shift+" + text + "</b></color>] $territoryward_member_manage_hint_key");
				}
				stringBuilder.Append("\n[<color=yellow><b>" + text + "</b></color>] $territoryward_toggle_hint_key");
				if (flag3 && !flag2)
				{
					stringBuilder.Append(string.Format("\n[<color={0}><b>Shift+{1}</b></color>] $territoryward_member_leave_hint_key", "yellow", TerritoryConfig.RangeRingKey.Value));
				}
			}
			else if (!flag)
			{
				stringBuilder.Append("\n[<color=yellow><b>" + text + "</b></color>] $territoryward_member_join_hint_key");
				stringBuilder.Append(string.Format("\n[<color={0}><b>Shift+{1}</b></color>] $territoryward_member_leave_hint_key", "yellow", TerritoryConfig.RangeRingKey.Value));
			}
			else
			{
				stringBuilder.Append("\n<color=grey>$territoryward_join_blocked_while_active_hint</color>");
			}
			stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_fuel_hint", "yellow", TerritoryConfig.FuelStorageKey.Value));
			stringBuilder.Append("\n");
			stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_upgrade_hint_key", "yellow", TerritoryConfig.UpgradeKey.Value));
			if ((Object)(object)component != (Object)null)
			{
				if (num < 8)
				{
					TerritoryConfig.WardSize? nextLevelSize = component.GetNextLevelSize();
					stringBuilder.Append(string.Format(" <color={0}>Lv{1}</color>→<color={2}><b>Lv{3}</b></color>", "#00FFFF", num, "#00FFFF", num + 1));
					stringBuilder.Append("\n<color=yellow>$territoryward_material_label</color> : " + component.GetUpgradeRequirementText());
					if (nextLevelSize.HasValue)
					{
						stringBuilder.Append(string.Format("\n<color={0}>$territoryward_range_label</color> : {1:0.#}x{2:0.#}m", "yellow", nextLevelSize.Value.Width, nextLevelSize.Value.Depth));
					}
					stringBuilder.Append("\n<color=yellow>$territoryward_fuel_label</color> : " + component.GetNextLevelFuelInfoText());
					string nextLevelFullFuelText = component.GetNextLevelFullFuelText();
					if (!string.IsNullOrEmpty(nextLevelFullFuelText))
					{
						stringBuilder.Append(string.Format("\n<color={0}>Lv1/Lv{1} $territoryward_fuel_label</color> :", "yellow", num + 1));
						stringBuilder.Append("\n" + nextLevelFullFuelText);
					}
				}
				else
				{
					stringBuilder.Append(" $territoryward_max_level");
				}
			}
			if (num >= 5 && (Object)(object)component != (Object)null)
			{
				if (component.IsShielded())
				{
					int num2 = Mathf.CeilToInt(component.GetShieldRemainingMinutes());
					string text4 = Localization.instance.Localize("$territoryward_shield_active", new string[1] { num2.ToString() });
					stringBuilder.Append("\n<color=#00FFFF>[" + text4 + "]</color>");
					if (flag2 || flag3)
					{
						stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_shield_deactivate_hint_key", "yellow", TerritoryConfig.ShieldKey.Value));
					}
				}
				else if (flag2 || flag3)
				{
					if (!flag)
					{
						stringBuilder.Append("\n<color=grey>$territoryward_shield_ward_off_hint</color>");
					}
					else
					{
						float shieldBankedRemainingMinutes = component.GetShieldBankedRemainingMinutes();
						if (shieldBankedRemainingMinutes > 0f)
						{
							int num3 = Mathf.CeilToInt(shieldBankedRemainingMinutes);
							string arg2 = Localization.instance.Localize("$territoryward_shield_resume_hint", new string[1] { num3.ToString() });
							stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] {2}", "yellow", TerritoryConfig.ShieldKey.Value, arg2));
						}
						else
						{
							string arg3 = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.ShieldItemName.Value) ?? TerritoryConfig.ShieldItemName.Value);
							stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_shield_hint_key ({2} x1)", "yellow", TerritoryConfig.ShieldKey.Value, arg3));
						}
					}
				}
			}
			__result = Localization.instance.Localize(stringBuilder.ToString());
		}

		private static string GetPermittedNamesString(PrivateArea instance, ZNetView nview)
		{
			try
			{
				if ((Object)(object)nview != (Object)null && nview.IsValid())
				{
					ZDO zDO = nview.GetZDO();
					int num = zDO.GetInt("permitted", 0);
					if (num > 0)
					{
						List<string> list = new List<string>(num);
						for (int i = 0; i < num; i++)
						{
							string text = zDO.GetString("pu_name" + i, "");
							if (!string.IsNullOrEmpty(text))
							{
								list.Add(text);
							}
						}
						if (list.Count > 0)
						{
							return string.Join(", ", list);
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				FieldInfo[] fields = typeof(PrivateArea).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (!fieldInfo.Name.ToLower().Contains("permitted") || !(fieldInfo.GetValue(instance) is IEnumerable enumerable))
					{
						continue;
					}
					List<string> list2 = new List<string>();
					foreach (object item in enumerable)
					{
						if (item != null)
						{
							string text2 = item.GetType().GetProperty("Value")?.GetValue(item) as string;
							if (!string.IsNullOrEmpty(text2))
							{
								list2.Add(text2);
							}
						}
					}
					if (list2.Count > 0)
					{
						return string.Join(", ", list2);
					}
				}
			}
			catch
			{
			}
			return "$territoryward_none";
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	public static class Patch_Hud_WardHoverTextPosition
	{
		private static Vector2? s_basePos;

		private static Vector2? s_baseSizeDelta;

		private static TextMeshProUGUI s_rightColumn;

		private static RectTransform s_dividerRect;

		private const float OffsetY = 340f;

		private const float WidthMultiplier = 1.3225f;

		private const float DividerWidth = 4f;

		private const float ColumnGap = 12f;

		private const float MinDividerHeight = 200f;

		private const float DividerHeightPad = 20f;

		private static void Postfix(Hud __instance)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? obj = typeof(Hud).GetField("m_hoverName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(__instance);
				Component val = (Component)((obj is Component) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				RectTransform component = val.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				if (property == null)
				{
					return;
				}
				string text = (property.GetValue(val) as string) ?? "";
				bool flag = text.Contains("영토 와드") || text.Contains("Territory Ward");
				if (!s_basePos.HasValue)
				{
					s_basePos = component.anchoredPosition;
				}
				if (!s_baseSizeDelta.HasValue)
				{
					s_baseSizeDelta = component.sizeDelta;
				}
				component.anchoredPosition = s_basePos.Value + (Vector2)(flag ? new Vector2(0f, 340f) : Vector2.zero);
				if (!flag)
				{
					component.sizeDelta = s_baseSizeDelta.Value;
					if ((Object)(object)s_rightColumn != (Object)null)
					{
						((Component)s_rightColumn).gameObject.SetActive(false);
					}
					if ((Object)(object)s_dividerRect != (Object)null)
					{
						((Component)s_dividerRect).gameObject.SetActive(false);
					}
					return;
				}
				EnsureColumnObjects(val, component);
				float num = s_baseSizeDelta.Value.x * 1.3225f;
				component.sizeDelta = new Vector2(num, s_baseSizeDelta.Value.y);
				string[] array = text.Split(new char[1] { '\n' });
				int num2 = Mathf.CeilToInt((float)array.Length / 2f);
				string value = string.Join("\n", array, 0, num2);
				string text2 = string.Join("\n", array, num2, array.Length - num2);
				property.SetValue(val, value);
				((TMP_Text)s_rightColumn).text = text2;
				Vector2 anchoredPosition = component.anchoredPosition;
				float num3 = num + 12f;
				float num4 = num + 24f + 4f;
				RectTransform component2 = ((Component)s_rightColumn).GetComponent<RectTransform>();
				component2.sizeDelta = new Vector2(num, s_baseSizeDelta.Value.y);
				component2.anchoredPosition = anchoredPosition + new Vector2(num4, 0f);
				((Component)s_rightColumn).gameObject.SetActive(true);
				TextMeshProUGUI val2 = (TextMeshProUGUI)(object)((val is TextMeshProUGUI) ? val : null);
				float num5 = (((Object)(object)val2 != (Object)null) ? ((TMP_Text)val2).preferredHeight : 200f);
				float preferredHeight = ((TMP_Text)s_rightColumn).preferredHeight;
				float num6 = Mathf.Max(Mathf.Max(num5, preferredHeight), 200f) + 20f;
				s_dividerRect.sizeDelta = new Vector2(4f, num6);
				s_dividerRect.anchoredPosition = anchoredPosition + new Vector2(num3, 0f);
				((Component)s_dividerRect).gameObject.SetActive(true);
			}
			catch
			{
			}
		}

		private static void EnsureColumnObjects(Component originalComp, RectTransform originalRt)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_rightColumn == (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(originalComp.gameObject, ((Transform)originalRt).parent);
				((Object)val).name = "TerritoryWard_HoverTextRightColumn";
				s_rightColumn = val.GetComponent<TextMeshProUGUI>();
			}
			if ((Object)(object)s_dividerRect == (Object)null)
			{
				GameObject val2 = new GameObject("TerritoryWard_HoverTextDivider", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val2.transform.SetParent(((Transform)originalRt).parent, false);
				((Graphic)val2.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.4f);
				s_dividerRect = val2.GetComponent<RectTransform>();
				s_dividerRect.pivot = new Vector2(0.5f, 1f);
			}
		}
	}
	internal static class WardInventoryHelper
	{
		internal static bool IsWardStorage(Inventory inv)
		{
			return inv.m_name == "$territoryward_storage";
		}

		internal static bool IsWardFuel(string name)
		{
			return name == "$item_wood" || name == "$item_resin";
		}

		internal static bool IsWithdrawAllowed(Inventory inv)
		{
			if (TerritoryWardController.IsInternalWithdrawInProgress)
			{
				return true;
			}
			InventoryGui instance = InventoryGui.instance;
			return (Object)(object)instance != (Object)null && instance.IsContainerOpen() && instance.m_currentContainer.GetInventory() == inv;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
	public static class Patch_InventoryGrid_UpdateInventory_ForceRebuild
	{
		private static void Prefix(InventoryGrid __instance, Inventory inventory)
		{
			if (inventory != null)
			{
				int num = inventory.GetWidth() * inventory.GetHeight();
				if (__instance.m_elements.Count != num)
				{
					__instance.m_width = -1;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "GetElement")]
	public static class Patch_InventoryGrid_GetElement_Safety
	{
		private static bool Prefix(InventoryGrid __instance, int x, int y, int width, ref Element __result)
		{
			int num = y * width + x;
			if (num >= 0 && num < __instance.m_elements.Count)
			{
				return true;
			}
			if (__instance.m_elements.Count == 0)
			{
				return true;
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"[Territory] InventoryGrid.GetElement 범위 밖 접근 방어: x={x}, y={y}, width={width}, elements={__instance.m_elements.Count}");
			}
			__result = __instance.m_elements[Mathf.Clamp(num, 0, __instance.m_elements.Count - 1)];
			return false;
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	public static class Patch_Container_Interact_IntrusionAlert
	{
		private static void Prefix(Container __instance, Humanoid character)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			IntrusionAlert.CheckAndAlert(((Component)__instance).transform.position, character);
		}
	}
	[HarmonyPatch(typeof(CraftingStation), "Interact")]
	public static class Patch_CraftingStation_Interact_IntrusionAlert
	{
		private static void Prefix(CraftingStation __instance, Humanoid user)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			IntrusionAlert.CheckAndAlert(((Component)__instance).transform.position, user);
		}
	}
	internal static class IntrusionAlert
	{
		public static void CheckAndAlert(Vector3 position, Humanoid character)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			List<PrivateArea> list = new List<PrivateArea>();
			foreach (PrivateArea s_ward in TerritoryWard.s_wards)
			{
				if (!((Object)(object)s_ward == (Object)null) && s_ward.IsEnabled() && s_ward.IsInside(position, 0f))
				{
					if (s_ward.HaveLocalAccess())
					{
						return;
					}
					list.Add(s_ward);
				}
			}
			foreach (PrivateArea item in list)
			{
				((Component)item).GetComponent<TerritoryWardController>()?.ReportIntrusion(Player.m_localPlayer.GetPlayerName());
			}
		}
	}
	internal static class KnownPlayersRegistry
	{
		private static readonly Dictionary<long, Dictionary<long, string>> s_byWorld = new Dictionary<long, Dictionary<long, string>>();

		private static string s_filePath;

		private static string FilePath
		{
			get
			{
				if (s_filePath == null)
				{
					s_filePath = Path.Combine(Paths.ConfigPath, "Captain_territorial_known_players.json");
				}
				return s_filePath;
			}
		}

		private static long CurrentWorldUid()
		{
			return ZNet.m_world?.m_uid ?? 0;
		}

		internal static void Load()
		{
			s_byWorld.Clear();
			if (!File.Exists(FilePath))
			{
				return;
			}
			string text = File.ReadAllText(FilePath, Encoding.UTF8);
			int num = text.IndexOf('{');
			int num2 = text.LastIndexOf('}');
			if (num < 0 || num2 < 0 || num2 <= num)
			{
				return;
			}
			string s = text.Substring(num + 1, num2 - num - 1);
			foreach (string item in SplitTopLevel(s))
			{
				int num3 = item.IndexOf(':');
				if (num3 < 0 || !TryUnquote(item.Substring(0, num3), out var value) || !long.TryParse(value, out var result))
				{
					continue;
				}
				string text2 = item.Substring(num3 + 1).Trim();
				int num4 = text2.IndexOf('{');
				int num5 = text2.LastIndexOf('}');
				if (num4 < 0 || num5 < 0 || num5 <= num4)
				{
					continue;
				}
				Dictionary<long, string> dictionary = new Dictionary<long, string>();
				foreach (string item2 in SplitTopLevel(text2.Substring(num4 + 1, num5 - num4 - 1)))
				{
					int num6 = item2.IndexOf(':');
					if (num6 >= 0 && TryUnquote(item2.Substring(0, num6), out var value2) && TryUnquote(item2.Substring(num6 + 1), out var value3) && long.TryParse(value2, out var result2))
					{
						dictionary[result2] = Unescape(value3);
					}
				}
				if (dictionary.Count > 0)
				{
					s_byWorld[result] = dictionary;
				}
			}
		}

		internal static bool RecordPlayer(long playerID, string name)
		{
			long num = CurrentWorldUid();
			if (num == 0L || playerID == 0L || string.IsNullOrEmpty(name))
			{
				return false;
			}
			if (!s_byWorld.TryGetValue(num, out var value))
			{
				value = new Dictionary<long, string>();
				s_byWorld[num] = value;
			}
			if (value.TryGetValue(playerID, out var value2) && value2 == name)
			{
				return false;
			}
			value[playerID] = name;
			Save();
			return true;
		}

		internal static void ReplaceAll(Dictionary<long, string> data)
		{
			long num = CurrentWorldUid();
			if (num != 0)
			{
				s_byWorld[num] = new Dictionary<long, string>(data);
				Save();
			}
		}

		internal static Dictionary<long, string> GetAll()
		{
			long num = CurrentWorldUid();
			if (num != 0L && s_byWorld.TryGetValue(num, out var value))
			{
				return new Dictionary<long, string>(value);
			}
			return new Dictionary<long, string>();
		}

		private static void Save()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{\n");
			bool flag = true;
			foreach (KeyValuePair<long, Dictionary<long, string>> item in s_byWorld)
			{
				if (item.Value.Count == 0)
				{
					continue;
				}
				if (!flag)
				{
					stringBuilder.Append(",\n");
				}
				flag = false;
				stringBuilder.Append("  \"").Append(item.Key).Append("\": {\n");
				bool flag2 = true;
				foreach (KeyValuePair<long, string> item2 in item.Value)
				{
					if (!flag2)
					{
						stringBuilder.Append(",\n");
					}
					flag2 = false;
					stringBuilder.Append("    \"").Append(item2.Key).Append("\": \"")
						.Append(Escape(item2.Value))
						.Append('"');
				}
				stringBuilder.Append("\n  }");
			}
			stringBuilder.Append("\n}\n");
			string directoryName = Path.GetDirectoryName(FilePath);
			if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllText(FilePath, stringBuilder.ToString(), Encoding.UTF8);
		}

		private static List<string> SplitTopLevel(string s)
		{
			List<string> list = new List<string>();
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < s.Length; i++)
			{
				switch (s[i])
				{
				case '{':
					num++;
					break;
				case '}':
					num--;
					break;
				case ',':
					if (num == 0)
					{
						list.Add(s.Substring(num2, i - num2));
						num2 = i + 1;
					}
					break;
				}
			}
			string text = s.Substring(num2);
			if (text.Trim().Length > 0)
			{
				list.Add(text);
			}
			return list;
		}

		private static bool TryUnquote(string raw, out string value)
		{
			raw = raw.Trim();
			int num = raw.IndexOf('"');
			int num2 = raw.LastIndexOf('"');
			if (num < 0 || num2 <= num)
			{
				value = null;
				return false;
			}
			value = raw.Substring(num + 1, num2 - num - 1);
			return true;
		}

		private static string Escape(string s)
		{
			return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
		}

		private static string Unescape(string s)
		{
			return s.Replace("\\\"", "\"").Replace("\\\\", "\\");
		}
	}
	[HarmonyPatch(typeof(ZNet), "Awake")]
	internal static class Patch_ZNet_Awake_RegisterKnownPlayersRpc
	{
		private static void Postfix()
		{
			KnownPlayersSync.RegisterRpcs();
		}
	}
	internal static class KnownPlayersSync
	{
		private const string SyncRpcName = "CaptTerritory_KnownPlayersSync";

		private const string RequestRpcName = "CaptTerritory_RequestKnownPlayers";

		private static ZRoutedRpc s_registeredOn;

		internal static void RegisterRpcs()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && instance != s_registeredOn)
			{
				instance.Register<ZPackage>("CaptTerritory_KnownPlayersSync", (Action<long, ZPackage>)RPC_ReceiveSync);
				instance.Register("CaptTerritory_RequestKnownPlayers", (Action<long>)RPC_HandleRequest);
				s_registeredOn = instance;
				KnownPlayersRegistry.Load();
				if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
				{
					RequestFromServer();
				}
			}
		}

		internal static void RequestFromServer()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer())
			{
				instance.InvokeRoutedRPC(instance.GetServerPeerID(), "CaptTerritory_RequestKnownPlayers", Array.Empty<object>());
			}
		}

		internal static void BroadcastToAll()
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				SendSyncTo(ZRoutedRpc.Everybody);
			}
		}

		private static void RPC_HandleRequest(long sender)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				SendSyncTo(sender);
			}
		}

		private static void SendSyncTo(long target)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance == null)
			{
				return;
			}
			Dictionary<long, string> all = KnownPlayersRegistry.GetAll();
			ZPackage val = new ZPackage();
			val.Write(all.Count);
			foreach (KeyValuePair<long, string> item in all)
			{
				val.Write(item.Key);
				val.Write(item.Value);
			}
			instance.InvokeRoutedRPC(target, "CaptTerritory_KnownPlayersSync", new object[1] { val });
		}

		private static void RPC_ReceiveSync(long sender, ZPackage pkg)
		{
			if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer())
			{
				int num = pkg.ReadInt();
				Dictionary<long, string> dictionary = new Dictionary<long, string>(num);
				for (int i = 0; i < num; i++)
				{
					long key = pkg.ReadLong();
					string value = pkg.ReadString();
					dictionary[key] = value;
				}
				KnownPlayersRegistry.ReplaceAll(dictionary);
			}
		}
	}
	public static class TerritoryLocalization
	{
		public static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "Korean";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				["territoryward_name"] = "영토 와드",
				["territoryward_storage"] = "영토 와드 창고",
				["territoryward_no_fuel"] = "연료 부족으로 영토 와드가 비활성화되었습니다!",
				["territoryward_off_blocked"] = "비활성화된 영토 와드 구역에서는 사용할 수 없습니다!",
				["territoryward_not_permitted"] = "영토 와드의 소유자나 허용된 사람만 사용할 수 있습니다!",
				["territoryward_remove_creator_only"] = "영토 와드는 설치자 또는 관리자만 제거할 수 있습니다!",
				["territoryward_join_blocked_while_active"] = "활성화된 영토 와드에는 가입할 수 없습니다! 비활성화 상태에서만 가입할 수 있습니다.",
				["territoryward_join_blocked_while_active_hint"] = "활성화 중에는 가입할 수 없음 (비활성화 시 가입 가능)",
				["territoryward_no_build"] = "영토 와드 구역 안에서만 건설할 수 있습니다!",
				["territoryward_must_activate"] = "영토와드를 활성화 해야합니다!",
				["territoryward_no_overlap"] = "다른 영토 와드 구역 안에서는 설치할 수 없습니다!",
				["territoryward_fuel_hint"] = "연료 창고 열기",
				["territoryward_disabled"] = "영토 와드 시스템이 비활성화되어 있습니다!",
				["territoryward_limit_reached"] = "영토 와드 설치 한도를 초과했습니다!",
				["territoryward_upgrade_hint_key"] = "영토 와드 업그레이드",
				["territoryward_range_label"] = "범위",
				["territoryward_fuel_label"] = "연료",
				["territoryward_fuel_per_minutes"] = "$1분마다",
				["territoryward_fuel_or"] = "또는",
				["territoryward_upgrade_too_far"] = "영토 와드와 너무 멀리 떨어져 있습니다!",
				["territoryward_upgrade_not_creator"] = "영토 와드를 설치한 사람만 업그레이드할 수 있습니다!",
				["territoryward_intrusion_alert"] = "$1가 승인없이 영토에 침입했습니다.",
				["territoryward_upgrade_success"] = "영토 와드가 업그레이드되었습니다!",
				["territoryward_max_level"] = "이미 최대 레벨입니다!",
				["territoryward_missing_fuel_suffix"] = " 부족!",
				["territoryward_shield_hint_key"] = "영토 보호 활성화",
				["territoryward_shield_deactivate_hint_key"] = "영토 보호 비활성화",
				["territoryward_shield_active"] = "보호 중 — 남은 $1분",
				["territoryward_shield_started"] = "영토 보호가 활성화되었습니다! (1시간)",
				["territoryward_shield_stopped"] = "영토 보호가 비활성화되었습니다.",
				["territoryward_shield_resumed"] = "남은 시간으로 영토 보호가 재개되었습니다! (아이템 소모 없음)",
				["territoryward_shield_resume_hint"] = "재개 (아이템 소모 없음, 남은 $1분)",
				["territoryward_shield_no_item"] = "슈트링 코어가 부족합니다!",
				["territoryward_shield_ended_no_fuel"] = "슈르트링 코어가 부족하여 영토 보호가 종료되었습니다!",
				["territoryward_shield_low_level"] = "Lv5 이상에서만 사용 가능합니다!",
				["territoryward_rangering_hint_key"] = "범위 링 토글",
				["territoryward_shield_hud"] = "[ 영토 보호 중 — $1분 남음 ]",
				["territoryward_shield_hud_paused"] = "[ 영토 보호 일시정지 — 와드 비활성 (보관 $1분) ]",
				["territoryward_shield_ward_off_hint"] = "와드가 비활성 상태입니다 (영토 보호 사용 불가)",
				["territoryward_passive_shield_label"] = "보호막",
				["territoryward_passive_shield_hud"] = "[ 보호막 $1 / $2 ]",
				["territoryward_passive_shield_broken"] = "영토 보호막이 파괴되었습니다! 회복까지 기다리세요.",
				["territoryward_intrusion_chat"] = "[영토 침입 경고] $1가 승인 없이 영토에 진입했습니다!",
				["territoryward_status_enabled"] = "활성화",
				["territoryward_status_disabled"] = "비활성화",
				["territoryward_owner_label"] = "소유자",
				["territoryward_permitted_label"] = "허용됨",
				["territoryward_toggle_hint_key"] = "와드 활성화 / 비활성화",
				["territoryward_member_leave_hint_key"] = "멤버 탈퇴",
				["territoryward_member_join_hint_key"] = "멤버 가입",
				["territoryward_material_label"] = "재료",
				["territoryward_none"] = "없음",
				["territoryward_intruder_label"] = "침입자",
				["territoryward_whitelist_title"] = "[ 영토 와드 멤버 관리 ]",
				["territoryward_known_members_label"] = "알려진 캐릭터 (클릭해서 추가/추방)",
				["territoryward_online_tag"] = " (온라인)",
				["territoryward_close_button"] = "닫기",
				["territoryward_member_manage_hint_key"] = "온라인 멤버관리"
			});
			text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				["territoryward_name"] = "Territory Ward",
				["territoryward_storage"] = "Territory Ward Storage",
				["territoryward_no_fuel"] = "Territory Ward deactivated: out of fuel!",
				["territoryward_off_blocked"] = "Cannot use items inside a deactivated Territory Ward!",
				["territoryward_not_permitted"] = "Only the owner or permitted members can use this Territory Ward!",
				["territoryward_remove_creator_only"] = "Only the creator or an admin can remove this Territory Ward!",
				["territoryward_join_blocked_while_active"] = "Cannot join an active Territory Ward! You can only join while it is deactivated.",
				["territoryward_join_blocked_while_active_hint"] = "Cannot join while active (join allowed when deactivated)",
				["territoryward_no_build"] = "You can only build inside a Territory Ward!",
				["territoryward_must_activate"] = "You must activate the Territory Ward!",
				["territoryward_no_overlap"] = "Cannot place a Territory Ward inside another Territory Ward!",
				["territoryward_fuel_hint"] = "Open Fuel Storage",
				["territoryward_disabled"] = "Territory Ward system is disabled!",
				["territoryward_limit_reached"] = "Territory Ward placement limit reached!",
				["territoryward_upgrade_hint_key"] = "Upgrade Territory Ward",
				["territoryward_range_label"] = "Range",
				["territoryward_fuel_label"] = "Fuel",
				["territoryward_fuel_per_minutes"] = "every $1 min",
				["territoryward_fuel_or"] = "or",
				["territoryward_upgrade_too_far"] = "You are too far from the Territory Ward!",
				["territoryward_upgrade_not_creator"] = "Only the creator of this Territory Ward can upgrade it!",
				["territoryward_intrusion_alert"] = "$1 has invaded the territory without permission!",
				["territoryward_upgrade_success"] = "Territory Ward upgraded!",
				["territoryward_max_level"] = "Already at max level!",
				["territoryward_missing_fuel_suffix"] = " is missing!",
				["territoryward_shield_hint_key"] = "Activate Territory Shield",
				["territoryward_shield_deactivate_hint_key"] = "Deactivate Territory Shield",
				["territoryward_shield_active"] = "Shield Active — $1 min remaining",
				["territoryward_shield_started"] = "Territory Shield activated! (1 hour)",
				["territoryward_shield_stopped"] = "Territory Shield deactivated.",
				["territoryward_shield_resumed"] = "Territory Shield resumed with remaining time! (no item consumed)",
				["territoryward_shield_resume_hint"] = "Resume (no item needed, $1 min left)",
				["territoryward_shield_no_item"] = "Not enough Surtling Core!",
				["territoryward_shield_ended_no_fuel"] = "Territory Shield ended: out of Surtling Core!",
				["territoryward_shield_low_level"] = "Requires Lv5 or higher!",
				["territoryward_rangering_hint_key"] = "Toggle Range Ring",
				["territoryward_shield_hud"] = "[ Shield Active — $1 min remaining ]",
				["territoryward_shield_hud_paused"] = "[ Shield Paused — Ward Disabled ($1 min banked) ]",
				["territoryward_shield_ward_off_hint"] = "Ward is disabled (shield unavailable)",
				["territoryward_passive_shield_label"] = "Shield",
				["territoryward_passive_shield_hud"] = "[ Shield $1 / $2 ]",
				["territoryward_passive_shield_broken"] = "The territory shield has been destroyed! Wait for it to regenerate.",
				["territoryward_intrusion_chat"] = "[Intrusion Alert] $1 has entered the territory without permission!",
				["territoryward_status_enabled"] = "Enabled",
				["territoryward_status_disabled"] = "Disabled",
				["territoryward_owner_label"] = "Owner",
				["territoryward_permitted_label"] = "Permitted",
				["territoryward_toggle_hint_key"] = "Toggle Ward On/Off",
				["territoryward_member_leave_hint_key"] = "Leave Membership",
				["territoryward_member_join_hint_key"] = "Join Membership",
				["territoryward_material_label"] = "Materials",
				["territoryward_none"] = "None",
				["territoryward_intruder_label"] = "Intruder",
				["territoryward_whitelist_title"] = "[ Territory Ward Member Management ]",
				["territoryward_known_members_label"] = "Known Characters (click to add/kick)",
				["territoryward_online_tag"] = " (Online)",
				["territoryward_close_button"] = "Close",
				["territoryward_member_manage_hint_key"] = "Manage Online Members"
			});
		}

		public static void RefreshWardDescription()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.Lv1FuelA.Value, warnIfMissing: false) ?? "$item_wood");
			string text2 = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.Lv1FuelB.Value, warnIfMissing: false) ?? "$item_resin");
			float value = TerritoryConfig.Lv1Width.Value;
			float value2 = TerritoryConfig.Lv1Depth.Value;
			int value3 = TerritoryConfig.Lv1FuelAAmount.Value;
			int value4 = TerritoryConfig.Lv1FuelBAmount.Value;
			float value5 = TerritoryConfig.Lv1IntervalMinutes.Value;
			string text3 = "Korean";
			localization.AddTranslation(ref text3, new Dictionary<string, string> { ["territoryward_desc"] = $"{value:0.#}x{value2:0.#}미터의 영토를 설정합니다.\n" + "ON 상태에서만 구역 안에서 건설하고 상호작용할 수 있습니다.\n" + $"연료: {text} {value3}개 + {text2} {value4}개 / {value5:0}분마다" });
			text3 = "English";
			localization.AddTranslation(ref text3, new Dictionary<string, string> { ["territoryward_desc"] = $"Sets a {value:0.#}x{value2:0.#}m territory.\n" + "Building and interaction only allowed when ON.\n" + $"Fuel: {text} x{value3} + {text2} x{value4} every {value5:0} min" });
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "IsSpawnPointGood")]
	public static class Patch_SpawnSystem_IsSpawnPointGood_NoSpawnInWard
	{
		private static void Postfix(ref bool __result, ref Vector3 spawnPoint)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (__result && TerritoryWard.IsInsideActiveWard(spawnPoint))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "ApplyDamage")]
	public static class Patch_WearNTear_ApplyDamage_PassiveShield
	{
		private static void Prefix(WearNTear __instance, ref float damage, HitData hitData)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (damage <= 0f)
			{
				return;
			}
			Character val = ((hitData != null) ? hitData.GetAttacker() : null);
			if (!((Object)(object)val == (Object)null) && val.IsMonsterFaction(Time.time))
			{
				TerritoryWardController territoryWardController = TerritoryWardController.FindPassiveShieldZoneAt(((Component)__instance).transform.position);
				if (!((Object)(object)territoryWardController == (Object)null))
				{
					territoryWardController.DrainPassiveShield(damage);
					damage = 0f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	public static class Patch_Character_ApplyDamage_PassiveShield
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!(__instance is Player))
			{
				return;
			}
			float totalDamage = hit.GetTotalDamage();
			if (totalDamage <= 0f)
			{
				return;
			}
			Character attacker = hit.GetAttacker();
			if (!((Object)(object)attacker == (Object)null) && attacker.IsMonsterFaction(Time.time))
			{
				TerritoryWardController territoryWardController = TerritoryWardController.FindPassiveShieldZoneAt(((Component)__instance).transform.position);
				if (!((Object)(object)territoryWardController == (Object)null))
				{
					territoryWardController.DrainPassiveShield(totalDamage);
					((DamageTypes)(ref hit.m_damage)).Modify(0f);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "FixedUpdate")]
	public static class Patch_Projectile_FixedUpdate_PassiveShieldBlock
	{
		private static void Postfix(Projectile __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || ((Object)(object)__instance.m_owner != (Object)null && __instance.m_owner.IsPlayer()))
			{
				return;
			}
			Vector3 position = ((Component)__instance).transform.position;
			foreach (PrivateArea s_ward in TerritoryWard.s_wards)
			{
				if (!s_ward.IsEnabled())
				{
					continue;
				}
				TerritoryWardController component = ((Component)s_ward).GetComponent<TerritoryWardController>();
				if ((Object)(object)component == (Object)null || (!component.IsShielded() && !component.HasPassiveShield()) || !component.IsPointInside(position) || component.IsPointInside(__instance.m_startPoint))
				{
					continue;
				}
				if (!component.IsShielded() && (Object)(object)__instance.m_owner != (Object)null && __instance.m_owner.IsMonsterFaction(Time.time))
				{
					component.DrainPassiveShield(((DamageTypes)(ref __instance.m_damage)).GetTotalDamage());
				}
				__instance.OnHit((Collider)null, position, false, -((Component)__instance).transform.forward);
				ZNetScene.instance.Destroy(((Component)__instance).gameObject);
				break;
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	public static class Patch_Humanoid_StartAttack_ShieldSiege
	{
		private const float AttackReachMargin = 4f;

		private static void Postfix(Humanoid __instance, bool __result)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || !((Character)__instance).IsMonsterFaction(Time.time) || TerritoryWard.s_wards.Count == 0)
			{
				return;
			}
			Vector3 position = ((Component)__instance).transform.position;
			foreach (PrivateArea s_ward in TerritoryWard.s_wards)
			{
				if (!s_ward.IsEnabled())
				{
					continue;
				}
				TerritoryWardController component = ((Component)s_ward).GetComponent<TerritoryWardController>();
				if (!((Object)(object)component == (Object)null) && !component.IsShielded() && component.HasPassiveShield() && !component.IsPointInside(position) && component.IsPointInside(position, 4f))
				{
					ItemData currentWeapon = __instance.GetCurrentWeapon();
					float num = ((currentWeapon != null) ? ((DamageTypes)(ref currentWeapon.m_shared.m_damages)).GetTotalDamage() : 0f);
					if (!(num <= 0f))
					{
						component.DrainPassiveShield(num);
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "RPC_TogglePermitted")]
	public static class Patch_PrivateArea_RPC_TogglePermitted_AllowWhileEnabled
	{
		private static bool Prefix(PrivateArea __instance, long uid, long playerID, string name)
		{
			TerritoryWardController component = ((Component)__instance).GetComponent<TerritoryWardController>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			bool flag = __instance.m_nview.IsOwner();
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"[Territory] RPC_TogglePermitted: target={name}({playerID}) isOwner={flag}");
			}
			if (!flag)
			{
				return false;
			}
			if (__instance.m_piece.GetCreator() != uid && __instance.IsEnabled())
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"[Territory] RPC_TogglePermitted: non-creator self toggle blocked (ward enabled) target={name}({playerID})");
				}
				return false;
			}
			if (__instance.IsPermitted(playerID))
			{
				__instance.RemovePermitted(playerID);
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)$"[Territory] RPC_TogglePermitted: removed {name}({playerID})");
				}
			}
			else
			{
				__instance.AddPermitted(playerID, name);
				ManualLogSource log4 = Plugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)$"[Territory] RPC_TogglePermitted: added {name}({playerID})");
				}
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				bool flag2 = KnownPlayersRegistry.RecordPlayer(playerID, name);
				ManualLogSource log5 = Plugin.Log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"[Territory] RPC_TogglePermitted: RecordPlayer({name},{playerID}) recorded={flag2}");
				}
				if (flag2)
				{
					KnownPlayersSync.BroadcastToAll();
				}
			}
			return false;
		}
	}
	[BepInPlugin("KorCaptain_territorial_ward", "Captain Territorial", "1.0.85")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string UpgradeButtonName = "TerritorialWardUpgrade";

		internal static ButtonConfig UpgradeButton;

		internal static ButtonConfig ShieldButton;

		internal static ButtonConfig RangeRingButton;

		internal static ManualLogSource Log;

		private readonly Harmony _harmony = new Harmony("KorCaptain.Captain_territorial");

		private void Awake()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			TerritoryConfig.Init(((BaseUnityPlugin)this).Config);
			TerritoryLocalization.Register();
			VFXManager.Initialize();
			PrefabManager.OnVanillaPrefabsAvailable += TerritoryWard.Create;
			PrefabManager.OnVanillaPrefabsAvailable += TerritoryLocalization.RefreshWardDescription;
			UpgradeButton = new ButtonConfig
			{
				Name = "TerritorialWardUpgrade",
				Config = TerritoryConfig.UpgradeKey,
				HintToken = "$territoryward_upgrade_hint_key"
			};
			InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, UpgradeButton);
			ShieldButton = new ButtonConfig
			{
				Name = "TerritorialWardShield",
				Config = TerritoryConfig.ShieldKey,
				HintToken = "$territoryward_shield_hint_key"
			};
			InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, ShieldButton);
			RangeRingButton = new ButtonConfig
			{
				Name = "TerritorialWardRangeRing",
				Config = TerritoryConfig.RangeRingKey,
				HintToken = "$territoryward_rangering_hint_key"
			};
			InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, RangeRingButton);
			SynchronizationManager.OnConfigurationSynchronized += delegate(object _, ConfigurationSynchronizationEventArgs e)
			{
				if (e.InitialSynchronization)
				{
					TerritoryLocalization.RefreshWardDescription();
				}
			};
			_harmony.PatchAll();
			((MonoBehaviour)this).InvokeRepeating("ScanKnownPlayers", 5f, 5f);
			((MonoBehaviour)this).InvokeRepeating("UpdateWardMapPins", 5f, 5f);
			PrintLoadedMessage();
		}

		private void UpdateWardMapPins()
		{
			TerritoryWardMapPinManager.Update();
		}

		private void ScanKnownPlayers()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			bool flag = false;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				long playerID = allPlayer.GetPlayerID();
				if (playerID != 0 && KnownPlayersRegistry.RecordPlayer(playerID, allPlayer.GetPlayerName()))
				{
					flag = true;
				}
			}
			if (flag)
			{
				KnownPlayersSync.BroadcastToAll();
			}
		}

		private void PrintLoadedMessage()
		{
			string text = $"[Captain_territorial] Captain Territorial {((BaseUnityPlugin)this).Info.Metadata.Version} Loaded!";
			try
			{
				Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager");
				MethodInfo methodInfo = type?.GetMethod("SetConsoleColor", Binding