Decompiled source of BNYS mod v1.3.0

Bunject.NewYardSystem.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using Bunburrows;
using Bunject.Computer;
using Bunject.Dialogue;
using Bunject.Internal;
using Bunject.Levels;
using Bunject.Menu;
using Bunject.Monitoring;
using Bunject.NewYardSystem.Computer;
using Bunject.NewYardSystem.Internal;
using Bunject.NewYardSystem.Levels;
using Bunject.NewYardSystem.Levels.Archive;
using Bunject.NewYardSystem.Levels.Local;
using Bunject.NewYardSystem.Levels.Web;
using Bunject.NewYardSystem.Model;
using Bunject.NewYardSystem.Resources;
using Bunject.NewYardSystem.Utility;
using Bunject.Tiling;
using Characters.Bunny.Data;
using Dialogue;
using HarmonyLib;
using Levels;
using Misc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Tiling.Behaviour;
using UnityEngine;
using UnityEngine.Tilemaps;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BunjectNewYardSystem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BunjectNewYardSystem")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("72607052-293c-42fa-b044-aed2841c5102")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Bunject.NewYardSystem
{
	[BepInPlugin("sergedev.bunject.newyardsystem", "BNYS", "1.3.0")]
	public class BNYSPlugin : BaseUnityPlugin, IBunjectorPlugin, IMonitor, IMenuSource, IComputerPageSource
	{
		public const string pluginGuid = "sergedev.bunject.newyardsystem";

		public const string pluginName = "BNYS";

		public const string pluginVersion = "1.3.0";

		public static string pluginsDirectory = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..\\"));

		public static string rootDirectory = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

		public static string inlineDirectory = Path.Combine(rootDirectory, "BNYS");

		private List<CustomWorld> CustomWorlds;

		private List<IModBunburrow> AllModBurrows;

		private List<BNYSModBunburrowBase> BNYSModBurrows;

		private CustomWorld CurrentCustomWorld;

		private CustomWorld WorldPendingDeletion;

		private EmergencyLevelsList emergencyList;

		public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		public string MenuTitle => "BNYS";

		public void Awake()
		{
			Logger.LogInfo((object)"Bunject New Yard System [BNYS] Plugin Awakened. v1.3.0");
			CustomBunburrowCache customBunburrowCache = new CustomBunburrowCache();
			try
			{
				CustomWorlds = LoadCustomWorlds().ToList();
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"Error caught on loading custom burrows... ");
				Logger.LogError((object)ex.Message);
				Logger.LogError((object)ex);
				return;
			}
			List<IModBunburrow> list = new List<IModBunburrow>();
			if (CustomWorlds.Count > 0)
			{
				Logger.LogInfo((object)"Initial Load - Building Cached Burrows!");
				foreach (CustomBunburrowModel cachedBurrow in customBunburrowCache.CustomBurrows)
				{
					Burrow burrowModel = CustomWorlds.Where((CustomWorld cw) => cachedBurrow.World == cw.Title || string.IsNullOrEmpty(cachedBurrow.World)).SelectMany((CustomWorld cw) => cw.Burrows).FirstOrDefault((Burrow b) => b.Name == cachedBurrow.Name);
					CustomWorld customWorld = CustomWorlds.FirstOrDefault((CustomWorld cw) => cw.Burrows.Contains(burrowModel));
					if (burrowModel != null)
					{
						Logger.LogInfo((object)("Cached Burrow : " + burrowModel.Name + " found!"));
						cachedBurrow.World = customWorld.Title;
						cachedBurrow.Prefix = customWorld.Prefix;
						cachedBurrow.Indicator = burrowModel.Indicator;
						list.Add((IModBunburrow)(object)customWorld.GenerateBunburrow(this, burrowModel.Name));
					}
					else
					{
						Logger.LogInfo((object)("Cached Burrow : " + cachedBurrow.Name + " NOT found!"));
						list.Add((IModBunburrow)(object)new BNYSLostBunburrow(cachedBurrow));
					}
				}
				Logger.LogInfo((object)"Initial Load - Building Uncached Burrows!");
				foreach (Burrow burrow in CustomWorlds.SelectMany((CustomWorld cw) => cw.Burrows))
				{
					CustomWorld customWorld2 = CustomWorlds.FirstOrDefault((CustomWorld cw) => cw.Burrows.Contains(burrow));
					if (customBunburrowCache.CustomBurrows.FirstOrDefault((CustomBunburrowModel cb) => cb.Name == burrow.Name && (cb.World == customWorld2.Title || string.IsNullOrEmpty(cb.World))) == null)
					{
						Logger.LogInfo((object)("Uncached Burrow : " + burrow.Name + " built!"));
						BNYSModBunburrowBase bNYSModBunburrowBase = customWorld2.GenerateBunburrow(this, burrow.Name);
						list.Add((IModBunburrow)(object)bNYSModBunburrowBase);
						customBunburrowCache.CacheBunburrow(bNYSModBunburrowBase);
					}
				}
				customBunburrowCache.SaveCache();
				AllModBurrows = list.ToList();
				BNYSModBurrows = list.OfType<BNYSModBunburrowBase>().ToList();
				LinkLevelLists(BNYSModBurrows);
				BunjectAPI.RegisterPlugin((IBunjectorPlugin)(object)this);
				Logger.LogInfo((object)"Initial Load Finished!");
			}
			else
			{
				Logger.LogInfo((object)"All worlds empty! Please configure a burrow with a surface entrance, and depth of at least 1!");
			}
		}

		public void OnAssetsLoaded()
		{
		}

		public void OnProgressionLoaded(GeneralProgression progression)
		{
			if (CurrentCustomWorld != null)
			{
				progression.HandleBunburrowSignsDiscovery();
				progression.HandleBackToSurfaceUnlock();
				progression.HandleOphelinePortableComputerUnlock();
				progression.HandleMapUnlock();
				progression.HandleSeenBootAnimation();
				if (CurrentCustomWorld.TeleportAnywhereUnlocked)
				{
					progression.HandleTeleportAnywhereUnlock();
				}
			}
		}

		public LevelObject OnLevelLoad(LevelObject level, LevelIdentity identity)
		{
			return level;
		}

		public string OnLevelTitle(string title, LevelIdentity _, bool useWhite)
		{
			return title;
		}

		public void OnBunnyCapture(BunnyIdentity bunnyIdentity, bool wasHomeCapture)
		{
		}

		public void OnPowerTile(PowerUnlockTile tile, LevelIdentity identity, Action dismiss)
		{
			//IL_000d: 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)
			if (!CustomBunburrowExtension.IsCustomBunburrow(identity.Bunburrow))
			{
				return;
			}
			if (GameManager.GeneralProgression.HasUnlockedTeleportAnywhere)
			{
				dismiss();
				return;
			}
			GameManager.UIController.DisplayDialogue((DialogueObject)(object)BuildTeleportUnlockDialogue(), (BunburrowStyle)null, true, false);
			Action<bool> onDialogueEnd = null;
			onDialogueEnd = delegate
			{
				GameManager.UIController.OnDialogueEnd -= onDialogueEnd;
				dismiss();
			};
			GameManager.UIController.OnDialogueEnd += onDialogueEnd;
		}

		public bool TryResolvePowerTileSprite(PowerUnlockTile tile, LevelIdentity identity, out TileBase sprite)
		{
			//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)
			if (!CustomBunburrowExtension.IsCustomBunburrow(identity.Bunburrow))
			{
				sprite = null;
				return false;
			}
			sprite = (TileBase)(object)(GameManager.GeneralProgression.HasUnlockedTeleportAnywhere ? null : AssetsManager.TeleportAnywherePowerUnlockAnimatedTile);
			return true;
		}

		private static CustomDialogueObject BuildTeleportUnlockDialogue()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			CustomDialogueObject obj = ScriptableObject.CreateInstance<CustomDialogueObject>();
			((Object)obj).name = "BNYS::TeleportAnywhereUnlock";
			obj.DialogueLines = new List<DialogueLine> { (DialogueLine)new CustomDialogueLine
			{
				Headshot = "PaqueretteHappy",
				Content = "Teleport Powers Unlocked!"
			} };
			Traverse.Create((object)obj).Field("unlocksTeleportAnywhere").SetValue((object)true);
			return obj;
		}

		public void OnMainMenu()
		{
			if (CurrentCustomWorld != null)
			{
				BunjectAPI.ClearRegisters();
				Traverse obj = Traverse.Create(typeof(AssetsManager));
				LevelObject value = obj.Field<LevelObject>("surfaceMiddleLevelBase").Value;
				LevelObject value2 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded").Value;
				LevelObject value3 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded2NoHerbe").Value;
				LevelObject value4 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded2Herbe").Value;
				ExtendedSurfaceLevelGenerator.LinkSurface(value, AssetsManager.SurfaceRightLevel);
				ExtendedSurfaceLevelGenerator.LinkSurface(value2, AssetsManager.SurfaceRightLevel);
				ExtendedSurfaceLevelGenerator.LinkSurface(value3, AssetsManager.SurfaceRightLevel);
				ExtendedSurfaceLevelGenerator.LinkSurface(value4, AssetsManager.SurfaceRightLevel);
				CurrentCustomWorld = null;
			}
		}

		public void OnShowCredits()
		{
		}

		public LevelsList LoadEmergencyLevelsList(LevelsList original)
		{
			if ((Object)(object)emergencyList == (Object)null)
			{
				emergencyList = ScriptableObject.CreateInstance<EmergencyLevelsList>();
				emergencyList.Bnys = this;
			}
			return (LevelsList)(object)emergencyList;
		}

		public void LoadBurrowSurfaceLevel(string listName, LevelObject otherwise)
		{
			Burrow burrow = CustomWorlds.SelectMany((CustomWorld cw) => cw.Burrows).FirstOrDefault((Burrow b) => b.Name == listName);
			if (burrow != null)
			{
				CustomWorlds.FirstOrDefault((CustomWorld cw) => cw.Burrows.Contains(burrow)).Burrows.Where((Burrow b) => b.Depth > 0 && b.HasSurfaceEntry).ToList().IndexOf(burrow);
				Logger.LogWarning((object)"Burrow was not surfaceable / not in the list of generated surface levels!");
			}
		}

		public IEnumerable<CustomWorld> LoadCustomWorlds()
		{
			if (Directory.Exists(inlineDirectory))
			{
				foreach (string item in Directory.EnumerateDirectories(inlineDirectory))
				{
					string text = Path.Combine(item, "config.json");
					if (!File.Exists(text))
					{
						continue;
					}
					CustomWorld customWorld = LoadWorldConfig(text);
					if (customWorld == null || !customWorld.Burrows.Any((Burrow b) => b.HasSurfaceEntry && b.Depth > 0) || !customWorld.Enabled)
					{
						continue;
					}
					foreach (Burrow burrow in customWorld.Burrows)
					{
						PatchBurrowDetails(item, burrow);
					}
					yield return customWorld;
				}
			}
			foreach (string item2 in Directory.EnumerateDirectories(pluginsDirectory))
			{
				foreach (string item3 in Directory.EnumerateFiles(item2, "*.bnys"))
				{
					CustomWorld customWorld2 = LoadWorldConfigFromArchive(item3);
					if (customWorld2 != null && customWorld2.Burrows.Any((Burrow b) => b.HasSurfaceEntry && b.Depth > 0) && customWorld2.Enabled)
					{
						yield return customWorld2;
					}
				}
			}
		}

		private CustomWorld LoadWorldConfig(string filename)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			CustomWorld customWorld = null;
			try
			{
				using StreamReader streamReader = new StreamReader(filename);
				customWorld = (CustomWorld)new JsonSerializer().Deserialize((TextReader)streamReader, typeof(LocalCustomWorld));
			}
			catch (Exception ex)
			{
				Logger.LogError((object)"Following file could not be parsed");
				Logger.LogError((object)filename);
				Logger.LogError((object)ex.Message);
				Logger.LogError((object)ex);
			}
			if (string.IsNullOrEmpty(customWorld.Title))
			{
				customWorld.Title = "Untitled";
			}
			if (!string.IsNullOrEmpty(customWorld.ProxyURL))
			{
				try
				{
					return LoadProxyWorld(customWorld);
				}
				catch (Exception ex2)
				{
					Logger.LogError((object)"Error loading Proxy World config.json");
					Logger.LogError((object)filename);
					Logger.LogError((object)ex2.Message);
					Logger.LogError((object)ex2);
				}
			}
			return customWorld;
		}

		private CustomWorld LoadWorldConfigFromArchive(string archivePath)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			ZipArchive zipArchive = ZipFile.OpenRead(archivePath);
			Logger.LogInfo((object)("Opening World Archive: " + archivePath));
			ZipArchiveEntry entry = zipArchive.GetEntry("config.json");
			if (entry == null)
			{
				Logger.LogError((object)("Archive " + Path.GetFileName(archivePath) + " is missing config.json."));
				Logger.LogError((object)"Please double check that config.json is at the root level of the .bnys (zip) file.");
				return null;
			}
			ArchiveCustomWorld archiveCustomWorld = null;
			try
			{
				using Stream stream = entry.Open();
				using StreamReader streamReader = new StreamReader(stream);
				archiveCustomWorld = (ArchiveCustomWorld)new JsonSerializer().Deserialize((TextReader)streamReader, typeof(ArchiveCustomWorld));
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Archive " + Path.GetFileName(archivePath) + " config.json file could not be parsed: "));
				Logger.LogError((object)ex.Message);
				Logger.LogError((object)ex);
			}
			archiveCustomWorld.Archive = zipArchive;
			if (string.IsNullOrEmpty(archiveCustomWorld.Title))
			{
				archiveCustomWorld.Title = "Untitled";
			}
			if (!string.IsNullOrEmpty(archiveCustomWorld.ProxyURL))
			{
				try
				{
					return LoadProxyWorld(archiveCustomWorld);
				}
				catch (Exception ex2)
				{
					Logger.LogError((object)("Error loading Archive Proxy World config.json - " + Path.GetFileName(archivePath)));
					Logger.LogError((object)ex2.Message);
					Logger.LogError((object)ex2);
				}
			}
			return archiveCustomWorld;
		}

		private WebCustomWorld LoadProxyWorld(CustomWorld basis)
		{
			Uri uri = new Uri(basis.ProxyURL);
			WebCustomWorld webCustomWorld = new Uri(uri, "config.json").Load<WebCustomWorld>();
			if (webCustomWorld != null)
			{
				webCustomWorld.ProxyUri = uri;
				webCustomWorld.ProxyURL = basis.ProxyURL;
				webCustomWorld.Enabled = webCustomWorld.Enabled || basis.Enabled;
				webCustomWorld.LiveReloading = false;
				if (string.IsNullOrEmpty(webCustomWorld.Title))
				{
					webCustomWorld.Title = basis.Title;
				}
				if (webCustomWorld.Burrows != null)
				{
					foreach (Burrow burrow in webCustomWorld.Burrows)
					{
						burrow.ProxyUri = new Uri(webCustomWorld.ProxyUri, burrow.Directory + "/");
					}
					if (webCustomWorld.SurfaceEntries == null || webCustomWorld.SurfaceEntries.Count == 0)
					{
						webCustomWorld.SurfaceEntries = basis.SurfaceEntries;
					}
				}
				if (string.IsNullOrEmpty(webCustomWorld.Title))
				{
					webCustomWorld.Title = "Untitled";
				}
			}
			return webCustomWorld;
		}

		private void PatchBurrowDetails(string directory, Burrow burrow)
		{
			if (!Path.IsPathRooted(burrow.Directory))
			{
				burrow.Directory = Path.Combine(directory, burrow.Directory);
				Logger.LogInfo((object)("Burrow Directory: " + burrow.Directory));
			}
		}

		private void GenerateSurfaceLevels(CustomWorld world)
		{
			Traverse obj = Traverse.Create(typeof(AssetsManager));
			LevelObject value = obj.Field<LevelObject>("surfaceMiddleLevelBase").Value;
			LevelObject value2 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded").Value;
			LevelObject value3 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded2NoHerbe").Value;
			LevelObject value4 = obj.Field<LevelObject>("surfaceMiddleLevelExpanded2Herbe").Value;
			LevelObject val = value;
			try
			{
				ExtendedSurfaceLevelGenerator.CreateSurfaceLevels(world, BNYSModBurrows.Where((BNYSModBunburrowBase b) => b.World == world).ToList(), val);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error occurred while generating surface levels for world: " + world.Title));
				Logger.LogError((object)ex.Message);
				Logger.LogError((object)ex);
			}
			val = world.GeneratedSurfaceLevels.LastOrDefault() ?? val;
			LevelObject rightOfShop = world.GeneratedSurfaceLevels.FirstOrDefault() ?? val;
			ExtendedSurfaceLevelGenerator.LinkSurface(value, rightOfShop);
			ExtendedSurfaceLevelGenerator.LinkSurface(value2, rightOfShop);
			ExtendedSurfaceLevelGenerator.LinkSurface(value3, rightOfShop);
			ExtendedSurfaceLevelGenerator.LinkSurface(value4, rightOfShop);
			PatchLevelAsEndcap(val);
		}

		private void PatchLevelAsEndcap(LevelObject endcapLevel)
		{
			Traverse.Create((object)endcapLevel).Field("specificBackground").SetValue((object)SurfaceBurrowsPatch.EndingBackground);
		}

		private void LinkLevelLists(List<BNYSModBunburrowBase> burrows)
		{
			foreach (BNYSModBunburrowBase burrow in burrows)
			{
				if (!string.IsNullOrEmpty(burrow.BurrowModel.Links.Left))
				{
					BNYSModBunburrowBase bNYSModBunburrowBase = burrows.FirstOrDefault((BNYSModBunburrowBase bb) => bb.LocalName == burrow.BurrowModel.Links.Left);
					if (bNYSModBunburrowBase != null)
					{
						burrow.GetLevels().AdjacentBunburrows.SetPart((Direction)0, bNYSModBunburrowBase.GetLevels());
					}
				}
				if (!string.IsNullOrEmpty(burrow.BurrowModel.Links.Up))
				{
					BNYSModBunburrowBase bNYSModBunburrowBase2 = burrows.FirstOrDefault((BNYSModBunburrowBase bb) => bb.LocalName == burrow.BurrowModel.Links.Up);
					if (bNYSModBunburrowBase2 != null)
					{
						burrow.GetLevels().AdjacentBunburrows.SetPart((Direction)2, bNYSModBunburrowBase2.GetLevels());
					}
				}
				if (!string.IsNullOrEmpty(burrow.BurrowModel.Links.Right))
				{
					BNYSModBunburrowBase bNYSModBunburrowBase3 = burrows.FirstOrDefault((BNYSModBunburrowBase bb) => bb.LocalName == burrow.BurrowModel.Links.Right);
					if (bNYSModBunburrowBase3 != null)
					{
						burrow.GetLevels().AdjacentBunburrows.SetPart((Direction)1, bNYSModBunburrowBase3.GetLevels());
					}
				}
				if (!string.IsNullOrEmpty(burrow.BurrowModel.Links.Down))
				{
					BNYSModBunburrowBase bNYSModBunburrowBase4 = burrows.FirstOrDefault((BNYSModBunburrowBase bb) => bb.LocalName == burrow.BurrowModel.Links.Down);
					if (bNYSModBunburrowBase4 != null)
					{
						burrow.GetLevels().AdjacentBunburrows.SetPart((Direction)3, bNYSModBunburrowBase4.GetLevels());
					}
				}
			}
		}

		public static BunburrowStyle ResolveStyle(string style)
		{
			switch (style)
			{
			case "Aquatic":
			case "Sunken":
				return AssetsManager.BunburrowsListOfStyles[(Bunburrow)1];
			case "Hay":
				return AssetsManager.BunburrowsListOfStyles[(Bunburrow)2];
			case "Purple":
			case "Forgotten":
				return AssetsManager.BunburrowsListOfStyles[(Bunburrow)4];
			case "Ghostly":
			case "Spooky":
				return AssetsManager.BunburrowsListOfStyles[(Bunburrow)3];
			case "Void":
				return AssetsManager.BunburrowsListOfStyles.VoidB;
			case "Temple":
				return AssetsManager.BunburrowsListOfStyles.Temple;
			case "Hell":
				return AssetsManager.BunburrowsListOfStyles.Hell;
			case "HellTemple":
				return AssetsManager.BunburrowsListOfStyles.HellTemple;
			default:
				return AssetsManager.BunburrowsListOfStyles[(Bunburrow)0];
			}
		}

		public void DrawMenuOptions()
		{
			foreach (CustomWorld customWorld in CustomWorlds)
			{
				CreateButtonFor(customWorld);
			}
		}

		public void CreateButtonFor(CustomWorld world)
		{
			if (WorldPendingDeletion == world)
			{
				CreateDeleteConfirmationFor(world);
				return;
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(world.Title, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (GUILayout.Button("Load", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				LoadWorld(world);
			}
			if (GUILayout.Button("Delete", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				WorldPendingDeletion = world;
			}
			GUILayout.EndHorizontal();
		}

		private void CreateDeleteConfirmationFor(CustomWorld world)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Delete save?", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (GUILayout.Button("Yes", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				DeleteWorldSave(world);
				WorldPendingDeletion = null;
			}
			if (GUILayout.Button("No", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				WorldPendingDeletion = null;
			}
			GUILayout.EndHorizontal();
		}

		private void LoadWorld(CustomWorld world)
		{
			BunjectAPI.BeginLoadingScreen();
			try
			{
				SurfaceBurrowsPatch.PatchSurfaceBurrows(AssetsManager.SurfaceRightLevel, null);
				foreach (BNYSModBunburrowBase item in BNYSModBurrows.Where((BNYSModBunburrowBase b) => b.World == world))
				{
					BunjectAPI.RegisterBunburrow((IModBunburrow)(object)item);
					if (item == null)
					{
						continue;
					}
					BNYSModBunburrowBase bNYSModBunburrowBase = item;
					foreach (int elevatorDepth in bNYSModBunburrowBase.BurrowModel.ElevatorDepths)
					{
						BunjectAPI.RegisterElevator(item.ID, elevatorDepth);
					}
				}
				GenerateSurfaceLevels(world);
				BunjectAPI.LoadSave("BNYS", world.Title);
				CurrentCustomWorld = world;
			}
			catch (Exception ex)
			{
				Debug.LogException(ex);
				CurrentCustomWorld = null;
				BunjectAPI.CancelLoadingScreen();
			}
		}

		private void DeleteWorldSave(CustomWorld world)
		{
			if (SaveFileModUtility.PluginSaveExists("BNYS", world.Title))
			{
				File.Delete(SaveFileModUtility.GetPluginSaveFilePath("BNYS", world.Title));
			}
		}

		public void GeneratePages(ICustomPageGenerator pageMaker)
		{
			if (CurrentCustomWorld != null)
			{
				pageMaker.CreateComputerPage<CreditsPage>().World = CurrentCustomWorld;
			}
		}
	}
}
namespace Bunject.NewYardSystem.Utility
{
	public class CoordinateJsonConverter : JsonConverter<SurfaceCoordinate>
	{
		public override bool CanWrite => false;

		public override SurfaceCoordinate ReadJson(JsonReader reader, Type objectType, SurfaceCoordinate existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			JsonToken tokenType = reader.TokenType;
			if ((int)tokenType != 1)
			{
				if ((int)tokenType == 2)
				{
					return new SurfaceCoordinate(((JContainer)JArray.Load(reader)).Values<int>().ToArray());
				}
				Console.WriteLine("Uh oh!");
				Console.WriteLine(Enum.GetName(typeof(JsonToken), reader.TokenType));
				return new SurfaceCoordinate();
			}
			JToken val = JToken.Load(reader);
			SurfaceCoordinate surfaceCoordinate = new SurfaceCoordinate();
			JToken obj = val[(object)"Hole"];
			surfaceCoordinate.Hole = ((obj == null) ? null : obj.Values<int>()?.ToArray());
			JToken obj2 = val[(object)"Sign"];
			surfaceCoordinate.Sign = ((obj2 == null) ? null : obj2.Values<int>()?.ToArray());
			surfaceCoordinate.NoSign = val.Value<bool?>((object)"NoSign") == true;
			return surfaceCoordinate;
		}

		public override void WriteJson(JsonWriter writer, SurfaceCoordinate value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	public static class UriExtensions
	{
		public static string Load(this Uri uri)
		{
			Console.WriteLine("Loading: " + uri);
			using WebClient webClient = new WebClient();
			return webClient.DownloadString(uri);
		}

		public static T Load<T>(this Uri uri) where T : class
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Console.WriteLine("Loading: " + uri);
			using WebClient webClient = new WebClient();
			using StreamReader streamReader = new StreamReader(webClient.OpenRead(uri));
			return new JsonSerializer().Deserialize((TextReader)streamReader, typeof(T)) as T;
		}
	}
}
namespace Bunject.NewYardSystem.Resources
{
	internal static class DefaultLevel
	{
		public static string Content = "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,S,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine + "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T" + Environment.NewLine;
	}
	internal class ImportImage
	{
		public static Sprite ImportSprite(string name, string path, Vector2 pivot, float pixelsPerUnit)
		{
			//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)
			Texture2D val = ImportTexture(name, path);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), pivot, pixelsPerUnit);
		}

		public static Texture2D ImportTexture(string name, string path)
		{
			//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_0015: Expected O, but got Unknown
			//IL_0016: 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_0024: Expected O, but got Unknown
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			((Object)val).name = name;
			val.Apply();
			return val;
		}
	}
}
namespace Bunject.NewYardSystem.Model
{
	public class Burrow
	{
		public string Directory { get; set; }

