Decompiled source of Uriel v0.22.0

BepInEx/plugins/Uriel.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Behaviours;
using ProjectM.CastleBuilding;
using ProjectM.Network;
using ProjectM.Pathfinding;
using ProjectM.Scripting;
using ProjectM.Shared;
using ProjectM.Tiles;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
using Uriel.Config;
using Uriel.Services;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("kdpen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026 Kristopher Penland")]
[assembly: AssemblyDescription("Uriel, Lord of Hosts — a host of server-side quality-of-life enhancements and structural fixes for V Rising dedicated servers.")]
[assembly: AssemblyFileVersion("0.22.0.0")]
[assembly: AssemblyInformationalVersion("0.22.0+0bad5feee6e3350ee41d2c693db75ce1d5f3eeef")]
[assembly: AssemblyProduct("Uriel")]
[assembly: AssemblyTitle("Uriel")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.22.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Uriel
{
	internal static class Core
	{
		private static bool _initInProgress;

		private static int _initAttempts;

		public static World Server { get; private set; }

		public static EntityManager EntityManager { get; private set; }

		public static PrefabCollectionSystem PrefabCollectionSystem { get; private set; }

		public static ServerScriptMapper ServerScriptMapper { get; private set; }

		public static DebugEventsSystem DebugEventsSystem { get; private set; }

		public static ServerGameManager ServerGameManager => ServerScriptMapper.GetServerGameManager();

		public static PublicStorageService PublicStorage { get; private set; }

		public static ItemCatalogService ItemCatalog { get; private set; }

		public static StairSwapService StairSwap { get; private set; }

		public static ObjectSpawnService ObjectSpawn { get; private set; }

		public static ObjectConditionsService ObjectConditions { get; private set; }

		public static PlayerUnlockService PlayerUnlock { get; private set; }

		public static UnitSpawnService Units { get; private set; }

		public static CastleEventService Events { get; private set; }

		public static ManualLogSource Log => Plugin.PluginLog;

		public static bool IsReady { get; private set; }

		internal static void TryInitialize(string trigger)
		{
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Expected O, but got Unknown
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (IsReady || _initInProgress)
			{
				return;
			}
			_initInProgress = true;
			_initAttempts++;
			bool flag = default(bool);
			try
			{
				World val = FindServerWorld();
				BepInExInfoLogInterpolatedStringHandler val2;
				if (val == null)
				{
					if (_initAttempts == 1)
					{
						ManualLogSource log = Log;
						val2 = new BepInExInfoLogInterpolatedStringHandler(56, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Uriel init (");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(trigger);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): Server world not yet present; will retry.");
						}
						log.LogInfo(val2);
					}
					return;
				}
				PrefabCollectionSystem existingSystemManaged = val.GetExistingSystemManaged<PrefabCollectionSystem>();
				if (existingSystemManaged == null || existingSystemManaged.SpawnableNameToPrefabGuidDictionary.Count == 0)
				{
					if (_initAttempts == 1)
					{
						ManualLogSource log2 = Log;
						val2 = new BepInExInfoLogInterpolatedStringHandler(68, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Uriel init (");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(trigger);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): PrefabCollectionSystem not yet populated; will retry.");
						}
						log2.LogInfo(val2);
					}
					return;
				}
				Server = val;
				EntityManager = val.EntityManager;
				PrefabCollectionSystem = existingSystemManaged;
				ServerScriptMapper = val.GetExistingSystemManaged<ServerScriptMapper>();
				DebugEventsSystem = val.GetExistingSystemManaged<DebugEventsSystem>();
				Tick.StartDriver();
				ItemCatalog = new ItemCatalogService();
				ItemCatalog.Build();
				StairSwap = new StairSwapService();
				PlayerUnlock = new PlayerUnlockService();
				PlayerUnlock.Load();
				ObjectConditions = new ObjectConditionsService();
				ObjectConditions.Load();
				ObjectSpawn = new ObjectSpawnService();
				ObjectSpawn.Load();
				try
				{
					ObjectSpawn.ReapplySpawned();
				}
				catch (Exception ex)
				{
					ManualLogSource log3 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel SPAWN] boot re-apply failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
					}
					log3.LogWarning(val3);
				}
				try
				{
					ObjectSpawn.StartRespawnLoop();
				}
				catch (Exception ex2)
				{
					ManualLogSource log4 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel SPAWN] respawn loop start failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex2);
					}
					log4.LogWarning(val3);
				}
				try
				{
					ObjectSpawn.StartOrphanSweepLoop();
				}
				catch (Exception ex3)
				{
					ManualLogSource log5 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel SPAWN] orphan sweep start failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex3);
					}
					log5.LogWarning(val3);
				}
				Units = new UnitSpawnService();
				try
				{
					Units.Start();
				}
				catch (Exception ex4)
				{
					ManualLogSource log6 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(27, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel UNIT] start failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex4);
					}
					log6.LogWarning(val3);
				}
				Events = new CastleEventService();
				Events.Load();
				try
				{
					Events.Start();
				}
				catch (Exception ex5)
				{
					ManualLogSource log7 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel EVENT] start failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex5);
					}
					log7.LogWarning(val3);
				}
				PublicStorage = new PublicStorageService();
				PublicStorage.Load();
				try
				{
					PublicStorage.ReapplyAll();
				}
				catch (Exception ex6)
				{
					ManualLogSource log8 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel SHARE] re-apply failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex6);
					}
					log8.LogWarning(val3);
				}
				try
				{
					KillSwitch.RunOnBootIfRequested();
				}
				catch (Exception ex7)
				{
					ManualLogSource log9 = Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel KILLSWITCH] boot restore failed: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex7);
					}
					log9.LogWarning(val3);
				}
				IsReady = true;
				ManualLogSource log10 = Log;
				val2 = new BepInExInfoLogInterpolatedStringHandler(60, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Uriel initialized via ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(trigger);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (attempt #");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_initAttempts);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("). Prefab map has ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(existingSystemManaged.SpawnableNameToPrefabGuidDictionary.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" entries.");
				}
				log10.LogInfo(val2);
			}
			catch (Exception ex8)
			{
				ManualLogSource log11 = Log;
				BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(35, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Uriel init (");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(trigger);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") FAILED on attempt #");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(_initAttempts);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<Exception>(ex8);
				}
				log11.LogError(val4);
			}
			finally
			{
				_initInProgress = false;
			}
		}

		private static World FindServerWorld()
		{
			Enumerator<World> enumerator = World.s_AllWorlds.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current.Name == "Server")
				{
					return current;
				}
			}
			return null;
		}
	}
	internal static class EntityExtensions
	{
		public delegate void RefAction<T>(ref T value) where T : unmanaged;

		public static bool Exists(this Entity entity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (entity != Entity.Null)
			{
				EntityManager entityManager = Core.EntityManager;
				return ((EntityManager)(ref entityManager)).Exists(entity);
			}
			return false;
		}

		public static bool Has<T>(this Entity entity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (entity.Exists())
			{
				EntityManager entityManager = Core.EntityManager;
				return ((EntityManager)(ref entityManager)).HasComponent<T>(entity);
			}
			return false;
		}

		public static T Read<T>(this Entity entity) where T : unmanaged
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			return ((EntityManager)(ref entityManager)).GetComponentData<T>(entity);
		}

		public static void Write<T>(this Entity entity, T value) where T : unmanaged
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			((EntityManager)(ref entityManager)).SetComponentData<T>(entity, value);
		}

		public static bool TryGetComponent<T>(this Entity entity, out T component) where T : unmanaged
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (entity.Exists())
			{
				EntityManager entityManager = Core.EntityManager;
				if (((EntityManager)(ref entityManager)).HasComponent<T>(entity))
				{
					entityManager = Core.EntityManager;
					component = ((EntityManager)(ref entityManager)).GetComponentData<T>(entity);
					return true;
				}
			}
			component = default(T);
			return false;
		}

		public static void With<T>(this Entity entity, RefAction<T> mutator) where T : unmanaged
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<T>())
			{
				ManualLogSource log = Core.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel] Entity.With<");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(typeof(T).Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(">: component missing on ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Entity>(entity);
				}
				log.LogWarning(val);
			}
			else
			{
				EntityManager entityManager = Core.EntityManager;
				T value = ((EntityManager)(ref entityManager)).GetComponentData<T>(entity);
				mutator(ref value);
				entityManager = Core.EntityManager;
				((EntityManager)(ref entityManager)).SetComponentData<T>(entity, value);
			}
		}

		public static void AddOrSet<T>(this Entity entity, T value) where T : unmanaged
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_001e: 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)
			if (entity.Exists())
			{
				EntityManager entityManager = Core.EntityManager;
				if (!((EntityManager)(ref entityManager)).HasComponent<T>(entity))
				{
					entityManager = Core.EntityManager;
					((EntityManager)(ref entityManager)).AddComponent<T>(entity);
				}
				entityManager = Core.EntityManager;
				((EntityManager)(ref entityManager)).SetComponentData<T>(entity, value);
			}
		}

		public static void RemoveIfPresent<T>(this Entity entity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (entity.Has<T>())
			{
				EntityManager entityManager = Core.EntityManager;
				((EntityManager)(ref entityManager)).RemoveComponent<T>(entity);
			}
		}

		public static ulong GetSteamId(this Entity playerCharacter)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			if (playerCharacter.TryGetComponent<PlayerCharacter>(out PlayerCharacter component) && component.UserEntity.TryGetComponent<User>(out User component2))
			{
				return component2.PlatformId;
			}
			return 0uL;
		}

		public static PrefabGUID GetPrefabGuid(this Entity entity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.TryGetComponent<PrefabGUID>(out PrefabGUID component))
			{
				return default(PrefabGUID);
			}
			return component;
		}

		public unsafe static bool TryResolvePlayer(string nameOrId, out ulong steamId, out string resolvedName, out string error)
		{
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			steamId = 0uL;
			resolvedName = null;
			error = null;
			if (string.IsNullOrWhiteSpace(nameOrId))
			{
				error = "Provide a character name or steamId.";
				return false;
			}
			if (ulong.TryParse(nameOrId, out var result) && result > 1000)
			{
				steamId = result;
				resolvedName = result.ToString();
				return true;
			}
			EntityManager entityManager = Core.EntityManager;
			EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<User>() });
			NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
			int num = 0;
			try
			{
				for (int i = 0; i < val2.Length; i++)
				{
					if (!val2[i].TryGetComponent<User>(out User component))
					{
						continue;
					}
					string text = ((object)(*(FixedString64Bytes*)(&component.CharacterName))/*cast due to .constrained prefix*/).ToString();
					if (!string.IsNullOrEmpty(text) && text.Contains(nameOrId, StringComparison.OrdinalIgnoreCase))
					{
						num++;
						steamId = component.PlatformId;
						resolvedName = text;
						if (string.Equals(text, nameOrId, StringComparison.OrdinalIgnoreCase))
						{
							num = 1;
							break;
						}
					}
				}
			}
			finally
			{
				val2.Dispose();
			}
			if (num == 0)
			{
				error = "No player matches '" + nameOrId + "'.";
				return false;
			}
			if (num > 1)
			{
				error = "'" + nameOrId + "' matches multiple players — be more specific or use the steamId.";
				steamId = 0uL;
				return false;
			}
			return true;
		}

		public static string GetPrefabName(this PrefabGUID prefabGuid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PrefabLookupMap prefabLookupMap = Core.PrefabCollectionSystem._PrefabLookupMap;
				NativeParallelHashMap<PrefabGUID, Entity> guidToEntityMap = prefabLookupMap.GuidToEntityMap;
				if (guidToEntityMap.ContainsKey(prefabGuid))
				{
					return ((PrefabLookupMap)(ref prefabLookupMap)).GetName(prefabGuid);
				}
			}
			catch
			{
			}
			return $"PrefabGuid({prefabGuid._Value})";
		}
	}
	[BepInPlugin("kdpen.Uriel", "Uriel", "0.22.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		internal static Harmony Harmony;

		internal static ManualLogSource PluginLog;

		internal static Plugin Instance { get; private set; }

		public override void Load()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			if (!(Application.productName != "VRisingServer"))
			{
				Instance = this;
				PluginLog = ((BasePlugin)this).Log;
				ManualLogSource log = ((BasePlugin)this).Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("kdpen.Uriel");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.22.0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loading...");
				}
				log.LogInfo(val);
				Settings.Initialize(((BasePlugin)this).Config);
				Harmony = new Harmony("kdpen.Uriel");
				Harmony.PatchAll(Assembly.GetExecutingAssembly());
				int num = Harmony.GetPatchedMethods().Count();
				ManualLogSource log2 = ((BasePlugin)this).Log;
				val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Harmony patches applied: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" method(s) patched.");
				}
				log2.LogInfo(val);
				CommandRegistry.RegisterAll();
				ManualLogSource log3 = ((BasePlugin)this).Log;
				val = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("kdpen.Uriel");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.22.0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. Awaiting game data init.");
				}
				log3.LogInfo(val);
			}
		}

		public override bool Unload()
		{
			CommandRegistry.UnregisterAssembly();
			Core.PublicStorage?.SaveSync();
			Core.Events?.SaveSync();
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "kdpen.Uriel";

		public const string PLUGIN_NAME = "Uriel";

		public const string PLUGIN_VERSION = "0.22.0";
	}
}
namespace Uriel.Services
{
	internal static class CastleDoors
	{
		private static string F(float v)
		{
			return v.ToString("0.0", CultureInfo.InvariantCulture);
		}

