Decompiled source of Arena Rush v1.0.0

plugins/ArenaTravel.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml.Linq;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SideLoader.Helpers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Rox.ArenaTravel
{
	internal sealed class Destination
	{
		public readonly string Region;

		public readonly string Name;

		public readonly string Boss;

		public readonly string Scene;

		public readonly int Spawn;

		public Destination(string region, string name, string boss, string scene, int spawn)
		{
			Region = region;
			Name = name;
			Boss = boss;
			Scene = scene;
			Spawn = spawn;
		}
	}
	internal static class Destinations
	{
		public static readonly string[] Regions = new string[6] { "Chersonese", "Enmerkar Forest", "Hallowed Marsh", "Abrassar", "Antique Plateau", "Caldera" };

		public static readonly Destination[] All = new Destination[19]
		{
			new Destination(Regions[0], "Blister Burrow", "Troglodyte Queen", "ChersoneseDungeonsBosses", 0),
			new Destination(Regions[0], "Conflux Mountain", "Brand Squire", "ChersoneseDungeonsBosses", 2),
			new Destination(Regions[0], "Voltaic Hatchery", "Elite Mantis Shrimp", "ChersoneseDungeonsBosses", 1),
			new Destination(Regions[1], "Berg", "Light Mender & Plague Doctor", "EmercarDungeonsBosses", 0),
			new Destination(Regions[1], "Burning Tree", "Elite Burning Man", "EmercarDungeonsBosses", 1),
			new Destination(Regions[1], "Cabal of Wind Temple", "Immaculate Dreamer", "EmercarDungeonsBosses", 2),
			new Destination(Regions[2], "Giants' Village - South", "Ash Giant Highmonk", "HallowedDungeonsBosses", 0),
			new Destination(Regions[2], "Giants' Village - North", "Elite Ash Giants", "HallowedDungeonsBosses", 1),
			new Destination(Regions[2], "Ziggurat Passage", "Elite Alpha Tuanosaur", "HallowedDungeonsBosses", 2),
			new Destination(Regions[3], "Electric Lab", "Elite Crescent Sharks", "AbrassarDungeonsBosses", 2),
			new Destination(Regions[3], "Levant", "Calixa", "AbrassarDungeonsBosses", 0),
			new Destination(Regions[3], "Parched Shipwrecks", "Elite Beast Golem", "AbrassarDungeonsBosses", 1),
			new Destination(Regions[4], "Immaculate's Camp", "Immaculate's Bird", "AntiqueFieldDungeonsBosses", 0),
			new Destination(Regions[4], "Isolated Windmill", "Elite Sublime Shell", "AntiqueFieldDungeonsBosses", 1),
			new Destination(Regions[4], "Mana Lake", "Elite Boozu", "AntiqueFieldDungeonsBosses", 2),
			new Destination(Regions[5], "Tower of Regrets", "Grandmother", "CalderaDungeonsBosses", 1),
			new Destination(Regions[5], "Vault of Stone", "Elite Crimson Avatar", "CalderaDungeonsBosses", 2),
			new Destination(Regions[5], "River of Red", "Elite Torcrab", "CalderaDungeonsBosses", 4),
			new Destination(Regions[5], "New Sirocco", "Elite Gargoyles", "CalderaDungeonsBosses", 3)
		};
	}
	[BepInPlugin("rox.outward.arenatravel", "Arena Rush", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(LocalCharacterControl), "DetectMovementInputs")]
		private static class MenuMovementPatch
		{
			private static bool Prefix(Character ___m_character, ref Vector2 ___m_moveInput, ref Vector3 ___m_modifMoveInput, ref Vector3 ___m_inputMoveVector, ref bool ___m_autoRun)
			{
				//IL_000b: 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_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: 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_002b: 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)
				if (!MenuCaptures(___m_character))
				{
					return true;
				}
				___m_moveInput = Vector2.zero;
				___m_modifMoveInput = Vector2.op_Implicit(Vector2.zero);
				___m_inputMoveVector = Vector2.op_Implicit(Vector2.zero);
				___m_autoRun = false;
				if (___m_character.Sprinting)
				{
					___m_character.SprintInput(false);
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class MenuActionsPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				string[] array = new string[5] { "UpdateWeapon", "UpdateQuickSlots", "UpdateInteraction", "UpdateTargeting", "UpdateMenuInputs" };
				foreach (string text in array)
				{
					yield return AccessTools.Method(typeof(LocalCharacterControl), text, (Type[])null, (Type[])null);
				}
			}

			private static bool Prefix(Character ___m_character)
			{
				return !MenuCaptures(___m_character);
			}
		}

		[HarmonyPatch]
		private static class MenuCameraPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				yield return AccessTools.Method(typeof(ControlsInput), "RotateCameraHorizontal", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(ControlsInput), "RotateCameraVertical", (Type[])null, (Type[])null);
			}

			private static void Postfix(int _playerID, ref float __result)
			{
				Character val = SoloCharacter();
				if (Object.op_Implicit((Object)(object)val) && Instance.CapturesInput && Object.op_Implicit((Object)(object)val.OwnerPlayerSys) && val.OwnerPlayerSys.PlayerID == _playerID)
				{
					__result = 0f;
				}
			}
		}

		private sealed class Origin
		{
			public string Scene;

			public int Spawn;

			public Vector3 Position;

			public Quaternion Rotation;
		}

		private Canvas canvas;

		private RectTransform panel;

		private Font font;

		private Sprite buttonSprite;

		private Sprite highlightSprite;

		private Text heading;

		private Text status;

		private Button enter;

		private Button returnButton;

		private readonly Button[] regions = (Button[])(object)new Button[6];

		private readonly Button[] rows = (Button[])(object)new Button[4];

		private readonly Text[] bosses = (Text[])(object)new Text[4];

		private static readonly Color Gold = new Color(0.84f, 0.67f, 0.36f);

		private static readonly Color Ink = new Color(0.9f, 0.87f, 0.77f);

		private static readonly Color Muted = new Color(0.66f, 0.65f, 0.59f);

		internal static Plugin Instance;

		private bool opened;

		private bool cursorOwned;

		private bool busy;

		private int releaseFrame = -1;

		private int region;

		private string owner = "";

		private string message = "Choose a region, then an arena.";

		private ConfigEntry<KeyboardShortcut> menuKey;

		private Harmony harmony;

		private Destination selected;

		private Origin origin;

		internal bool CapturesInput
		{
			get
			{
				if (!opened)
				{
					return Time.frameCount <= releaseFrame;
				}
				return true;
			}
		}

		private string OriginPath => Path.Combine(Paths.ConfigPath, "UnknownArenaTravel", Convert.ToBase64String(Encoding.UTF8.GetBytes(owner)).Replace('/', '_').Replace('+', '-') + ".xml");

		private static bool MenuCaptures(Character character)
		{
			if (Object.op_Implicit((Object)(object)Instance) && Instance.CapturesInput)
			{
				return IsPlayer(character);
			}
			return false;
		}

		private RectTransform Rect(string name, Transform parent, float x, float y, float w, float h)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(x, 0f - y);
			component.sizeDelta = new Vector2(w, h);
			return component;
		}

		private Text Label(Transform p, string text, float x, float y, float w, float h, int size = 16, Color? color = null)
		{
			//IL_004e: 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)
			Text obj = ((Component)Rect("Label", p, x, y, w, h)).gameObject.AddComponent<Text>();
			obj.font = font;
			obj.text = text;
			obj.fontSize = size;
			((Graphic)obj).color = (Color)(((??)color) ?? Ink);
			obj.alignment = (TextAnchor)4;
			((Graphic)obj).raycastTarget = false;
			obj.supportRichText = false;
			return obj;
		}

		private Image Art(Transform p, Sprite s, float x, float y, float w, float h)
		{
			Image obj = ((Component)Rect("Artwork", p, x, y, w, h)).gameObject.AddComponent<Image>();
			obj.sprite = s;
			obj.type = (Type)1;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private Button Button(Transform p, string text, float x, float y, float w, float h, Action action)
		{
			//IL_0047: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			Image val = Art(p, buttonSprite, x, y, w, h);
			((Graphic)val).raycastTarget = true;
			Button val2 = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)val2).targetGraphic = (Graphic)(object)val;
			((Selectable)val2).transition = (Transition)0;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)val2).navigation = navigation;
			Label(((Component)val2).transform, text, 18f, 0f, w - 36f, h);
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				action();
			});
			return val2;
		}

		private void BuildUI(Character c)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			PauseMenu pauseMenu = c.CharacterUI.PauseMenu;
			Button val = (Button)AccessTools.Field(typeof(PauseMenu), "m_btnTogglePause").GetValue(pauseMenu);
			font = ((Component)val).GetComponentInChildren<Text>(true).font;
			buttonSprite = ((Image)((Selectable)val).targetGraphic).sprite;
			SpriteState spriteState = ((Selectable)val).spriteState;
			highlightSprite = ((SpriteState)(ref spriteState)).highlightedSprite ?? buttonSprite;
			Sprite sprite = ((Component)((Component)pauseMenu).transform.Find("Buttons/BG")).GetComponent<Image>().sprite;
			GameObject val2 = new GameObject("Arena Rush", new Type[4]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			Object.DontDestroyOnLoad((Object)(object)val2);
			canvas = val2.GetComponent<Canvas>();
			canvas.renderMode = (RenderMode)0;
			canvas.sortingOrder = 150;
			CanvasScaler component = val2.GetComponent<CanvasScaler>();
			component.uiScaleMode = (ScaleMode)1;
			component.referenceResolution = new Vector2(1600f, 900f);
			component.matchWidthOrHeight = 0.5f;
			panel = Rect("Arena Travel", val2.transform, 0f, 0f, 744f, 602f);
			RectTransform obj = panel;
			RectTransform obj2 = panel;
			RectTransform obj3 = panel;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			obj3.pivot = val3;
			Vector2 anchorMin = (obj2.anchorMax = val3);
			obj.anchorMin = anchorMin;
			panel.anchoredPosition = Vector2.zero;
			RectTransform p = Rect("Regions", (Transform)(object)panel, 0f, 0f, 360f, 602f);
			RectTransform p2 = Rect("Arenas", (Transform)(object)panel, 384f, 0f, 360f, 602f);
			Art((Transform)(object)p, sprite, 0f, 0f, 360f, 602f);
			Art((Transform)(object)p2, sprite, 0f, 0f, 360f, 602f);
			Label((Transform)(object)p, "ARENA RUSH", 35f, 45f, 290f, 36f, 23, Gold);
			Label((Transform)(object)p, "Choose a region", 35f, 88f, 290f, 25f, 15, Muted);
			for (int i = 0; i < 6; i++)
			{
				int slot = i;
				regions[i] = Button((Transform)(object)p, Destinations.Regions[i], 28f, 135 + i * 47, 304f, 38f, delegate
				{
					region = slot;
					selected = null;
					message = "Choose an arena.";
					Refresh();
				});
			}
			returnButton = Button((Transform)(object)p, "Return to Starting Location", 28f, 445f, 304f, 38f, delegate
			{
				Travel(back: true);
			});
			Label((Transform)(object)p, "Return location saved per character", 35f, 487f, 290f, 25f, 13, Muted);
			Button((Transform)(object)p, "Close", 115f, 535f, 130f, 34f, delegate
			{
				SetOpen(value: false);
			});
			heading = Label((Transform)(object)p2, "", 35f, 45f, 290f, 36f, 23, Gold);
			Label((Transform)(object)p2, "Select your destination", 35f, 88f, 290f, 25f, 15, Muted);
			for (int num = 0; num < 4; num++)
			{
				int slot2 = num;
				rows[num] = Button((Transform)(object)p2, "", 28f, 135 + num * 70, 304f, 38f, delegate
				{
					Destination[] array = Destinations.All.Where((Destination d) => d.Region == Destinations.Regions[region]).ToArray();
					if (slot2 < array.Length)
					{
						selected = array[slot2];
						message = "Ready to enter " + selected.Name + ".";
						Refresh();
					}
				});
				bosses[num] = Label((Transform)(object)p2, "", 28f, 173 + num * 70, 304f, 25f, 13, Muted);
			}
			status = Label((Transform)(object)p2, "", 35f, 427f, 290f, 56f, 15);
			enter = Button((Transform)(object)p2, "Enter Arena", 78f, 495f, 204f, 38f, delegate
			{
				Travel(back: false);
			});
			Label((Transform)(object)p2, "World remains live", 35f, 544f, 290f, 24f, 13, Muted);
			((Component)panel).gameObject.SetActive(false);
		}

		private void Refresh()
		{
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)canvas))
			{
				return;
			}
			heading.text = Destinations.Regions[region];
			Destination[] array = Destinations.All.Where((Destination d) => d.Region == Destinations.Regions[region]).ToArray();
			for (int num = 0; num < regions.Length; num++)
			{
				((Component)regions[num]).GetComponent<Image>().sprite = ((num == region) ? highlightSprite : buttonSprite);
			}
			for (int num2 = 0; num2 < rows.Length; num2++)
			{
				bool flag = num2 < array.Length;
				((Component)rows[num2]).gameObject.SetActive(flag);
				((Component)bosses[num2]).gameObject.SetActive(flag);
				if (flag)
				{
					((Component)rows[num2]).GetComponentInChildren<Text>().text = array[num2].Name;
					bosses[num2].text = array[num2].Boss;
					((Component)rows[num2]).GetComponent<Image>().sprite = ((selected == array[num2]) ? highlightSprite : buttonSprite);
				}
			}
			status.text = (Solo() ? message : "Travel is available in solo sessions only.");
			((Selectable)enter).interactable = Solo() && selected != null && !busy;
			((Selectable)returnButton).interactable = Solo() && origin != null && !busy;
			((Graphic)((Component)enter).GetComponentInChildren<Text>()).color = (((Selectable)enter).interactable ? Ink : Muted);
			((Graphic)((Component)returnButton).GetComponentInChildren<Text>()).color = (((Selectable)returnButton).interactable ? Ink : Muted);
		}

		private static Character SoloCharacter()
		{
			if (!Object.op_Implicit((Object)(object)CharacterManager.Instance))
			{
				return null;
			}
			return CharacterManager.Instance.GetFirstLocalCharacter();
		}

		private static bool IsPlayer(Character c)
		{
			if (Object.op_Implicit((Object)(object)c))
			{
				return (Object)(object)c == (Object)(object)SoloCharacter();
			}
			return false;
		}

		private static bool Ready(Character c)
		{
			if (Object.op_Implicit((Object)(object)c) && c.IsLocalPlayer && !c.IsDead && Object.op_Implicit((Object)(object)c.CharacterUI) && Object.op_Implicit((Object)(object)NetworkLevelLoader.Instance) && !NetworkLevelLoader.Instance.InLoading && Object.op_Implicit((Object)(object)MenuManager.Instance))
			{
				return !MenuManager.Instance.IsMasterLoadingDisplayed;
			}
			return false;
		}

		private static bool Solo()
		{
			if (Object.op_Implicit((Object)(object)CharacterManager.Instance) && CharacterManager.Instance.PlayerCharacters.Count == 1)
			{
				return !PhotonNetwork.isNonMasterClientInRoom;
			}
			return false;
		}

		private void Awake()
		{
			//IL_0027: 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_004b: Expected O, but got Unknown
			Instance = this;
			menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Open menu", new KeyboardShortcut((KeyCode)117, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Default: Left Ctrl + U. Escape closes.");
			harmony = new Harmony("rox.outward.arenatravel");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Arena Rush ready: Left Ctrl + U.");
		}

		private void Update()
		{
			//IL_001d: 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_005e: 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)
			Character val = SoloCharacter();
			if (!Ready(val))
			{
				SetOpen(value: false);
				return;
			}
			if (owner != UID.op_Implicit(val.UID))
			{
				SetOpen(value: false);
				owner = UID.op_Implicit(val.UID);
				LoadOrigin();
				selected = null;
			}
			KeyboardShortcut value = menuKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && !busy && (opened || (!val.CharacterUI.IsMenuFocused && !val.CharacterUI.IsDialogueInProgress)))
			{
				if (!Object.op_Implicit((Object)(object)canvas))
				{
					try
					{
						BuildUI(val);
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)ex);
						return;
					}
				}
				SetOpen(!opened);
			}
			if (opened && Input.GetKeyDown((KeyCode)27))
			{
				SetOpen(value: false);
			}
		}

		private void SetOpen(bool value)
		{
			if (opened != value)
			{
				opened = value;
				if (value && !cursorOwned)
				{
					ForceUnlockCursor.AddUnlockSource();
					cursorOwned = true;
				}
				if (!value && cursorOwned)
				{
					ForceUnlockCursor.RemoveUnlockSource();
					cursorOwned = false;
					releaseFrame = Time.frameCount + 1;
				}
				if (Object.op_Implicit((Object)(object)panel))
				{
					((Component)panel).gameObject.SetActive(value);
				}
				if (value)
				{
					Refresh();
				}
			}
		}

		private void OnDestroy()
		{
			SetOpen(value: false);
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if (Object.op_Implicit((Object)(object)canvas))
			{
				Object.Destroy((Object)(object)((Component)canvas).gameObject);
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LoadOrigin()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			this.origin = null;
			try
			{
				if (File.Exists(OriginPath))
				{
					XElement root = XDocument.Load(OriginPath).Root;
					Origin origin = new Origin
					{
						Scene = (string)root.Attribute(XName.op_Implicit("scene")),
						Spawn = (int)root.Attribute(XName.op_Implicit("spawn")),
						Position = new Vector3((float)root.Attribute(XName.op_Implicit("x")), (float)root.Attribute(XName.op_Implicit("y")), (float)root.Attribute(XName.op_Implicit("z"))),
						Rotation = new Quaternion((float)root.Attribute(XName.op_Implicit("qx")), (float)root.Attribute(XName.op_Implicit("qy")), (float)root.Attribute(XName.op_Implicit("qz")), (float)root.Attribute(XName.op_Implicit("qw")))
					};
					if (!string.IsNullOrEmpty(origin.Scene) && Application.CanStreamedLevelBeLoaded(origin.Scene) && origin.Spawn >= 0)
					{
						this.origin = origin;
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot read return location: " + ex.Message));
			}
		}

		private void SaveOrigin(Character c)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			Origin origin = new Origin
			{
				Scene = SceneManagerHelper.ActiveSceneName,
				Spawn = Math.Max(0, NetworkLevelLoader.Instance.LastSpawnPointID),
				Position = ((Component)c).transform.position,
				Rotation = ((Component)c).transform.rotation
			};
			XElement val = new XElement(XName.op_Implicit("origin"), new object[9]
			{
				(object)new XAttribute(XName.op_Implicit("scene"), (object)origin.Scene),
				(object)new XAttribute(XName.op_Implicit("spawn"), (object)origin.Spawn),
				(object)new XAttribute(XName.op_Implicit("x"), (object)origin.Position.x),
				(object)new XAttribute(XName.op_Implicit("y"), (object)origin.Position.y),
				(object)new XAttribute(XName.op_Implicit("z"), (object)origin.Position.z),
				(object)new XAttribute(XName.op_Implicit("qx"), (object)origin.Rotation.x),
				(object)new XAttribute(XName.op_Implicit("qy"), (object)origin.Rotation.y),
				(object)new XAttribute(XName.op_Implicit("qz"), (object)origin.Rotation.z),
				(object)new XAttribute(XName.op_Implicit("qw"), (object)origin.Rotation.w)
			});
			Directory.CreateDirectory(Path.GetDirectoryName(OriginPath));
			string text = OriginPath + ".tmp";
			new XDocument(new object[1] { val }).Save(text);
			if (File.Exists(OriginPath))
			{
				File.Replace(text, OriginPath, OriginPath + ".bak");
			}
			else
			{
				File.Move(text, OriginPath);
			}
			this.origin = origin;
		}

		private void Travel(bool back)
		{
			Character c = SoloCharacter();
			if (busy || !Ready(c))
			{
				return;
			}
			if (!Solo())
			{
				message = "Travel is available in solo sessions only.";
				Refresh();
			}
			else if (!NetworkLevelLoader.Instance.GetAllPlayerCanTravel())
			{
				message = "Please wait until loading has finished.";
				Refresh();
			}
			else
			{
				if ((back && origin == null) || (!back && selected == null))
				{
					return;
				}
				string text = (back ? origin.Scene : selected.Scene);
				int spawn = (back ? origin.Spawn : selected.Spawn);
				if (Application.CanStreamedLevelBeLoaded(text))
				{
					try
					{
						if (!back && !Destinations.All.Any((Destination d) => d.Scene == SceneManagerHelper.ActiveSceneName))
						{
							SaveOrigin(c);
						}
						busy = true;
						SetOpen(value: false);
						((MonoBehaviour)this).StartCoroutine(CompleteTravel(text, spawn, back ? origin : null, owner));
						return;
					}
					catch (Exception ex)
					{
						busy = false;
						message = "Travel cancelled: could not save the return location.";
						((BaseUnityPlugin)this).Logger.LogError((object)ex);
						Refresh();
						return;
					}
				}
				message = "This destination is unavailable in this installation.";
				Refresh();
			}
		}

		private IEnumerator CompleteTravel(string scene, int spawn, Origin back, string uid)
		{
			bool flag = false;
			try
			{
				NetworkLevelLoader.Instance.RequestSwitchArea(0f, scene, spawn, 1.5f, true);
				flag = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Travel requested: " + scene + " / spawn " + spawn));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
				message = "Travel failed. Check BepInEx logs.";
			}
			if (flag)
			{
				float deadline = Time.realtimeSinceStartup + 300f;
				bool sawLoading = false;
				bool arrived = false;
				while (Time.realtimeSinceStartup < deadline)
				{
					if (Object.op_Implicit((Object)(object)NetworkLevelLoader.Instance) && NetworkLevelLoader.Instance.InLoading)
					{
						sawLoading = true;
					}
					Character val = SoloCharacter();
					if (sawLoading && Ready(val) && SceneManagerHelper.ActiveSceneName == scene)
					{
						if (UID.op_Implicit(val.UID) != uid)
						{
							message = "Travel tracking cancelled: character changed.";
							busy = false;
							yield break;
						}
						if (back != null)
						{
							try
							{
								val.Internal_SendTeleport(back.Position, back.Rotation);
								((BaseUnityPlugin)this).Logger.LogInfo((object)"Returned to saved world position.");
							}
							catch (Exception ex2)
							{
								((BaseUnityPlugin)this).Logger.LogError((object)ex2);
								message = "Returned to the area entrance; exact position restore failed.";
								busy = false;
								yield break;
							}
						}
						arrived = true;
						message = ((back != null) ? "Returned to your starting location." : "Arrived. Defeated bosses follow the normal reset timer.");
						break;
					}
					yield return null;
				}
				if (!arrived)
				{
					message = "Travel confirmation timed out. Reopen the menu to retry.";
					((BaseUnityPlugin)this).Logger.LogWarning((object)message);
				}
			}
			busy = false;
		}
	}
}