		public string Name { get; set; }

		public string Indicator { get; set; }

		public string Style { get; set; } = "Pink";

		public bool HasSurfaceEntry { get; set; }

		public bool IsVoid { get; set; }

		public int UpperBunnyCount { get; set; }

		public int TempleBunnyCount { get; set; }

		public int HellBunnyCount { get; set; }

		public int Depth { get; set; }

		public BunburrowRequirements Requirements { get; set; } = new BunburrowRequirements();

		public BurrowLinks Links { get; set; } = new BurrowLinks();

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

		[JsonIgnore]
		public Uri ProxyUri { get; set; }

		[JsonIgnore]
		public ModLevelsList Levels { get; set; }
	}
	public class BurrowLinks
	{
		public string Left { get; set; }

		public string Up { get; set; }

		public string Right { get; set; }

		public string Down { get; set; }
	}
	public class CustomBunburrowModel
	{
		public string World { get; set; }

		public string Name { get; set; }

		public string Prefix { get; set; }

		public string Indicator { get; set; }

		[JsonIgnore]
		public int ID { get; set; }
	}
	public abstract class CustomWorld
	{
		public string ProxyURL { get; set; }

		public bool Enabled { get; set; } = true;

		public bool LiveReloading { get; set; }

		public bool TeleportAnywhereUnlocked { get; set; }