		public static Entity Nearest(Entity heart, float3 pos, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00bb: 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)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			Entity result = Entity.Null;
			float num = radius;
			EntityQueryBuilder val = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
			val = ((EntityQueryBuilder)(ref val)).AddAll(new ComponentType(Il2CppType.Of<Door>(), (AccessMode)1));
			val = ((EntityQueryBuilder)(ref val)).AddAll(new ComponentType(Il2CppType.Of<CastleHeartConnection>(), (AccessMode)1));
			val = ((EntityQueryBuilder)(ref val)).AddAll(new ComponentType(Il2CppType.Of<Translation>(), (AccessMode)1));
			EntityQueryBuilder val2 = ((EntityQueryBuilder)(ref val)).WithOptions((EntityQueryOptions)66);
			EntityManager entityManager = Core.EntityManager;
			EntityQuery val3 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val2);
			try
			{
				NativeArray<Entity> val4 = ((EntityQuery)(ref val3)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					Enumerator<Entity> enumerator = val4.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						if (heart != Entity.Null)
						{
							CastleHeartConnection val5 = current.Read<CastleHeartConnection>();
							if (((NetworkedEntity)(ref val5.CastleHeartEntity)).GetEntityOnServer() != heart)
							{
								continue;
							}
						}
						float num2 = math.distance(current.Read<Translation>().Value, pos);
						if (num2 <= num)
						{
							num = num2;
							result = current;
						}
					}
					return result;
				}
				finally
				{
					val4.Dispose();
				}
			}
			finally
			{
				((EntityQuery)(ref val3)).Dispose();
			}
		}

		public static Entity At(Entity heart, float3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return Nearest(Entity.Null, pos, 1f);
		}

		public static string Diagnose(float3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			EntityQueryBuilder val = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
			val = ((EntityQueryBuilder)(ref val)).AddAll(new ComponentType(Il2CppType.Of<Door>(), (AccessMode)1));
			EntityQueryBuilder val2 = ((EntityQueryBuilder)(ref val)).WithOptions((EntityQueryOptions)66);
			EntityManager entityManager = Core.EntityManager;
			EntityQuery val3 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val2);
			try
			{
				NativeArray<Entity> val4 = ((EntityQuery)(ref val3)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					int num = 0;
					int num2 = 0;
					float num3 = float.MaxValue;
					float num4 = float.MaxValue;
					Enumerator<Entity> enumerator = val4.GetEnumerator();
					while (enumerator.MoveNext())
					{
						Entity current = enumerator.Current;
						if (current.Has<CastleHeartConnection>())
						{
							num++;
						}
						if (current.TryGetComponent<Translation>(out Translation component))
						{
							num2++;
							num3 = math.min(num3, math.distance(component.Value, pos));
						}
						if (current.TryGetComponent<LocalToWorld>(out LocalToWorld component2))
						{
							num4 = math.min(num4, math.distance(((LocalToWorld)(ref component2)).Position, pos));
						}
					}
					return $"doors={val4.Length} withHeart={num} withTranslation={num2} nearest={D(num3)} nearestLtw={D(num4)}";
				}
				finally
				{
					val4.Dispose();
				}
			}
			finally
			{
				((EntityQuery)(ref val3)).Dispose();
			}
			static string D(float d)
			{
				if (!(d < float.MaxValue))
				{
					return "-";
				}
				return F(d);
			}
		}

		public static bool IsOpen(Entity door)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (door.TryGetComponent<Door>(out Door component))
			{
				return component.OpenState;
			}
			return false;
		}

		public static bool IsLocked(Entity door)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (door.TryGetComponent<Interactable>(out Interactable component))
			{
				return component.Disabled;
			}
			return false;
		}

		public static bool SetOpen(Entity door, bool open)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!door.TryGetComponent<Door>(out Door component))
			{
				return false;
			}
			if (component.OpenState == open)
			{
				return true;
			}
			component.OpenState = open;
			door.Write<Door>(component);
			return true;
		}

		public static bool SetLocked(Entity door, bool locked)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (!door.TryGetComponent<Interactable>(out Interactable component))
			{
				return false;
			}
			if (component.Disabled == locked)
			{
				return true;
			}
			component.Disabled = locked;
			door.Write<Interactable>(component);
			return true;
		}

		public static string Describe(Entity door)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (!door.Exists())
			{
				return "none";
			}
			float3 value = door.Read<Translation>().Value;
			string prefabName = door.GetPrefabGuid().GetPrefabName();
			return $"{prefabName} x={F(value.x)} y={F(value.y)} z={F(value.z)} open={IsOpen(door)} locked={IsLocked(door)} interactable={door.Has<Interactable>()}";
		}
	}
	internal sealed class CastleEventService
	{
		internal sealed class Marker
		{
			public int Id { get; set; }

			public float X { get; set; }

			public float Y { get; set; }

			public float Z { get; set; }

			public string Slot { get; set; } = "mob";

			public int Prefab { get; set; }

			public int Count { get; set; }

			public int Level { get; set; }

			public string Contain { get; set; }

			public int PaidItem { get; set; }

			public int PaidAmount { get; set; }

			public ulong PaidBy { get; set; }
		}

		internal sealed class Group
		{
			public string Name { get; set; }

			public int Floor { get; set; }

			public float[] Door { get; set; }

			public string Squad { get; set; }

			public List<Marker> Markers { get; set; } = new List<Marker>();
		}

		internal sealed class Layout
		{
			public int Territory { get; set; }

			public int NextMarkerId { get; set; } = 1;

			public List<Group> Groups { get; set; } = new List<Group>();
		}

		internal sealed class HeldDoor
		{
			public int Territory { get; set; }

			public float X { get; set; }

			public float Y { get; set; }

			public float Z { get; set; }

			public bool WasOpen { get; set; }

			public bool WasLocked { get; set; }

			public bool Pending { get; set; }
		}

		internal sealed class RunRecord
		{
			public int Territory { get; set; }

			public string Template { get; set; }

			public string Options { get; set; }

			public DateTime StartedUtc { get; set; }

			public int Units { get; set; }

			public int Bosses { get; set; }

			public double BossSeconds { get; set; } = -1.0;

			public double Seconds { get; set; }

			public string Result { get; set; }
		}

		private sealed class SaveFile
		{
			public int SchemaVersion { get; set; } = 2;

			public Dictionary<string, Layout> Layouts { get; set; } = new Dictionary<string, Layout>();

			public Dictionary<string, Squad> Squads { get; set; } = new Dictionary<string, Squad>(StringComparer.OrdinalIgnoreCase);

			public Dictionary<string, FloorPlan> FloorPlans { get; set; } = new Dictionary<string, FloorPlan>(StringComparer.OrdinalIgnoreCase);

			public Dictionary<string, EventTemplate> EventTemplates { get; set; } = new Dictionary<string, EventTemplate>(StringComparer.OrdinalIgnoreCase);

			public List<RunRecord> History { get; set; } = new List<RunRecord>();

			public List<HeldDoor> HeldDoors { get; set; } = new List<HeldDoor>();
		}

		private sealed class RunGroup
		{
			public string Name;

			public string Tag;

			public string Squad;

			public HeldDoor Door;

			public int Spawned;

			public int Bosses;

			public bool Cleared;
		}

		private sealed class Run
		{
			public int Territory;

			public Entity Heart;

			public string Template;

			public string Options;

			public UnitScaling Scale;

			public ulong By;

			public DateTime Started;

			public DateTime? InPlace;

			public DateTime? BossesDown;

			public int LimitSeconds;

			public int Warned;

			public int Units;

			public int Bosses;

			public List<RunGroup> Groups = new List<RunGroup>();

			public string Prefix => $"ev{Territory}:";

			public double Elapsed => (DateTime.UtcNow - (InPlace ?? Started)).TotalSeconds;
		}

		internal interface IOwned
		{
			string Name { get; }

			ulong Owner { get; }
		}

		internal sealed class SquadEntry
		{
			public string Role { get; set; } = "mob";

			public List<int> Units { get; set; } = new List<int>();

			public int Count { get; set; } = 1;

			public bool Distinct { get; set; }

			public int Level { get; set; }
		}

		internal sealed class SquadSet
		{
			public int Weight { get; set; } = 1;

			public List<SquadEntry> Entries { get; set; } = new List<SquadEntry>();
		}

		internal sealed class Squad : IOwned
		{
			public string Name { get; set; }

			public ulong Owner { get; set; }

			public List<SquadSet> Sets { get; set; } = new List<SquadSet>();
		}

		internal sealed class FloorPlan : IOwned
		{
			public string Name { get; set; }

			public ulong Owner { get; set; }

			public Dictionary<string, List<string>> Groups { get; set; } = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
		}

		internal sealed class EventTemplate : IOwned
		{
			public string Name { get; set; }

			public ulong Owner { get; set; }

			public Dictionary<string, List<string>> Floors { get; set; } = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);

			public string Options { get; set; }

			[JsonIgnore]
			public string Squad { get; set; }
		}

		internal readonly record struct Rolled(int Guid, bool Boss, int Level);

		private const int HistoryKept = 100;

		private SaveFile _file = new SaveFile();

		private readonly Dictionary<int, Run> _runs = new Dictionary<int, Run>();

		private bool _loopStarted;

		private static readonly Random Rng = new Random();

		private const int PendingTries = 30;

		private bool _pendingLoop;

		private static string SaveDir => Path.Combine(Paths.ConfigPath, "Uriel");

		private static string SavePath => Path.Combine(SaveDir, "castle_events.json");

		public int PendingDoors => _file.HeldDoors.Count((HeldDoor h) => h.Pending);

		private static string F(float v)
		{
			return v.ToString("0.0", CultureInfo.InvariantCulture);
		}

		private static string Tag(int territory, string group)
		{
			return $"ev{territory}:{group.ToLowerInvariant()}";
		}

		public void Load()
		{
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				if (File.Exists(SavePath))
				{
					_file = JsonSerializer.Deserialize<SaveFile>(File.ReadAllText(SavePath)) ?? new SaveFile();
				}
				SaveFile file = _file;
				if (file.Layouts == null)
				{
					Dictionary<string, Layout> dictionary = (file.Layouts = new Dictionary<string, Layout>());
				}
				_file.Squads = new Dictionary<string, Squad>(_file.Squads ?? new Dictionary<string, Squad>(), StringComparer.OrdinalIgnoreCase);
				_file.FloorPlans = new Dictionary<string, FloorPlan>(_file.FloorPlans ?? new Dictionary<string, FloorPlan>(), StringComparer.OrdinalIgnoreCase);
				_file.EventTemplates = new Dictionary<string, EventTemplate>(_file.EventTemplates ?? new Dictionary<string, EventTemplate>(), StringComparer.OrdinalIgnoreCase);
				foreach (FloorPlan value in _file.FloorPlans.Values)
				{
					value.Groups = new Dictionary<string, List<string>>(value.Groups ?? new Dictionary<string, List<string>>(), StringComparer.OrdinalIgnoreCase);
				}
				foreach (EventTemplate value2 in _file.EventTemplates.Values)
				{
					value2.Floors = new Dictionary<string, List<string>>(value2.Floors ?? new Dictionary<string, List<string>>(), StringComparer.OrdinalIgnoreCase);
				}
				file = _file;
				if (file.History == null)
				{
					List<RunRecord> list = (file.History = new List<RunRecord>());
				}
				file = _file;
				if (file.HeldDoors == null)
				{
					List<HeldDoor> list3 = (file.HeldDoors = new List<HeldDoor>());
				}
				ManualLogSource log = Core.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(84, 6, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] loaded layouts=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.Layouts.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" squads=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.Squads.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" floorTemplates=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.FloorPlans.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" templates=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.EventTemplates.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" history=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.History.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" heldDoors=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_file.HeldDoors.Count);
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Core.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(31, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Uriel EVENT] failed loading ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SavePath);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val2);
				_file = new SaveFile();
			}
		}

		public void SaveSync()
		{
			Save();
		}

		private void Save()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			try
			{
				Directory.CreateDirectory(SaveDir);
				File.WriteAllText(SavePath, JsonSerializer.Serialize(_file, new JsonSerializerOptions
				{
					WriteIndented = true
				}));
			}
			catch (Exception ex)
			{
				ManualLogSource log = Core.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] failed saving ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(SavePath);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		public void Start()
		{
			foreach (HeldDoor heldDoor in _file.HeldDoors)
			{
				heldDoor.Pending = true;
			}
			StartPendingLoop();
			if (!_loopStarted)
			{
				_loopStarted = true;
				Tick.RunRepeating(30, Monitor);
			}
		}

		private void StartPendingLoop()
		{
			if (!_pendingLoop && _file.HeldDoors.Any((HeldDoor h) => h.Pending))
			{
				_pendingLoop = true;
				Tick.RunLater(300, delegate
				{
					ReleasePending(1);
				});
			}
		}

		private void ReleasePending(int attempt)
		{
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				List<HeldDoor> list = _file.HeldDoors.Where((HeldDoor h) => h.Pending).ToList();
				int num = 0;
				int num2 = 0;
				foreach (HeldDoor item in list)
				{
					if (Release(item, restore: true, out var why))
					{
						_file.HeldDoors.Remove(item);
						num++;
						ManualLogSource log = Core.Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(67, 6, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] door-released territory=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Territory);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" x=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(item.X));
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" z=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(item.Z));
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" open=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(item.WasOpen);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" locked=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(item.WasLocked);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" attempt=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(attempt);
						}
						log.LogInfo(val);
					}
					else if (attempt >= 30 && why == "no-heart")
					{
						_file.HeldDoors.Remove(item);
						num2++;
						ManualLogSource log2 = Core.Log;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(53, 4, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Uriel EVENT] door-abandoned territory=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(item.Territory);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" x=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(F(item.X));
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" z=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(F(item.Z));
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" reason=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(why);
						}
						log2.LogWarning(val2);
					}
					else if (attempt == 1)
					{
						ManualLogSource log3 = Core.Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 4, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] door-pending territory=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Territory);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" x=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(item.X));
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" z=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(item.Z));
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" reason=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(why);
						}
						log3.LogInfo(val);
					}
				}
				if (num + num2 > 0)
				{
					Save();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log4 = Core.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Uriel EVENT] pending doors failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log4.LogWarning(val2);
			}
			if (_file.HeldDoors.Any((HeldDoor h) => h.Pending))
			{
				Tick.RunLater((attempt < 30) ? 300 : 1800, delegate
				{
					ReleasePending(attempt + 1);
				});
			}
			else
			{
				_pendingLoop = false;
			}
		}

		private bool TryCallerPlot(Entity character, bool isAdmin, out float3 feet, out Entity heart, out int territory, out string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			feet = default(float3);
			heart = Entity.Null;
			territory = -1;
			message = null;
			if (!isAdmin && !Settings.CastleEvents_PlayerEvents.Value)
			{
				message = "Castle events are admin-only on this server (CastleEvents.PlayerEvents).";
				return false;
			}
			if (!character.TryGetComponent<Translation>(out Translation component))
			{
				message = "Can't read your position.";
				return false;
			}
			feet = component.Value;
			if (!Core.ObjectSpawn.TryResolvePlot(feet, out heart, out territory))
			{
				message = "Stand inside a castle plot to set up its event.";
				return false;
			}
			if (!ObjectSpawnService.CastleClaimedAndAlive(heart))
			{
				message = "That castle plot is abandoned or decaying.";
				return false;
			}
			if (!isAdmin && !ObjectSpawnService.OwnsHeart(character, heart))
			{
				message = "You can only set up events in your own castle.";
				ManualLogSource log = Core.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] refused reason=not-owner territory=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(character.GetSteamId());
				}
				log.LogInfo(val);
				return false;
			}
			return true;
		}

		private Layout LayoutFor(int territory, bool create)
		{
			string key = territory.ToString(CultureInfo.InvariantCulture);
			if (_file.Layouts.TryGetValue(key, out var value))
			{
				return value;
			}
			if (!create)
			{
				return null;
			}
			value = new Layout
			{
				Territory = territory
			};
			_file.Layouts[key] = value;
			return value;
		}

		private static Group FindGroup(Layout l, string name)
		{
			return l?.Groups.FirstOrDefault((Group g) => string.Equals(g.Name, name, StringComparison.OrdinalIgnoreCase));
		}

		private static bool ValidName(string name)
		{
			if (!string.IsNullOrWhiteSpace(name) && name.Length <= 24 && name != "*")
			{
				return name.All((char c) => char.IsLetterOrDigit(c) || c == '-' || c == '_');
			}
			return false;
		}

		public string AddMarker(Entity character, bool isAdmin, string group, string slot, string prefabArg, int count, int level, string containArg)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Expected O, but got Unknown
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			if (!TryCallerPlot(character, isAdmin, out var feet, out var heart, out var territory, out var message))
			{
				return message;
			}
			if (_runs.ContainsKey(territory))
			{
				return "An event is running on this plot. Stop it first ('.uriel event stop').";
			}
			if (!ValidName(group))
			{
				return "A group name is 1-24 letters, digits, '-' or '_'.";
			}
			slot = (slot ?? "mob").ToLowerInvariant();
			if (slot != "mob" && slot != "boss")
			{
				return "The slot is mob or boss.";
			}
			int guid = 0;
			string name = null;
			if (!string.IsNullOrEmpty(prefabArg) && prefabArg != "-" && !prefabArg.Equals("template", StringComparison.OrdinalIgnoreCase) && !UnitSpawnService.TryResolveUnitPrefab(prefabArg, out guid, out name, out message))
			{
				return message;
			}
			string text = ((string.IsNullOrWhiteSpace(containArg) || containArg == "-") ? null : containArg);
			if (text != null && !UnitSpawnService.TryParseContain(text, out var _, out message))
			{
				return message;
			}
			count = Math.Clamp(count, 0, Math.Max(1, Settings.CastleEvents_MaxUnitsPerCommand.Value));
			Layout layout = LayoutFor(territory, create: true);
			int num = layout.Groups.Sum((Group g) => g.Markers.Count);
			if (!isAdmin && num >= Settings.CastleEvents_MaxMarkersPerPlot.Value)
			{
				return $"This castle has the most markers allowed ({num}/{Settings.CastleEvents_MaxMarkersPerPlot.Value}). Remove one first.";
			}
			int value = Settings.CastleEvents_MarkerCostItem.Value;
			int num2 = ((slot == "boss") ? Settings.CastleEvents_BossMarkerCostAmount.Value : Settings.CastleEvents_MarkerCostAmount.Value);
			bool flag = !isAdmin && value != 0 && num2 > 0;
			if (flag && !ObjectSpawnService.HasInventoryItems(character, value, num2))
			{
				return $"A {slot} marker costs {num2}x {EntityExtensions.GetPrefabName(new PrefabGUID(value))}; you don't have enough in your inventory.";
			}
			CastleFloorIndex.Invalidate(heart, territory);
			int num3 = CastleFloorIndex.StoreyOf(heart, feet.y);
			Group obj = FindGroup(layout, group);
			if (obj == null)
			{
				List<Group> groups = layout.Groups;
				Group obj2 = new Group
				{
					Name = group,
					Floor = num3
				};
				obj = obj2;
				groups.Add(obj2);
			}
			if (flag && !ObjectSpawnService.ChargeInventory(character, value, num2))
			{
				return "Payment failed; the marker was not placed.";
			}
			Marker marker = new Marker
			{
				Id = layout.NextMarkerId++,
				X = feet.x,
				Y = feet.y,
				Z = feet.z,
				Slot = slot,
				Prefab = guid,
				Count = count,
				Level = level,
				Contain = text,
				PaidItem = (flag ? value : 0),
				PaidAmount = (flag ? num2 : 0),
				PaidBy = (flag ? character.GetSteamId() : 0)
			};
			obj.Markers.Add(marker);
			Save();
			ManualLogSource log = Core.Log;
			bool flag2 = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(107, 13, ref flag2);
			if (flag2)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] marker-added territory=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(obj.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" id=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(marker.Id);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" slot=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(slot);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" floor=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" x=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(marker.X));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" y=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(marker.Y));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" z=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(F(marker.Z));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" prefab=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name ?? "squad");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" count=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" level=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(level);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" contain=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text ?? "default");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" paid=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(marker.PaidAmount);
			}
			log.LogInfo(val);
			return $"Marker #{marker.Id} ({slot}) in group '{obj.Name}' (floor {obj.Floor}): {name ?? "units from the group's squad"}{((count > 0) ? $" x{count}" : "")}. The group has {obj.Markers.Count} marker(s){((obj.Door != null) ? " and a door" : ", no door")}." + ((marker.PaidAmount > 0) ? $" Paid {marker.PaidAmount}x {EntityExtensions.GetPrefabName(new PrefabGUID(value))}." : "");
		}

		public string BindDoor(Entity character, bool isAdmin, string group, bool unbind)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			if (!TryCallerPlot(character, isAdmin, out var feet, out var heart, out var territory, out var message))
			{
				return message;
			}
			if (_runs.ContainsKey(territory))
			{
				return "An event is running on this plot. Stop it first ('.uriel event stop').";
			}
			if (!unbind && !Settings.DoorGatesOn)
			{
				return "Event doors are disabled by the server admin (CastleEvents.DoorGates).";
			}
			Group g = FindGroup(LayoutFor(territory, create: false), group);
			if (g == null)
			{
				return $"No group '{group}' on this plot. A group starts with its first marker ('.uriel event marker {group}').";
			}
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val;
			if (unbind)
			{
				g.Door = null;
				Save();
				ManualLogSource log = Core.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] door-unbound territory=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(g.Name);
				}
				log.LogInfo(val);
				return "Group '" + g.Name + "' no longer holds a door.";
			}
			Entity val2 = CastleDoors.Nearest(heart, feet, 6f);
			if (val2 == Entity.Null)
			{
				return "No castle door within 6 m. Stand next to the door this group should hold shut.";
			}
			float3 p = val2.Read<Translation>().Value;
			Group obj = LayoutFor(territory, create: false).Groups.FirstOrDefault((Group o) => o != g && o.Door != null && math.distance(new float3(o.Door[0], o.Door[1], o.Door[2]), p) < 1f);
			if (obj != null)
			{
				return "That door is already held by group '" + obj.Name + "'.";
			}
			g.Door = new float[3] { p.x, p.y, p.z };
			Save();
			ManualLogSource log2 = Core.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(43, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] door-bound territory=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(g.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(CastleDoors.Describe(val2));
			}
			log2.LogInfo(val);
			return $"Group '{g.Name}' holds the door {val2.GetPrefabGuid().GetPrefabName()} ({F(math.distance(p, feet))} m away): shut while its units live, open once they are all defeated.";
		}

		public string SetGroupSquad(Entity character, bool isAdmin, string group, string squad)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			if (!TryCallerPlot(character, isAdmin, out var _, out var _, out var territory, out var message))
			{
				return message;
			}
			if (_runs.ContainsKey(territory))
			{
				return "An event is running on this plot. Stop it first ('.uriel event stop').";
			}
			Group obj = FindGroup(LayoutFor(territory, create: false), group);
			if (obj == null)
			{
				return $"No group '{group}' on this plot. A group starts with its first marker ('.uriel event marker {group}').";
			}
			if (squad == "-")
			{
				obj.Squad = null;
			}
			else
			{
				Squad squad2 = Find(_file.Squads, squad, character.GetSteamId(), isAdmin);
				if (squad2 == null)
				{
					return "No squad '" + squad + "'. '.uriel squad list' shows yours and the server's.";
				}
				obj.Squad = squad2.Name;
			}
			Save();
			ManualLogSource log = Core.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(50, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] group-squad territory=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(obj.Name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" squad=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(obj.Squad ?? "-");
			}
			log.LogInfo(val);
			if (obj.Squad != null)
			{
				return $"Group '{obj.Name}' spawns squad '{obj.Squad}' unless the run's template says otherwise.";
			}
			return "Group '" + obj.Name + "' has no squad of its own.";
		}

		public string Remove(Entity character, bool isAdmin, string what)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Expected O, but got Unknown
			if (!TryCallerPlot(character, isAdmin, out var _, out var _, out var territory, out var message))
			{
				return message;
			}
			if (_runs.ContainsKey(territory))
			{
				return "An event is running on this plot. Stop it first ('.uriel event stop').";
			}
			Layout layout = LayoutFor(territory, create: false);
			if (layout == null)
			{
				return "This plot has no event layout.";
			}
			List<Marker> list = new List<Marker>();
			string text;
			if (int.TryParse(what.TrimStart('#'), out var id))
			{
				Group obj = layout.Groups.FirstOrDefault((Group x) => x.Markers.Any((Marker m) => m.Id == id));
				if (obj == null)
				{
					return $"No marker #{id} on this plot.";
				}
				Marker item = obj.Markers.First((Marker x) => x.Id == id);
				obj.Markers.Remove(item);
				list.Add(item);
				if (obj.Markers.Count == 0)
				{
					layout.Groups.Remove(obj);
				}
				text = $"marker #{id}";
			}
			else
			{
				Group obj2 = FindGroup(layout, what);
				if (obj2 == null)
				{
					return $"No marker #{what} or group '{what}' on this plot.";
				}
				list.AddRange(obj2.Markers);
				layout.Groups.Remove(obj2);
				text = $"group '{obj2.Name}' ({list.Count} marker(s))";
			}
			string text2 = RefundMarkers(character, list);
			Save();
			ManualLogSource log = Core.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] removed territory=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" what=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(what);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" markers=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
			}
			log.LogInfo(val);
			return "Removed " + text + "." + text2;
		}

		private static string RefundMarkers(Entity character, List<Marker> markers)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			ulong me = character.GetSteamId();
			int num = 0;
			foreach (Marker item in markers.Where((Marker m) => m.PaidAmount > 0 && m.PaidItem != 0 && m.PaidBy == me))
			{
				ObjectSpawnService.RefundInventory(character, item.PaidItem, item.PaidAmount);
				num += item.PaidAmount;
			}
			if (num <= 0)
			{
				return "";
			}
			return $" Refunded {num} item(s).";
		}

		public List<string> Describe(Entity character, bool isAdmin)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Expected O, but got Unknown
			List<string> list = new List<string>();
			if (!TryCallerPlot(character, isAdmin, out var _, out var heart, out var territory, out var message))
			{
				list.Add(message);
				return list;
			}
			Layout layout = LayoutFor(territory, create: false);
			if (layout == null || layout.Groups.Count == 0)
			{
				list.Add("This plot has no event layout yet. Start one: '.uriel event marker <group>'.");
				return list;
			}
			list.Add($"Event layout of plot {territory}: {layout.Groups.Count} group(s), {layout.Groups.Sum((Group g) => g.Markers.Count)} marker(s){(_runs.ContainsKey(territory) ? "; RUNNING" : "")}.");
			bool flag = default(bool);
			foreach (Group item in from g in layout.Groups
				orderby g.Floor, layout.Groups.IndexOf(g)
				select g)
			{
				string value = ((item.Door == null) ? "no door" : DoorLabel(heart, item.Door));
				string value2 = string.Join(", ", item.Markers.Select((Marker m) => $"#{m.Id} {m.Slot} {((m.Prefab != 0) ? EntityExtensions.GetPrefabName(new PrefabGUID(m.Prefab)) : "squad")}{((m.Count > 0) ? $" x{m.Count}" : "")}"));
				list.Add($"Floor {item.Floor} · {item.Name} · {value} · squad {item.Squad ?? "-"} · {value2}");
				ManualLogSource log = Core.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(67, 6, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] layout territory=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" floor=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Floor);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" door=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((item.Door == null) ? "none" : $"{F(item.Door[0])},{F(item.Door[1])},{F(item.Door[2])}");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" squad=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Squad ?? "-");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" markers=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Markers.Count);
				}
				log.LogInfo(val);
			}
			return list;
		}

		private static string DoorLabel(Entity heart, float[] d)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			Entity val = CastleDoors.At(heart, new float3(d[0], d[1], d[2]));
			if (!(val == Entity.Null))
			{
				return $"door at {F(d[0])},{F(d[2])}{(CastleDoors.IsOpen(val) ? " (open)" : " (shut)")}";
			}
			return "door missing at " + F(d[0]) + "," + F(d[2]);
		}

		public string StartRun(Entity character, bool isAdmin, string templateName, string options)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0284: Expected O, but got Unknown
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_067d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0756: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b64: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6b: Expected O, but got Unknown
			//IL_0976: Unknown result type (might be due to invalid IL or missing references)
			//IL_097d: Expected O, but got Unknown
			//IL_07c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c69: Unknown result type (might be due to invalid IL or missing references)
			//IL_0831: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c9: Expected O, but got Unknown
			if (!Settings.CastleEventsOn)
			{
				return "Castle events are disabled by the server admin (CastleEvents.Enabled).";
			}
			if (!TryCallerPlot(character, isAdmin, out var _, out var heart, out var territory, out var message))
			{
				return message;
			}
			if (_runs.ContainsKey(territory))
			{
				return "An event is already running on this plot. '.uriel event stop' ends it.";
			}
			Layout layout = LayoutFor(territory, create: false);
			if (layout == null || layout.Groups.All((Group g) => g.Markers.Count == 0))
			{
				return "This plot has no event markers. Place some: '.uriel event marker <group>'.";
			}
			ulong steamId = character.GetSteamId();
			EventTemplate eventTemplate = null;
			string template = null;
			if (!string.IsNullOrEmpty(templateName) && templateName != "-")
			{
				EventTemplate eventTemplate2 = Find(_file.EventTemplates, templateName, steamId, isAdmin);
				if (eventTemplate2 != null)
				{
					eventTemplate = eventTemplate2;
				}
				else
				{
					FloorPlan floorPlan = Find(_file.FloorPlans, templateName, steamId, isAdmin);
					if (floorPlan != null)
					{
						eventTemplate = new EventTemplate
						{
							Name = floorPlan.Name,
							Floors = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase) { ["*"] = new List<string> { floorPlan.Name } }
						};
					}
					else
					{
						Squad squad = Find(_file.Squads, templateName, steamId, isAdmin);
						if (squad == null)
						{
							return "No template, floor template or squad '" + templateName + "'. '.uriel template list' shows the ones you can use.";
						}
						eventTemplate = new EventTemplate
						{
							Name = squad.Name,
							Squad = squad.Name
						};
					}
				}
				template = eventTemplate.Name;
			}
			if (!TryParseOptions(eventTemplate?.Options, UnitScaling.None, out var scale, out var limitSeconds, out var oneFaction, out message))
			{
				return "Template options: " + message;
			}
			if (!TryParseOptions(options, scale, out scale, out var limitSeconds2, out var oneFaction2, out message))
			{
				return message;
			}
			if (limitSeconds2 >= 0)
			{
				limitSeconds = limitSeconds2;
			}
			if (oneFaction2 >= 0)
			{
				oneFaction = oneFaction2;
			}
			string text = string.Join(",", new string[2]
			{
				eventTemplate?.Options,
				(options == "-") ? null : options
			}.Where((string o) => !string.IsNullOrWhiteSpace(o)));
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val;
			if (scale.Auto)
			{
				int num = HighestPlayerLevel(territory);
				scale = scale with
				{
					Auto = false,
					Level = ((num > 0) ? Math.Clamp(num + scale.LevelAdd, 1, 200) : 0),
					LevelAdd = 0
				};
				ManualLogSource log = Core.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(51, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] auto-level territory=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" highest=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" level=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(scale.Level);
				}
				log.LogInfo(val);
			}
			Dictionary<int, FloorPlan> rolledFloors = new Dictionary<int, FloorPlan>();
			List<(Group, string, List<(Marker, Rolled)>)> list = new List<(Group, string, List<(Marker, Rolled)>)>();
			List<string> list2 = new List<string>();
			foreach (Group item4 in layout.Groups.Where((Group g) => g.Markers.Count > 0))
			{
				string text2 = SquadFor(eventTemplate, item4, rolledFloors, steamId, isAdmin);
				Squad squad2 = ((text2 != null) ? Find(_file.Squads, text2, steamId, isAdmin) : null);
				if (text2 != null && squad2 == null)
				{
					return $"Group '{item4.Name}' gets squad '{text2}', which doesn't exist (or isn't yours).";
				}
				List<(Marker, Rolled)> list3 = Spread(item4, (squad2 != null) ? Roll(squad2) : new List<Rolled>());
				if (list3.Count == 0)
				{
					list2.Add($"'{item4.Name}' (floor {item4.Floor})");
				}
				list.Add((item4, squad2?.Name, list3));
			}
			if (list2.Count > 0)
			{
				return "No units for group(s) " + string.Join(", ", list2) + ": give the group a squad ('.uriel event squad <group> <squad>'), give its markers units, or start a template that covers it.";
			}
			int num2 = list.Sum<(Group, string, List<(Marker, Rolled)>)>(((Group G, string Squad, List<(Marker M, Rolled U)> Units) p) => p.Units.Count);
			int num3 = Core.Units.RoomOnPlot(territory);
			if (num2 > num3)
			{
				return $"This event needs {num2} units; only {Math.Max(0, num3)} fit under the unit caps (CastleEvents.MaxUnitsPerPlot / MaxTrackedUnits).";
			}
			int value = Settings.CastleEvents_RunCostItem.Value;
			int value2 = Settings.CastleEvents_RunCostAmount.Value;
			if (!isAdmin && value != 0 && value2 > 0)
			{
				if (!ObjectSpawnService.HasInventoryItems(character, value, value2))
				{
					return $"Starting an event costs {value2}x {EntityExtensions.GetPrefabName(new PrefabGUID(value))}; you don't have enough in your inventory.";
				}
				if (!ObjectSpawnService.ChargeInventory(character, value, value2))
				{
					return "Payment failed; the event did not start.";
				}
			}
			int num4 = 0;
			if (oneFaction != 0)
			{
				List<Rolled> list4 = (from x in list.SelectMany<(Group, string, List<(Marker, Rolled)>), (Marker, Rolled)>(((Group G, string Squad, List<(Marker M, Rolled U)> Units) p) => p.Units)
					select x.U).ToList();
				if (list4.Count > 0)
				{
					num4 = (list4.Any((Rolled u) => u.Boss) ? list4.First((Rolled u) => u.Boss) : list4[0]).Guid;
				}
			}
			Run run = new Run
			{
				Territory = territory,
				Heart = heart,
				Template = template,
				Options = ((text.Length > 0) ? text : null),
				Scale = scale,
				By = steamId,
				Started = DateTime.UtcNow,
				LimitSeconds = Math.Max(0, limitSeconds)
			};
			string value3 = Settings.CastleEvents_DefaultContain.Value;
			int num5 = 0;
			foreach (var item5 in list)
			{
				Group item = item5.Item1;
				string item2 = item5.Item2;
				List<(Marker, Rolled)> item3 = item5.Item3;
				RunGroup runGroup = new RunGroup
				{
					Name = item.Name,
					Tag = Tag(territory, item.Name),
					Squad = item2
				};
				run.Groups.Add(runGroup);
				if (item.Door != null && Settings.DoorGatesOn)
				{
					runGroup.Door = Hold(territory, heart, item);
				}
				foreach (IGrouping<Marker, (Marker, Rolled)> item6 in from u in item3
					group u by u.M)
				{
					Marker key = item6.Key;
					if (!UnitSpawnService.TryParseContain(key.Contain ?? value3, out var contain, out var _))
					{
						contain = new UnitSpawnService.Containment(UnitSpawnService.Contain.Plot, 0f, Entity.Null);
					}
					int num6 = 0;
					foreach (IGrouping<Rolled, (Marker, Rolled)> item7 in from u in item6
						group u by u.U)
					{
						int num7 = item7.Count();
						Rolled key2 = item7.Key;
						if (Core.Units.EnqueueAt(new float3(key.X, key.Y, key.Z), steamId, key2.Guid, EntityExtensions.GetPrefabName(new PrefabGUID(key2.Guid)), num7, key2.Level, contain, runGroup.Tag, out var message3, key2.Boss, scale.IsNone ? null : scale, num6, num4))
						{
							runGroup.Spawned += num7;
							if (key2.Boss)
							{
								runGroup.Bosses += num7;
							}
						}
						else
						{
							num5++;
							ManualLogSource log2 = Core.Log;
							BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(57, 4, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Uriel EVENT] marker-failed territory=");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(territory);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" group=");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(item.Name);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" id=");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(key.Id);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" reason=");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(message3);
							}
							log2.LogWarning(val2);
						}
						num6 += num7;
					}
				}
				ManualLogSource log3 = Core.Log;
				val = new BepInExInfoLogInterpolatedStringHandler(81, 7, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] group-rolled territory=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" group=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" floor=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item.Floor);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" squad=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item2 ?? "-");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" units=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(runGroup.Spawned);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" bosses=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(runGroup.Bosses);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("spawns=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(",", from u in item3
						group u by u.U.Guid into k
						select $"{EntityExtensions.GetPrefabName(new PrefabGUID(k.Key))}x{k.Count()}"));
				}
				log3.LogInfo(val);
			}
			run.Units = run.Groups.Sum((RunGroup x) => x.Spawned);
			run.Bosses = run.Groups.Sum((RunGroup x) => x.Bosses);
			_runs[territory] = run;
			Save();
			int num8 = run.Groups.Count((RunGroup x) => x.Door != null);
			ManualLogSource log4 = Core.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(114, 11, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] started territory=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" template=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(run.Template ?? "-");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" groups=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(run.Groups.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" units=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(run.Units);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" bosses=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(run.Bosses);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" doors=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num8);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failedMarkers=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num5);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" scale=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<UnitScaling>(scale);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" limit=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(run.LimitSeconds);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" faction=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((num4 == 0) ? "keep" : EntityExtensions.GetPrefabName(new PrefabGUID(num4)));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" by=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(run.By);
			}
			log4.LogInfo(val);
			Announce(run, $"A castle event has begun: {run.Units} foes{((run.Bosses > 0) ? $" ({run.Bosses} boss{((run.Bosses == 1) ? "" : "es")})" : "")} in {run.Groups.Count} group(s){((num8 > 0) ? $"; {num8} door(s) are sealed until their guards fall" : "")}{((run.LimitSeconds > 0) ? ("; time limit " + Clock(run.LimitSeconds)) : "")}.");
			return $"Event started{((run.Template != null) ? (" from '" + run.Template + "'") : "")}: {run.Units} unit(s), {run.Bosses} boss(es), {run.Groups.Count} group(s), {num8} door(s) held{(scale.IsNone ? "" : $", scaled {scale}")}{((run.LimitSeconds > 0) ? (", limit " + Clock(run.LimitSeconds)) : "")}." + ((num5 > 0) ? $" {num5} marker(s) could not spawn (see the server log)." : "");
		}

		private static string Clock(double seconds)
		{
			int num = (int)Math.Round(seconds);
			if (num >= 3600)
			{
				return $"{num / 3600}h {num % 3600 / 60:00}m";
			}
			return $"{num / 60}m {num % 60:00}s";
		}

		private string SquadFor(EventTemplate t, Group g, Dictionary<int, FloorPlan> rolledFloors, ulong me, bool isAdmin)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			if (t != null && t.Squad != null)
			{
				return t.Squad;
			}
			if (t != null)
			{
				string key = g.Floor.ToString(CultureInfo.InvariantCulture);
				List<string> value;
				List<string> value2;
				List<string> list = (t.Floors.TryGetValue(key, out value) ? value : (t.Floors.TryGetValue("*", out value2) ? value2 : null));
				if (list != null && list.Count > 0)
				{
					if (!rolledFloors.TryGetValue(g.Floor, out var value3))
					{
						value3 = Find(_file.FloorPlans, list[Rng.Next(list.Count)], me, isAdmin);
						rolledFloors[g.Floor] = value3;
						if (value3 != null)
						{
							ManualLogSource log = Core.Log;
							bool flag = default(bool);
							BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Uriel EVENT] floor-rolled floor=");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(g.Floor);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" template=");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value3.Name);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" of=");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
							}
							log.LogInfo(val);
						}
					}
					if (value3 != null && (value3.Groups.TryGetValue(g.Name, out var value4) || value3.Groups.TryGetValue("*", out value4)) && value4.Count > 0)
					{
						return value4[Rng.Next(value4.Count)];
					}
				}
			}
			return g.Squad;
		}

		private static List<(Marker M, Rolled U)> Spread(Group g, List<Rolled> rolled)
		{
			List<(Marker, Rolled)> list = new List<(Marker, Rolled)>();
			foreach (Marker item in g.Markers.Where((Marker m) => m.Prefab != 0))
			{
				for (int num = 0; num < Math.Max(1, item.Count); num++)
				{
					list.Add((item, new Rolled(item.Prefab, item.Slot == "boss", item.Level)));
				}
			}
			List<Marker> list2 = g.Markers.Where((Marker m) => m.Prefab == 0).ToList();
			if (list2.Count == 0)
			{
				list2 = g.Markers;
			}
			List<Marker> list3 = list2.Where((Marker m) => m.Slot == "boss").ToList();
			List<Marker> list4 = list2.Where((Marker m) => m.Slot != "boss").ToList();
			if (list3.Count == 0)
			{
				list3 = list2;
			}
			if (list4.Count == 0)
			{
				list4 = list2;
			}
			int num2 = 0;
			int num3 = 0;
			foreach (Rolled item2 in rolled)
			{
				list.Add(item2.Boss ? (list3[num2++ % list3.Count], item2) : (list4[num3++ % list4.Count], item2));
			}
			return list;
		}

		private static int HighestPlayerLevel(int territory)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (Entity item in PlayersOn(territory))
			{
				if (item.TryGetComponent<Equipment>(out Equipment component))
				{
					num = Math.Max(num, (int)Math.Round(((Equipment)(ref component)).GetFullLevel()));
				}
			}
			return num;
		}

		private HeldDoor Hold(int territory, Entity heart, Group g)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			float3 val = default(float3);
			((float3)(ref val))..ctor(g.Door[0], g.Door[1], g.Door[2]);
			Entity val2 = CastleDoors.At(heart, val);
			bool flag = default(bool);
			if (val2 == Entity.Null)
			{
				ManualLogSource log = Core.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(50, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Uriel EVENT] door-missing territory=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(territory);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" group=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(g.Name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" x=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(F(val.x));
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" z=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(F(val.z));
				}
				log.LogWarning(val3);
				return null;
			}
			HeldDoor heldDoor = new HeldDoor
			{
				Territory = territory,
				X = val.x,
				Y = val.y,
				Z = val.z,
				WasOpen = CastleDoors.IsOpen(val2),
				WasLocked = CastleDoors.IsLocked(val2)
			};
			CastleDoors.SetOpen(val2, open: false);
			CastleDoors.SetLocked(val2, locked: true);
			_file.HeldDoors.Add(heldDoor);
			ManualLogSource log2 = Core.Log;
			BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(51, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Uriel EVENT] door-held territory=");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(territory);
				((BepInExLogInterpolatedStringHandler)val4).Append