		public string Title { get; set; }

		public string Prefix { get; set; }

		public string Author { get; set; }

		public string Description { get; set; }

		public List<Burrow> Burrows { get; set; }

		public List<SurfaceEntry> SurfaceEntries { get; set; }

		[JsonIgnore]
		public Uri ProxyUri { get; set; }

		[JsonIgnore]
		public List<LevelObject> GeneratedSurfaceLevels { get; set; }

		public abstract BNYSModBunburrowBase GenerateBunburrow(BNYSPlugin pluginRef, string bunburrowName);
	}
	public class GlobalConfig
	{
		public List<string> WebBurrows { get; set; }
	}
	public class LevelMetadata
	{
		public string Name { get; set; }

		public bool LiveReloading { get; set; }

		public LevelTools Tools { get; set; } = new LevelTools();

		public string Style { get; set; }

		public bool IsTemple { get; set; }

		public bool IsHell { get; set; }

		public string Content { get; set; }

		public bool IsWebLevel { get; set; }

		public List<LevelHint> Hints { get; set; }

		public int[] Teleport
		{
			get
			{
				if (TeleportX.HasValue && TeleportY.HasValue)
				{
					return new int[2] { TeleportX.Value, TeleportY.Value };
				}
				return null;
			}
			set
			{
				if (value != null && value.Length == 2)
				{
					TeleportX = value[0];
					TeleportY = value[1];
				}
				else
				{
					TeleportX = null;
					TeleportY = null;
				}
			}
		}

		public int? TeleportX { get; set; }

		public int? TeleportY { get; set; }

		public List<LevelDialogue> Dialogues { get; set; } = new List<LevelDialogue>();

		public List<LevelNPCDialogue> OphelineDialogues { get; set; } = new List<LevelNPCDialogue>();

		public List<LevelNPCDialogue> HerbeDialogues { get; set; } = new List<LevelNPCDialogue>();

		public Vector2Int ToTeleportPosition()
		{
			//IL_0044: 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)
			if (TeleportX.HasValue && TeleportY.HasValue)
			{
				return new Vector2Int(TeleportX.Value, TeleportY.Value);
			}
			return new Vector2Int(-1, -1);
		}
	}
	public class LevelTools
	{
		public int Traps { get; set; }

		public int Pickaxes { get; set; }

		public int Carrots { get; set; }

		public int Shovels { get; set; }
	}
	public class LevelHint
	{
		public int[] Position
		{
			get
			{
				return new int[2] { PositionX, PositionY };
			}
			set
			{
				if (value != null && value.Length == 2)
				{
					PositionX = value[0];
					PositionY = value[1];
				}
				else
				{
					PositionX = 0;
					PositionY = 0;
				}
			}
		}

		public int PositionX { get; set; }

		public int PositionY { get; set; }

		public Direction Orientation { get; set; } = (Direction)3;
	}
	public class LevelDialogue
	{
		public List<CustomDialogueLine> Lines { get; set; }

		public bool RequiresBunnyToPassBeforePlaying { get; set; }

		public bool RequiresNoBunnyCaptureThisLevel { get; set; }

		public bool RequiresSpecificEntryDirection { get; set; }

		public Direction SpecificEntryDirection { get; set; } = (Direction)3;

		public bool RequiresBunnyAtSpecificRelativePosition { get; set; }

		public List<int[]> SpecificBunnyRelativePositions { get; set; }

		public bool ShouldForceTurnPaqueretteAtStart { get; set; }

		public Direction ForceTurnPaqueretteDirection { get; set; }

		public CustomDialogueObject ConvertToCustomDialogueObject()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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)
			CustomDialogueObject val = (CustomDialogueObject)ScriptableObject.CreateInstance(typeof(CustomDialogueObject));
			if (Lines != null)
			{
				val.DialogueLines = Lines.ConvertAll((CustomDialogueLine line) => (DialogueLine)(object)line);
			}
			val.RequiresBunnyToPassBeforePlaying = RequiresBunnyToPassBeforePlaying;
			val.RequiresNoBunnyCaptureThisLevel = RequiresNoBunnyCaptureThisLevel;
			val.RequiresSpecificEntryDirection = RequiresSpecificEntryDirection;
			val.SpecificEntryDirection = SpecificEntryDirection;
			val.RequiresBunnyAtSpecificRelativePosition = RequiresBunnyAtSpecificRelativePosition;
			val.SpecificBunnyRelativePositions = new List<Vector2Int>();
			if (SpecificBunnyRelativePositions != null && SpecificBunnyRelativePositions.Count > 0)
			{
				foreach (int[] specificBunnyRelativePosition in SpecificBunnyRelativePositions)
				{
					if (specificBunnyRelativePosition.Length > 1)
					{
						val.SpecificBunnyRelativePositions.Add(new Vector2Int(specificBunnyRelativePosition[0], specificBunnyRelativePosition[1]));
					}
				}
			}
			val.ShouldForceTurnPaqueretteAtStart = ShouldForceTurnPaqueretteAtStart;
			val.ForceTurnPaqueretteDirection = ForceTurnPaqueretteDirection;
			return val;
		}
	}
	public class LevelNPCDialogue
	{
		public string Name { get; set; } = "";

		public List<CustomDialogueLine> Lines { get; set; }

		public int RequiredCaptures { get; set; }

		public int RequiredBabies { get; set; }

		public int RequiredHomeCaptures { get; set; }

		public bool ShouldOnlyPlayOnce { get; set; }

		public NPCDialogueObject ConvertToNPCDialogueObject()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			NPCDialogueObject val = (NPCDialogueObject)ScriptableObject.CreateInstance(typeof(NPCDialogueObject));
			((Object)val).name = "BNYS::" + Name;
			if (Lines != null)
			{
				((CustomDialogueObject)val).DialogueLines = Lines.ConvertAll((CustomDialogueLine line) => (DialogueLine)(object)line);
			}
			val.RequiredCaptures = RequiredCaptures;
			val.RequiredBabies = RequiredBabies;
			val.RequiredHomeCaptures = RequiredHomeCaptures;
			val.ShouldOnlyPlayOnce = ShouldOnlyPlayOnce;
			return val;
		}
	}
	public class SurfaceEntry
	{
		public Dictionary<string, SurfaceCoordinate> Coordinates { get; set; }

		public Dictionary<string, List<int[]>> ReleasePath { get; set; }

		public SurfaceEntryGrid Grid { get; set; }
	}
	[JsonConverter(typeof(CoordinateJsonConverter))]
	public class SurfaceCoordinate
	{
		public int[] Hole { get; set; }

		public int[] Sign { get; set; }

		public bool NoSign { get; set; }

		public SurfaceCoordinate()
		{
		}

		public SurfaceCoordinate(params int[] holeCoordinates)
		{
			Hole = holeCoordinates;
		}
	}
	public class SurfaceEntryGrid
	{
		public string NW { get; set; }

		public string N { get; set; }

		public string NE { get; set; }

		public string W { get; set; }

		public string C { get; set; }

		public string E { get; set; }

		public string SW { get; set; }

		public string S { get; set; }

		public string SE { get; set; }
	}
}
namespace Bunject.NewYardSystem.Internal
{
	internal class CustomBunburrowCache
	{
		private string cachePath;

		public List<CustomBunburrowModel> CustomBurrows;

		public CustomBunburrowCache()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			string rootSaveDataPath = SaveFileModUtility.GetRootSaveDataPath();
			cachePath = Path.Combine(rootSaveDataPath, "mod-burrow-cache.json");
			if (!Directory.Exists(rootSaveDataPath))
			{
				Directory.CreateDirectory(rootSaveDataPath);
			}
			if (File.Exists(cachePath))
			{
				using (StreamReader streamReader = new StreamReader(cachePath))
				{
					CustomBurrows = new JsonSerializer().Deserialize((TextReader)streamReader, typeof(List<CustomBunburrowModel>)) as List<CustomBunburrowModel>;
					return;
				}
			}
			CustomBurrows = new List<CustomBunburrowModel>();
		}

		public CustomBunburrowModel CacheBunburrow(IBNYSModBunburrow bunburrow)
		{
			CustomBunburrowModel customBunburrowModel = new CustomBunburrowModel
			{
				World = bunburrow.WorldName,
				Name = bunburrow.LocalName,
				Prefix = bunburrow.WorldPrefix,
				Indicator = bunburrow.LocalIndicator
			};
			CustomBurrows.Add(customBunburrowModel);
			return customBunburrowModel;
		}

		public void SaveCache()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			using StreamWriter streamWriter = new StreamWriter(cachePath);
			new JsonSerializer().Serialize((TextWriter)streamWriter, (object)CustomBurrows);
		}
	}
}
namespace Bunject.NewYardSystem.Levels
{
	public class BNYSLevelObject : ModLevelObject
	{
		private bool shouldReload = true;

		public bool ShouldReload
		{
			get
			{
				if (!DelayReload)
				{
					return shouldReload;
				}
				if (shouldReload)
				{
					return LastReloadTime.Minute != DateTime.Now.Minute;
				}
				return false;
			}
			set
			{
				shouldReload = value;
			}
		}

		public DateTime LastReloadTime { get; set; }

		public bool DelayReload { get; set; }
	}
	public class BNYSLevelsList : ModLevelsList
	{
		public BNYSPlugin Bnys { get; set; }

		public BNYSModBunburrowBase ModBunburrow { get; set; }

		public bool PermitReloading { get; set; } = true;

		public bool DelayReloading { get; set; }

		public BNYSLevelObject this[int depth]
		{
			get
			{
				return ((ModLevelsList)this)[depth] as BNYSLevelObject;
			}
			set
			{
				((ModLevelsList)this)[depth] = (ModLevelObject)(object)value;
			}
		}

		public override LevelObject LoadLevel(int depth, LoadingContext loadingContext)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			if (depth > 0 && depth <= ((ModLevelsList)this).MaximumDepth)
			{
				BNYSLevelObject bNYSLevelObject = this[depth];
				if ((Object)(object)bNYSLevelObject == (Object)null)
				{
					bNYSLevelObject = ScriptableObject.CreateInstance<BNYSLevelObject>();
					((ModLevelObject)bNYSLevelObject).BunburrowName = ModBunburrow.BurrowModel.Name;
					((ModLevelObject)bNYSLevelObject).Depth = depth;
					ReloadLevel(depth, bNYSLevelObject);
					this[depth] = bNYSLevelObject;
				}
				else if (PermitReloading && bNYSLevelObject.ShouldReload && (int)loadingContext == 1)
				{
					ReloadLevel(depth, bNYSLevelObject);
				}
				return (LevelObject)(object)bNYSLevelObject;
			}
			Bnys.Logger.LogWarning((object)$"{ModBunburrow.Name}: Depth requested, {depth}, exceeds burrow depth of {((ModLevelsList)this).MaximumDepth}");
			return null;
		}

		private void ReloadLevel(int depth, BNYSLevelObject levelObject)
		{
			LevelMetadata levelMetadata = ModBunburrow.LoadLevel(depth);
			levelObject.ShouldReload = PermitReloading && (ModBunburrow.World.LiveReloading || levelMetadata.LiveReloading);
			levelObject.LastReloadTime = DateTime.Now;
			levelObject.DelayReload = DelayReloading;
			PopulateLevel(levelObject, levelMetadata, depth);
		}

		private LevelMetadata CreateDefaultLevelMetadata()
		{
			return new LevelMetadata
			{
				Name = "Failed Level Load",
				LiveReloading = true,
				IsHell = false,
				IsTemple = false,
				Tools = new LevelTools()
			};
		}

		private void PopulateLevel(BNYSLevelObject levelObject, LevelMetadata levelConfig, int depth)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			((Object)levelObject).name = "Level " + ModBunburrow.Name + " - " + levelConfig.Name;
			((ModLevelObject)levelObject).CustomNameKey = levelConfig.Name;
			((ModLevelObject)levelObject).BunburrowStyle = BNYSPlugin.ResolveStyle(levelConfig.Style);
			LevelTools tools = levelConfig.Tools;
			if (tools != null)
			{
				((ModLevelObject)levelObject).NumberOfTraps = tools.Traps;
				((ModLevelObject)levelObject).NumberOfPickaxes = tools.Pickaxes;
				((ModLevelObject)levelObject).NumberOfCarrots = tools.Carrots;
				((ModLevelObject)levelObject).NumberOfShovels = tools.Shovels;
			}
			((ModLevelObject)levelObject).IsTemple = levelConfig.IsTemple;
			((ModLevelObject)levelObject).IsHell = levelConfig.IsHell;
			((ModLevelObject)levelObject).Content = levelConfig.Content;
			List<LevelHint> hints = levelConfig.Hints;
			if (hints != null)
			{
				((ModLevelObject)levelObject).Solutions = ((IEnumerable<LevelHint>)hints).Select((Func<LevelHint, Solution>)delegate(LevelHint hint)
				{
					//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: Expected O, but got Unknown
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_0037: Unknown result type (might be due to invalid IL or missing references)
					//IL_0042: Expected O, but got Unknown
					Solution val = new Solution();
					Traverse obj = Traverse.Create((object)val);
					obj.Field<Vector2Int>("position").Value = new Vector2Int(hint.PositionX, hint.PositionY);
					obj.Field<Direction>("orientation").Value = hint.Orientation;
					return val;
				}).ToList();
			}
			((ModLevelObject)levelObject).TeleportPosition = levelConfig.ToTeleportPosition();
			((ModLevelObject)levelObject).Dialogues = new List<DialogueObject>();
			((ModLevelObject)levelObject).OphelineDialogues = new List<NPCDialogueObject>();
			((ModLevelObject)levelObject).HerbeDialogues = new List<NPCDialogueObject>();
			if (levelConfig.Dialogues != null)
			{
				((ModLevelObject)levelObject).Dialogues = levelConfig.Dialogues.ConvertAll((LevelDialogue dialogue) => (DialogueObject)(object)dialogue.ConvertToCustomDialogueObject());
			}
			if (levelConfig.OphelineDialogues != null)
			{
				((ModLevelObject)levelObject).OphelineDialogues = levelConfig.OphelineDialogues.ConvertAll((LevelNPCDialogue dialogue) => dialogue.ConvertToNPCDialogueObject());
			}
			if (levelConfig.HerbeDialogues != null)
			{
				((ModLevelObject)levelObject).HerbeDialogues = levelConfig.HerbeDialogues.ConvertAll((LevelNPCDialogue dialogue) => dialogue.ConvertToNPCDialogueObject());
			}
		}
	}
	public class BNYSLostBunburrow : IModBunburrow
	{
		public int ID { get; set; }

		public string Name { get; set; }

		public string Indicator { get; set; }

		public bool IsVoid { get; set; }

		public BunburrowStyle Style { get; set; }

		public bool HasEntrance => false;

		public bool HasSign => false;

		public BunburrowRequirements Requirements => new BunburrowRequirements();

		public BNYSLostBunburrow(CustomBunburrowModel cachedBurrow)
		{
			Name = (string.IsNullOrEmpty(cachedBurrow.World) ? string.Empty : (cachedBurrow.World + "::")) + cachedBurrow.Name;
			Indicator = (string.IsNullOrEmpty(cachedBurrow.Prefix) ? string.Empty : (cachedBurrow.Prefix + "-")) + cachedBurrow.Indicator;
		}

		public Vector2Int? OverrideSignCoordinate()
		{
			return null;
		}

		public LevelObject GetLevel(int depth)
		{
			return null;
		}

		public LevelsList GetLevels()
		{
			return null;
		}

		public LevelObject GetSurfaceLevel()
		{
			return null;
		}

		public List<Vector2Int> GetReleasePath()
		{
			return null;
		}
	}
	public abstract class BNYSModBunburrowBase : IBNYSModBunburrow, IModBunburrow
	{
		private BunburrowStyle style;

		private Vector2Int? customSignCoordinate;

		private LevelsList levelsList;

		protected BNYSPlugin Bnys { get; private set; }

		public CustomWorld World { get; private set; }

		public Burrow BurrowModel { get; private set; }

		public string WorldName => World.Title;

		public string LocalName => BurrowModel.Name;

		public string WorldPrefix => World.Prefix;

		public string LocalIndicator => BurrowModel.Indicator;

		public bool IsVoid => BurrowModel.IsVoid;

		public int ID { get; set; }

		public string Name => WorldName + "::" + LocalName;

		public string Indicator => (string.IsNullOrEmpty(WorldPrefix) ? string.Empty : (WorldPrefix + "-")) + LocalIndicator;

		public BunburrowStyle Style
		{
			get
			{
				if ((Object)(object)style == (Object)null)
				{
					style = BNYSPlugin.ResolveStyle(BurrowModel.Style);
				}
				return style;
			}
		}

		public bool HasEntrance => BurrowModel.HasSurfaceEntry;

		public bool HasSign { get; private set; } = true;

		public BunburrowRequirements Requirements => BurrowModel.Requirements;

		public LevelObject SurfaceLevel { get; set; }

		public BNYSModBunburrowBase(BNYSPlugin bnys, CustomWorld worldModel, Burrow burrowModel)
		{
			Bnys = bnys;
			World = worldModel;
			BurrowModel = burrowModel;
			InitializeCustomSignCoordinate();
		}

		public Vector2Int? OverrideSignCoordinate()
		{
			return customSignCoordinate;
		}

		private void InitializeCustomSignCoordinate()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			SurfaceCoordinate surfaceCoordinate = World.SurfaceEntries?.Where((SurfaceEntry se) => se.Coordinates != null)?.SelectMany((SurfaceEntry se) => se.Coordinates)?.Where((KeyValuePair<string, SurfaceCoordinate> kvp) => kvp.Key == LocalName)?.Select((KeyValuePair<string, SurfaceCoordinate> kvp) => kvp.Value)?.FirstOrDefault();
			if (surfaceCoordinate == null)
			{
				return;
			}
			if (!surfaceCoordinate.NoSign)
			{
				if (surfaceCoordinate.Sign != null && surfaceCoordinate.Sign.Length > 1)
				{
					customSignCoordinate = new Vector2Int(surfaceCoordinate.Sign[0], surfaceCoordinate.Sign[1]);
				}
			}
			else
			{
				HasSign = false;
			}
		}

		public abstract LevelMetadata LoadLevel(int depth);

		public LevelsList GetLevels()
		{
			if ((Object)(object)levelsList == (Object)null)
			{
				levelsList = (LevelsList)(object)GenerateLevelsList();
			}
			return levelsList;
		}

		public LevelObject GetSurfaceLevel()
		{
			return SurfaceLevel;
		}

		public List<Vector2Int> GetReleasePath()
		{
			return ((from kvp in World.SurfaceEntries?.Where((SurfaceEntry se) => se.ReleasePath != null).SelectMany((SurfaceEntry se) => se.ReleasePath)
				where kvp.Key == LocalName
				select kvp.Value).FirstOrDefault())?.Select((Func<int[], Vector2Int>)((int[] x) => new Vector2Int(x[0], -x[1]))).ToList();
		}

		protected virtual BNYSLevelsList GenerateLevelsList()
		{
			BNYSLevelsList bNYSLevelsList = ScriptableObject.CreateInstance<BNYSLevelsList>();
			bNYSLevelsList.ModBunburrow = this;
			bNYSLevelsList.Bnys = Bnys;
			((Object)bNYSLevelsList).name = Name;
			((ModLevelsList)bNYSLevelsList).MaximumDepth = BurrowModel.Depth;
			((ModLevelsList)bNYSLevelsList).NumberOfRegularBunnies = BurrowModel.UpperBunnyCount;
			((ModLevelsList)bNYSLevelsList).NumberOfTempleBunnies = BurrowModel.TempleBunnyCount;
			((ModLevelsList)bNYSLevelsList).NumberOfHellBunnies = BurrowModel.HellBunnyCount;
			return bNYSLevelsList;
		}

		protected LevelMetadata CreateDefaultLevelMetadata()
		{
			return new LevelMetadata
			{
				Name = "Failed Level Load",
				LiveReloading = true,
				IsHell = false,
				IsTemple = false,
				Tools = new LevelTools()
			};
		}
	}
	internal class ContentValidator
	{
		private const string RESTRICTED_TILES = "^(F|P[0-9]+|N[0-9]+|X|C|A|Y(?:{.*})?)|T\\{\\.*[PS].*\\}$";

		private static readonly Regex restrictedTileRegex = new Regex("^(F|P[0-9]+|N[0-9]+|X|C|A|Y(?:{.*})?)|T\\{\\.*[PS].*\\}$");

		public static List<LevelValidationError> ValidateLevelContent(string content)
		{
			List<string> tilesFromContent = TileValidator.GetTilesFromContent(content);
			List<LevelValidationError> list = new List<LevelValidationError>();
			if (tilesFromContent.Count > 135)
			{
				list.Add(new LevelValidationError("Level has too many tiles", isWarning: true));
			}
			if (tilesFromContent.Count < 135)
			{
				list.Add(new LevelValidationError("Level has too few tiles"));
			}
			foreach (var (text, num) in tilesFromContent.Select((string t, int i) => (t: t, i: i)))
			{
				if (restrictedTileRegex.IsMatch(text) || !TileValidator.ValidateTile(text))
				{
					list.Add(new TileValidationError("Tile '" + text + "' is not valid", num / 15, num % 15));
				}
			}
			return list;
		}
	}
	public class EmergencyLevelsList : ModLevelsList
	{
		private LevelObject defaultLevel;

		public BNYSPlugin Bnys { get; set; }

		public override LevelObject LoadLevel(int depth, LoadingContext loadingContext)
		{
			if ((Object)(object)defaultLevel == (Object)null)
			{
				defaultLevel = GenerateDefaultLevel();
			}
			Bnys.Logger.LogError((object)"Something went wrong - loading default level!");
			return defaultLevel;
		}

		private LevelObject GenerateDefaultLevel()
		{
			ModLevelObject obj = ScriptableObject.CreateInstance<ModLevelObject>();
			obj.CustomNameKey = "Default Level";
			obj.BunburrowName = "Emergency List";
			obj.Depth = 1;
			obj.Content = DefaultLevel.Content;
			obj.BunburrowStyle = AssetsManager.BunburrowsListOfStyles[(Bunburrow)0];
			return (LevelObject)(object)obj;
		}
	}
	internal class ExtendedSurfaceLevelGenerator
	{
		[Flags]
		private enum SurfaceType
		{
			None = 0,
			Coordinates = 1,
			Grid = 2
		}

		public const string WallRow = "W,W,W,W,W,W,W,W,W,W,W,W,W,W,W";

		public const string TopRow = "W,T,T,T,T,T,T,T,T,T,T,T,T,W,W";

		public const string SpaceRow = "W,T,T,T,T,T,T,T,T,T,T,T,T,W,W";

		public const string EntryRow = "W,T,T,T,{0},T,T,{1},T,T,{2},T,T,W,W";

		public const string OpenRow = "T,T,T,T,T,T,T,T,T,T,T,T,T,T,T";

		public static void CreateSurfaceLevels(CustomWorld world, List<BNYSModBunburrowBase> modBunburrows, LevelObject precedingLevel)
		{
			if (world.GeneratedSurfaceLevels == null)
			{
				Dictionary<string, BNYSModBunburrowBase> burrows = modBunburrows.Where((BNYSModBunburrowBase b) => b.BurrowModel.Depth > 0).ToDictionary((BNYSModBunburrowBase b) => b.LocalName);
				world.GeneratedSurfaceLevels = GenerateLevels(precedingLevel, world, burrows).ToList();
			}
			else
			{
				LinkSurface(precedingLevel, world.GeneratedSurfaceLevels.First());
			}
		}

		public static void LinkSurface(LevelObject shop, LevelObject rightOfShop)
		{
			shop.SideLevels.SetPart((Direction)1, rightOfShop);
		}

		private static IEnumerable<LevelObject> GenerateLevels(LevelObject precedingLevel, CustomWorld world, Dictionary<string, BNYSModBunburrowBase> burrows)
		{
			IEnumerable<SurfaceEntry> surfaceEntries = world.SurfaceEntries;
			foreach (SurfaceEntry item3 in surfaceEntries ?? Enumerable.Empty<SurfaceEntry>())
			{
				string text = null;
				List<BNYSModBunburrowBase> list = null;
				switch (GetSurfaceType(item3))
				{
				case SurfaceType.Coordinates:
					Console.WriteLine(world.Title + ": Creating Coordinate Surface World!");
					(text, list) = GenerateCoordinatesSurfaceContent(item3.Coordinates, burrows);
					break;
				case SurfaceType.Grid:
					Console.WriteLine(world.Title + ": Creating Grid Surface World!");
					(text, list) = GenerateGridSurfaceContent(item3.Grid, burrows);
					break;
				}
				if (list == null || string.IsNullOrEmpty(text) || list.Count <= 0)
				{
					continue;
				}
				Console.WriteLine($"{list.Count} burrows placed in surface world");
				precedingLevel = GenerateLevel(world, text, precedingLevel);
				foreach (BNYSModBunburrowBase item4 in list)
				{
					item4.SurfaceLevel = precedingLevel;
				}
				yield return precedingLevel;
			}
			List<BNYSModBunburrowBase> enterableBurrows = burrows.Values.Where((BNYSModBunburrowBase b) => b.BurrowModel.HasSurfaceEntry).ToList();
			while (enterableBurrows.Any())
			{
				Console.WriteLine(world.Title + ": Creating DEFAULT Surface World");
				(string, List<BNYSModBunburrowBase>) tuple3 = GenerateDefaultSurfaceLevel(enterableBurrows);
				string item = tuple3.Item1;
				List<BNYSModBunburrowBase> item2 = tuple3.Item2;
				precedingLevel = GenerateLevel(world, item, precedingLevel);
				foreach (BNYSModBunburrowBase item5 in item2)
				{
					item5.SurfaceLevel = precedingLevel;
				}
				yield return precedingLevel;
			}
		}

		private static LevelObject GenerateLevel(CustomWorld world, string levelContent, LevelObject previousLevel)
		{
			ModLevelObject val = ScriptableObject.CreateInstance<ModLevelObject>();
			((Object)val).name = "SurfaceRight BNYS";
			val.Content = levelContent;
			val.IsSurface = true;
			val.CustomNameKey = world.Title;
			val.SpecificBackground = SurfaceBurrowsPatch.ExtendedBackground;
			val.BunburrowStyle = previousLevel.BunburrowStyle;
			val.SideLevels.SetPart((Direction)0, previousLevel);
			if ((Object)(object)previousLevel != (Object)null)
			{
				previousLevel.SideLevels.SetPart((Direction)1, (LevelObject)(object)val);
			}
			return (LevelObject)(object)val;
		}

		private static (string, List<BNYSModBunburrowBase>) GenerateCoordinatesSurfaceContent(Dictionary<string, SurfaceCoordinate> coordinates, Dictionary<string, BNYSModBunburrowBase> bunburrows)
		{
			string[][] emptyLevelContent = GetEmptyLevelContent();
			List<BNYSModBunburrowBase> list = new List<BNYSModBunburrowBase>();
			foreach (KeyValuePair<string, SurfaceCoordinate> coordinate in coordinates)
			{
				if (bunburrows.TryGetValue(coordinate.Key, out var value) && coordinate.Value?.Hole != null && coordinate.Value.Hole.Length != 0)
				{
					int num = coordinate.Value.Hole[0];
					int num2 = 3;
					if (coordinate.Value.Hole.Length > 1)
					{
						num2 = coordinate.Value.Hole[1];
					}
					emptyLevelContent[num2][num] = "N" + value.ID;
					list.Add(value);
					bunburrows.Remove(coordinate.Key);
				}
			}
			return (string.Join(",", emptyLevelContent.Select((string[] row) => string.Join(",", row)).ToArray()), list);
		}

		private static (string, List<BNYSModBunburrowBase>) GenerateGridSurfaceContent(SurfaceEntryGrid grid, Dictionary<string, BNYSModBunburrowBase> bunburrows)
		{
			Dictionary<string, SurfaceCoordinate> coordinates = new Dictionary<string, SurfaceCoordinate>();
			Action<string, SurfaceCoordinate> action = delegate(string burrowName, SurfaceCoordinate coordinate)
			{
				if (!string.IsNullOrEmpty(burrowName))
				{
					coordinates.Add(burrowName, coordinate);
				}
			};
			action(grid.NW, new SurfaceCoordinate(4, 1));
			action(grid.N, new SurfaceCoordinate(7, 1));
			action(grid.NE, new SurfaceCoordinate(10, 1));
			action(grid.W, new SurfaceCoordinate(4, 3));
			action(grid.C, new SurfaceCoordinate(7, 3));
			action(grid.E, new SurfaceCoordinate(10, 3));
			action(grid.SW, new SurfaceCoordinate(4, 5));
			action(grid.S, new SurfaceCoordinate(7, 5));
			action(grid.SE, new SurfaceCoordinate(10, 5));
			return GenerateCoordinatesSurfaceContent(coordinates, bunburrows);
		}

		private static (string, List<BNYSModBunburrowBase>) GenerateDefaultSurfaceLevel(List<BNYSModBunburrowBase> bunburrows)
		{
			List<BNYSModBunburrowBase> list = new List<BNYSModBunburrowBase>();
			BNYSModBunburrowBase bNYSModBunburrowBase = bunburrows.FirstOrDefault();
			if (bNYSModBunburrowBase != null)
			{
				bunburrows.Remove(bNYSModBunburrowBase);
				list.Add(bNYSModBunburrowBase);
			}
			BNYSModBunburrowBase bNYSModBunburrowBase2 = bunburrows.FirstOrDefault();
			if (bNYSModBunburrowBase2 != null)
			{
				bunburrows.Remove(bNYSModBunburrowBase2);
				list.Add(bNYSModBunburrowBase2);
			}
			BNYSModBunburrowBase bNYSModBunburrowBase3 = bunburrows.FirstOrDefault();
			if (bNYSModBunburrowBase3 != null)
			{
				bunburrows.Remove(bNYSModBunburrowBase3);
				list.Add(bNYSModBunburrowBase3);
			}
			return (GetBasicLevelContent(bNYSModBunburrowBase, bNYSModBunburrowBase2, bNYSModBunburrowBase3), list);
		}

		private static string[][] GetEmptyLevelContent()
		{
			return new string[9]
			{
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W",
				"W,T,T,T,T,T,T,T,T,T,T,T,T,W,W",
				"W,T,T,T,T,T,T,T,T,T,T,T,T,W,W",
				string.Format("W,T,T,T,{0},T,T,{1},T,T,{2},T,T,W,W", "T", "T", "T"),
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W",
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W"
			}.Select((string r) => r.Split(',')).ToArray();
		}

		private static string GetBasicLevelContent(BNYSModBunburrowBase first, BNYSModBunburrowBase second, BNYSModBunburrowBase third)
		{
			string[] value = new string[9]
			{
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W",
				"W,T,T,T,T,T,T,T,T,T,T,T,T,W,W",
				"W,T,T,T,T,T,T,T,T,T,T,T,T,W,W",
				$"W,T,T,T,{GetLevelEntryCode(first)},T,T,{GetLevelEntryCode(second)},T,T,{GetLevelEntryCode(third)},T,T,W,W",
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"T,T,T,T,T,T,T,T,T,T,T,T,T,T,T",
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W",
				"W,W,W,W,W,W,W,W,W,W,W,W,W,W,W"
			};
			return string.Join(Environment.NewLine, value);
		}

		private static string GetLevelEntryCode(BNYSModBunburrowBase burrow)
		{
			if (burrow != null)
			{
				return "N" + burrow.ID;
			}
			return "T";
		}

		private static SurfaceType GetSurfaceType(SurfaceEntry surfaceEntry)
		{
			SurfaceType surfaceType = SurfaceType.None;
			int num = 0;
			if (surfaceEntry.Coordinates != null)
			{
				surfaceType |= SurfaceType.Coordinates;
				num++;
			}
			if (surfaceEntry.Grid != null)
			{
				surfaceType |= SurfaceType.Grid;
				num++;
			}
			if (num > 1)
			{
				List<string> list = new List<string>();
				foreach (SurfaceType item in Enum.GetValues(typeof(SurfaceType)).Cast<SurfaceType>())
				{
					if (surfaceType.HasFlag(item) && item != SurfaceType.None)
					{
						list.Add(Enum.GetName(typeof(SurfaceType), item));
					}
				}
				throw new Exception("SurfaceEntry cannot have both a Coordinates and Grid - please select only one.");
			}
			return surfaceType;
		}

		private static int CountFlags<T>(T instance) where T : Enum
		{
			int num = 0;
			foreach (T item in Enum.GetValues(typeof(T)).Cast<T>())
			{
				if (instance.HasFlag(item))
				{
					num++;
				}
			}
			return num;
		}
	}
	public interface IBNYSModBunburrow
	{
		string WorldName { get; }

		string LocalName { get; }

		string WorldPrefix { get; }

		string LocalIndicator { get; }
	}
	public class LevelValidationError
	{
		public string Message { get; private set; }

		public bool IsWarning { get; private set; }

		public LevelValidationError(string message, bool isWarning)
		{
			Message = message;
			IsWarning = isWarning;
		}

		public LevelValidationError(string message)
			: this(message, isWarning: false)
		{
		}

		public override string ToString()
		{
			return Message;
		}
	}
	internal class SurfaceBurrowsPatch
	{
		private const string PatchedTexture = "PatchedTexture";

		private const string PatchedTexturePath = "ExtendedRegion.png";

		public static Sprite EndingBackground;

		public static Sprite ExtendedBackground;

		public static void PatchSurfaceBurrows(LevelObject originalBurrows, LevelObject newRightExit)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)EndingBackground == (Object)null)
			{
				EndingBackground = originalBurrows.SpecificBackground;
			}
			if ((Object)(object)ExtendedBackground == (Object)null)
			{
				string path = Path.Combine(BNYSPlugin.rootDirectory, "ExtendedRegion.png");
				if (!File.Exists(path))
				{
					path = Path.Combine(BNYSPlugin.inlineDirectory, "ExtendedRegion.png");
				}
				ExtendedBackground = ImportImage.ImportSprite("PatchedTexture", path, new Vector2(0f, 1f), 16f);
			}
		}
	}
	public class TileValidationError : LevelValidationError
	{
		public TileValidationError(string message, int row, int column)
			: base($"Tile on Row {row}, Column {column}: {message}")
		{
		}
	}
}
namespace Bunject.NewYardSystem.Levels.Web
{
	public class BNYSWebModBunburrow : BNYSModBunburrowBase
	{
		public new WebCustomWorld World { get; private set; }

		public BNYSWebModBunburrow(BNYSPlugin bnys, WebCustomWorld worldModel, Burrow burrowModel)
			: base(bnys, worldModel, burrowModel)
		{
			World = worldModel;
		}

		protected override BNYSLevelsList GenerateLevelsList()
		{
			BNYSLevelsList bNYSLevelsList = base.GenerateLevelsList();
			bNYSLevelsList.PermitReloading = true;
			bNYSLevelsList.DelayReloading = true;
			return bNYSLevelsList;
		}

		public override LevelMetadata LoadLevel(int depth)
		{
			string text = null;
			LevelMetadata levelMetadata = null;
			Uri uri = new Uri(base.BurrowModel.ProxyUri, $"{depth}.json");
			try
			{
				levelMetadata = uri.Load<LevelMetadata>();
				levelMetadata.IsWebLevel = true;
			}
			catch (Exception ex)
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: File doesn't exist, Level json failed to load from web.  Ensure {depth}.json exists and conforms to JSON standards.");
				base.Bnys.Logger.LogError((object)"Error loading files related to level:");
				base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
				base.Bnys.Logger.LogError((object)"Expected web endpoint:");
				base.Bnys.Logger.LogError((object)uri.ToString());
				base.Bnys.Logger.LogError((object)ex.Message);
				base.Bnys.Logger.LogError((object)ex);
				levelMetadata = CreateDefaultLevelMetadata();
			}
			if (string.IsNullOrEmpty(levelMetadata.Content))
			{
				Uri uri2 = new Uri(base.BurrowModel.ProxyUri, $"{depth}.level");
				try
				{
					text = uri2.Load();
					levelMetadata.IsWebLevel = true;
				}
				catch (Exception ex2)
				{
					base.Bnys.Logger.LogError((object)"Error loading files related to level:");
					base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
					base.Bnys.Logger.LogError((object)"Expected web path:");
					base.Bnys.Logger.LogError((object)uri2);
					base.Bnys.Logger.LogError((object)ex2.Message);
					base.Bnys.Logger.LogError((object)ex2);
				}
			}
			if (string.IsNullOrEmpty(text))
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level content failed to load.  Ensure {depth}.level exists and is appropriately formatted.");
				text = DefaultLevel.Content;
			}
			else
			{
				List<LevelValidationError> list = ContentValidator.ValidateLevelContent(text);
				if (list.Count > 0)
				{
					base.Bnys.Logger.LogWarning((object)$"{base.Name} - {depth}: Invalid level content found: ");
					foreach (LevelValidationError item in list)
					{
						if (item.IsWarning)
						{
							base.Bnys.Logger.LogWarning((object)item);
						}
						else
						{
							base.Bnys.Logger.LogError((object)item);
						}
					}
				}
				if (list.Any((LevelValidationError ve) => !ve.IsWarning))
				{
					text = DefaultLevel.Content;
				}
			}
			levelMetadata.Style = levelMetadata.Style ?? base.BurrowModel.Style;
			levelMetadata.Content = text;
			return levelMetadata;
		}
	}
	public class WebCustomWorld : CustomWorld
	{
		public override BNYSModBunburrowBase GenerateBunburrow(BNYSPlugin pluginRef, string bunburrowName)
		{
			return new BNYSWebModBunburrow(pluginRef, this, base.Burrows.First((Burrow b) => b.Name == bunburrowName));
		}
	}
}
namespace Bunject.NewYardSystem.Levels.Local
{
	public class BNYSLocalModBunburrow : BNYSModBunburrowBase
	{
		public new LocalCustomWorld World { get; private set; }

		public BNYSLocalModBunburrow(BNYSPlugin bnys, LocalCustomWorld worldModel, Burrow burrowModel)
			: base(bnys, worldModel, burrowModel)
		{
			World = worldModel;
		}

		public override LevelMetadata LoadLevel(int depth)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(base.BurrowModel.Directory, $"{depth}.level");
			string path2 = Path.Combine(base.BurrowModel.Directory, $"{depth}.json");
			string text = null;
			LevelMetadata levelMetadata = null;
			if (File.Exists(path2))
			{
				try
				{
					using StreamReader streamReader = new StreamReader(path2);
					levelMetadata = (LevelMetadata)new JsonSerializer().Deserialize((TextReader)streamReader, typeof(LevelMetadata));
				}
				catch (Exception ex)
				{
					base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level json failed to load.  Ensure {depth}.json exists and conforms to JSON standards.");
					base.Bnys.Logger.LogError((object)"Error loading files related to level:");
					base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
					base.Bnys.Logger.LogError((object)ex.Message);
					base.Bnys.Logger.LogError((object)ex);
					levelMetadata = CreateDefaultLevelMetadata();
				}
			}
			else
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level json failed to load.  Ensure {depth}.json exists and conforms to JSON standards.");
				base.Bnys.Logger.LogError((object)"Error loading files related to level:");
				base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
				levelMetadata = CreateDefaultLevelMetadata();
			}
			if (string.IsNullOrEmpty(levelMetadata.Content) && File.Exists(path))
			{
				try
				{
					text = File.ReadAllText(path);
				}
				catch (Exception ex2)
				{
					base.Bnys.Logger.LogError((object)"Error loading files related to level:");
					base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
					base.Bnys.Logger.LogError((object)ex2.Message);
					base.Bnys.Logger.LogError((object)ex2);
				}
			}
			if (string.IsNullOrEmpty(text))
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level content failed to load.  Ensure {depth}.level exists and is appropriately formatted.");
				text = DefaultLevel.Content;
			}
			else
			{
				List<LevelValidationError> list = ContentValidator.ValidateLevelContent(text);
				if (list.Count > 0)
				{
					base.Bnys.Logger.LogWarning((object)$"{base.Name} - {depth}: Invalid level content found: ");
					foreach (LevelValidationError item in list)
					{
						if (item.IsWarning)
						{
							base.Bnys.Logger.LogWarning((object)item);
						}
						else
						{
							base.Bnys.Logger.LogError((object)item);
						}
					}
				}
				if (list.Any((LevelValidationError ve) => !ve.IsWarning))
				{
					text = DefaultLevel.Content;
				}
			}
			levelMetadata.Style = levelMetadata.Style ?? base.BurrowModel.Style;
			levelMetadata.Content = text;
			return levelMetadata;
		}
	}
	public class LocalCustomWorld : CustomWorld
	{
		public override BNYSModBunburrowBase GenerateBunburrow(BNYSPlugin pluginRef, string bunburrowName)
		{
			return new BNYSLocalModBunburrow(pluginRef, this, base.Burrows.First((Burrow b) => b.Name == bunburrowName));
		}
	}
}
namespace Bunject.NewYardSystem.Levels.Archive
{
	public class ArchiveCustomWorld : CustomWorld
	{
		[JsonIgnore]
		public ZipArchive Archive { get; set; }

		public override BNYSModBunburrowBase GenerateBunburrow(BNYSPlugin pluginRef, string bunburrowName)
		{
			return new BNYSArchiveModBunburrow(pluginRef, this, base.Burrows.First((Burrow b) => b.Name == bunburrowName));
		}
	}
	public class BNYSArchiveModBunburrow : BNYSModBunburrowBase
	{
		public new ArchiveCustomWorld World { get; private set; }

		public BNYSArchiveModBunburrow(BNYSPlugin bnys, ArchiveCustomWorld worldModel, Burrow burrowModel)
			: base(bnys, worldModel, burrowModel)
		{
			World = worldModel;
		}

		protected override BNYSLevelsList GenerateLevelsList()
		{
			BNYSLevelsList bNYSLevelsList = base.GenerateLevelsList();
			bNYSLevelsList.PermitReloading = false;
			return bNYSLevelsList;
		}

		public override LevelMetadata LoadLevel(int depth)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			string entryName = base.BurrowModel.Directory + "/" + $"{depth}.level";
			string text = base.BurrowModel.Directory + "/" + $"{depth}.json";
			string text2 = null;
			LevelMetadata levelMetadata = null;
			ZipArchiveEntry entry = World.Archive.GetEntry(text);
			if (entry != null)
			{
				try
				{
					using Stream stream = entry.Open();
					using StreamReader streamReader = new StreamReader(stream);
					levelMetadata = (LevelMetadata)new JsonSerializer().Deserialize((TextReader)streamReader, typeof(LevelMetadata));
				}
				catch (Exception ex)
				{
					base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level json failed to load.  Ensure {depth}.json exists and conforms to JSON standards.");
					base.Bnys.Logger.LogError((object)"Error reading zip file entry related to level:");
					base.Bnys.Logger.LogError((object)text);
					base.Bnys.Logger.LogError((object)ex.Message);
					base.Bnys.Logger.LogError((object)ex);
					levelMetadata = CreateDefaultLevelMetadata();
				}
			}
			else
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level json failed to load.  Ensure {depth}.json exists and conforms to JSON standards.");
				base.Bnys.Logger.LogError((object)"Could not find zip file entry:");
				base.Bnys.Logger.LogError((object)text);
				levelMetadata = CreateDefaultLevelMetadata();
			}
			if (string.IsNullOrEmpty(levelMetadata.Content))
			{
				ZipArchiveEntry entry2 = World.Archive.GetEntry(entryName);
				if (entry2 != null)
				{
					try
					{
						using Stream stream2 = entry2.Open();
						using StreamReader streamReader2 = new StreamReader(stream2);
						text2 = streamReader2.ReadToEnd();
					}
					catch (Exception ex2)
					{
						base.Bnys.Logger.LogError((object)"Error reading archive entry related to level content:");
						base.Bnys.Logger.LogError((object)Path.Combine(base.BurrowModel.Directory, depth.ToString()));
						base.Bnys.Logger.LogError((object)ex2.Message);
						base.Bnys.Logger.LogError((object)ex2);
					}
				}
			}
			if (string.IsNullOrEmpty(text2))
			{
				base.Bnys.Logger.LogError((object)$"{base.Name} - {depth}: Level content failed to load.  Ensure {depth}.level exists and is appropriately formatted.");
				text2 = DefaultLevel.Content;
			}
			else
			{
				List<LevelValidationError> list = ContentValidator.ValidateLevelContent(text2);
				if (list.Count > 0)
				{
					base.Bnys.Logger.LogWarning((object)$"{base.Name} - {depth}: Invalid level content found: ");
					foreach (LevelValidationError item in list)
					{
						if (item.IsWarning)
						{
							base.Bnys.Logger.LogWarning((object)item);
						}
						else
						{
							base.Bnys.Logger.LogError((object)item);
						}
					}
				}
				if (list.Any((LevelValidationError ve) => !ve.IsWarning))
				{
					text2 = DefaultLevel.Content;
				}
			}
			levelMetadata.Style = levelMetadata.Style ?? base.BurrowModel.Style;
			levelMetadata.Content = text2;
			return levelMetadata;
		}
	}
}
namespace Bunject.NewYardSystem.Exceptions
{
	public class InvalidBurrowLinkException : Exception
	{
		public InvalidBurrowLinkException(string worldName, string burrowName, string linkDirection, string linkName)
			: base(worldName + " - " + burrowName + " has an invalid " + linkDirection + " burrow link: '" + linkName + "'")
		{
		}
	}
}
namespace Bunject.NewYardSystem.Computer
{
	internal class CreditsPage : BasicCustomComputerPageController
	{
		private string content;

		public CustomWorld World { get; set; }

		public override string ButtonName => "BNYSCredits";

		public override string ButtonText => "Level Credits";

		protected override string HeaderText => StartGold() + World?.Title + EndColor();

		protected override string ContentText => GetContentText();

		public override bool ShouldShow()
		{
			return World != null;
		}

		private string GetContentText()
		{
			if (World != null && content == null)
			{
				content = "By  " + StartGold() + GetAuthor() + EndColor() + Environment.NewLine + Environment.NewLine + GetDescription(World);
			}
			return content;
		}

		private string GetAuthor()
		{
			if (string.IsNullOrEmpty(World?.Author))
			{
				return "Bunknown Author";
			}
			return World?.Author;
		}

		private static string StartGold()
		{
			return "<color=#D3AF37>";
		}

		private static string EndColor()
		{
			return "</color>";
		}

		private static string GetDescription(CustomWorld world)
		{
			if (!string.IsNullOrWhiteSpace(world.Description))
			{
				return world.Description;
			}
			return "A custom world lovingly crafted for your bunjoyment.";
		}
	}
}