using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("clearwater.atlyss.additionalfasttravel")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+38f0b11e72cbf86e164f7bd20806d5a9fbb81072")] [assembly: AssemblyProduct("AdditionalFastTravel")] [assembly: AssemblyTitle("clearwater.atlyss.additionalfasttravel")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 ATLYSS_AdditionalFastTravel { public static class GotoCommand { public static void buildChatMessage(string inputMessage, bool useDividers = true) { string text = (useDividers ? "---\n" : "") + inputMessage + (useDividers ? "---\n" : ""); ChatBehaviour._current.New_ChatMessage(text); } public static void ProcessCommand(string rawCommand) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) string[] array = rawCommand.Split(' '); if (SceneData.IsInDungeon()) { buildChatMessage("Cannot use this command while in a dungeon.", useDividers: false); return; } Dictionary availableScenes = SceneData.GetAvailableScenes(); Dictionary first = availableScenes.FirstOrDefault((KeyValuePair x) => x.Value.Path == SceneData.GetCurrentScene()).Value.Gotos ?? new Dictionary(); Dictionary currentSceneSpawnPoints = SceneData.GetCurrentSceneSpawnPoints(); Dictionary dictionary = first.Concat(currentSceneSpawnPoints).ToDictionary, string, Vector3>((KeyValuePair x) => x.Key, (KeyValuePair x) => x.Value, StringComparer.InvariantCultureIgnoreCase); if (array.Length == 2) { string text = array[1]; if (dictionary.TryGetValue(text, out var value)) { Player._mainPlayer._pSound._aSrcGeneral.PlayOneShot(Player._mainPlayer._pSound._warp, 1f); ((Component)Player._mainPlayer).gameObject.SetActive(false); ((Component)Player._mainPlayer).transform.position = value; ((Component)Player._mainPlayer).gameObject.SetActive(true); buildChatMessage("Moved to " + text + ".", useDividers: false); } else { buildChatMessage("ERROR: This goto point does not exist for this area.", useDividers: false); } } else if (dictionary.Count > 0) { string text2 = string.Join("\n", dictionary.Keys.Select((string x) => " " + x).ToArray()); buildChatMessage("Available goto points for this area:\n" + text2 + "\nUse /goto [POINT] to goto the given point."); } else { buildChatMessage("ERROR: No goto points were found for the current area (" + SceneData.GetCurrentScene() + ")", useDividers: false); buildChatMessage("(Tell the mod developer to add some goto points for this area!)", useDividers: false); } } } public static class Logging { public static ManualLogSource PluginLogger = Logger.CreateLogSource("AdditionalFastTravel"); public static void Debug(string text) { PluginLogger.LogDebug((object)text); } public static void Message(string text) { PluginLogger.LogMessage((object)text); } public static void Warn(string text) { PluginLogger.LogWarning((object)text); } public static void Error(string text) { PluginLogger.LogError((object)text); } public static void Fatal(string text) { PluginLogger.LogFatal((object)text); } public static void Info(string text) { PluginLogger.LogInfo((object)text); } } [BepInPlugin("clearwater.atlyss.additionalfasttravel", "AdditionalFastTravel", "1.0.1")] public class Main : BaseUnityPlugin { private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Logging.Warn("-- LOADING AdditionalFastTravel--"); Harmony val = new Harmony("clearwater.atlyss.additionalfasttravel"); val.PatchAll(); } public void onSceneLoaded(Scene scene, LoadSceneMode mode) { } } public static class SceneData { public struct KnownSceneData { public string Path; public List Spawnpoints; public Dictionary Gotos; public KnownSceneData() { Path = ""; Gotos = new Dictionary(); Spawnpoints = new List(); } } private static List dungeonScenes = new List { "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity", "Assets/Scenes/map_dungeon01_crescentGrove.unity" }; private static readonly Dictionary SceneDatas = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["SanctumCatacombs"] = new KnownSceneData { Path = "Assets/Scenes/map_dungeon00_sanctumCatacombs.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(1) { "spawnPoint" } }, ["CrescentGrove"] = new KnownSceneData { Path = "Assets/Scenes/map_dungeon01_crescentGrove.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(1) { "spawnPoint" } }, ["Sanctum"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_sanctum.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["Spawn"] = new Vector3(8.4f, 7.3f, -16.1f), ["Shop"] = new Vector3(200f, 11f, -110f), ["Enchanting"] = new Vector3(310f, 11f, -281f), ["Barracks"] = new Vector3(-160f, 29f, -600f), ["Lake"] = new Vector3(500f, 43f, 90f) }, Spawnpoints = new List(1) { "startPoint" } }, ["SanctumArena"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_sanctumArena.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(1) { "spawnPoint" } }, ["OuterSanctum"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_outerSanctum.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(4) { "spawnPoint", "terraceSpawn", "arcwoodSpawn", "tuulValleyPoint" } }, ["EffoldTerrace"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_effoldTerrace.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["CenterArea"] = new Vector3(20f, 18f, 45f) }, Spawnpoints = new List(1) { "startPoint" } }, ["ArcwoodPass"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_arcwoodPass.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["CatacombsEntrance"] = new Vector3(298f, 42f, 1819f), ["CatacombsMerchants"] = new Vector3(-54f, 1f, 1702f), ["CatacombsBadgeMerchants"] = new Vector3(136f, 81f, 2585f), ["FishingPond"] = new Vector3(453f, 48f, 1770f) }, Spawnpoints = new List(5) { "spawnPoint", "keepSpawn", "catacombWaypoint", "endDungeonSpawn", "fortSpawn" } }, ["CatacombsArena"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_catacombsArena.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(1) { "spawnPoint" } }, ["CrescentRoad"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_crescentRoad.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(3) { "spawnPoint", "keepSpawn", "gardenPoint" } }, ["CrescentKeep"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_crescentKeep.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["KeepEntrance"] = new Vector3(-150f, 55f, 235f), ["GroveDungeonLobby"] = new Vector3(-1265f, 225f, 575f), ["GroveDungeonBadgeMerchants"] = new Vector3(-1265f, 225f, 655f) }, Spawnpoints = new List(5) { "startPoint", "ckeepWaypoint1", "moonGateSpawn", "groveEntrance", "ckeepWaypoint2" } }, ["LuvoraGarden"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_luvoraGarden.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(1) { "startPoint" } }, ["TuulValley"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_tuulValley.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(2) { "spawnPoint", "enclavePoint" } }, ["TuulEnclave"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_tuulEnclave.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase), Spawnpoints = new List(2) { "spawnPoint", "enclavePoint" } }, ["BularrFortress"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_bularFortress.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["AmmagonHut"] = new Vector3(-92f, 14f, -580f) }, Spawnpoints = new List(2) { "startPoint", "fortSpawn" } }, ["WallOfTheStars"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_wallOfTheStars.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["Merchant"] = new Vector3(-100f, 12f, -345f) }, Spawnpoints = new List(3) { "spawnPoint", "wallStarWaypoint", "trialSpawn" } }, ["TrialOfTheStars"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_trialOfTheStars.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["CheckpointHub"] = new Vector3(30f, 0f, 188f), ["Checkpoint1"] = new Vector3(60f, 448f, 185f), ["Checkpoint2"] = new Vector3(-10f, 878f, 184f), ["Checkpoint3"] = new Vector3(50f, 1130f, 181f), ["Summit"] = new Vector3(-9f, 1507f, 289f) }, Spawnpoints = new List(1) { "spawnPoint" } }, ["GateOfTheMoon"] = new KnownSceneData { Path = "Assets/Scenes/00_zone_forest/_zone00_gateOfTheMoon.unity", Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { ["RedwoudEntrance"] = new Vector3(805f, 5f, 820f) }, Spawnpoints = new List(1) { "spawnPoint" } } }; public static string GetCurrentScene() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player._mainPlayer == (Object)null) { return ""; } Scene scene = ((Component)Player._mainPlayer).gameObject.scene; return ((Scene)(ref scene)).path; } public static bool IsInDungeon() { return dungeonScenes.Contains(GetCurrentScene()); } public static Dictionary GetAvailableScenes() { Dictionary dictionary = new Dictionary(StringComparer.InvariantCultureIgnoreCase); foreach (KeyValuePair sceneData in SceneDatas) { dictionary[sceneData.Key] = sceneData.Value; } foreach (KeyValuePair extraMap in GameManager._current._cachedScriptableMapDatas) { if (!dictionary.Values.Any((KnownSceneData x) => x.Path == extraMap.Value._subScene) && !dictionary.ContainsKey(extraMap.Value._mapLockID)) { dictionary[extraMap.Value._mapLockID] = new KnownSceneData { Path = extraMap.Value._subScene, Gotos = new Dictionary(StringComparer.InvariantCultureIgnoreCase) }; } } return dictionary; } public static Dictionary GetCurrentSceneSpawnPoints() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player._mainPlayer == (Object)null) { return new Dictionary(); } SpawnPoint[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); Dictionary dictionary = new Dictionary(StringComparer.InvariantCultureIgnoreCase); SpawnPoint[] array2 = array; foreach (SpawnPoint val in array2) { if (!(((Component)val).gameObject.scene != ((Component)Player._mainPlayer).gameObject.scene)) { string spawnPointTag = val._spawnPointTag; if (!string.IsNullOrWhiteSpace(spawnPointTag)) { string text = char.ToUpper(spawnPointTag[0]).ToString(); string text2 = spawnPointTag; string key = text + text2.Substring(1, text2.Length - 1); dictionary[key] = ((Component)val).transform.position; } } } return dictionary; } } public static class WarpCommand { public static void buildChatMessage(string inputMessage, bool useDividers = true) { string text = (useDividers ? "---\n" : "") + inputMessage + (useDividers ? "\n---" : ""); ChatBehaviour._current.New_ChatMessage(text); } public static void ProcessCommand(string rawCommand) { string[] array = rawCommand.Split(' '); if (SceneData.IsInDungeon()) { buildChatMessage("Cannot use this command while in a dungeon.", useDividers: false); return; } Dictionary availableScenes = SceneData.GetAvailableScenes(); if (array.Length == 2) { if (!(array[1] == "*")) { if (availableScenes.TryGetValue(array[1], out var value)) { if (SceneData.GetCurrentScene() == value.Path) { buildChatMessage("You are already in the target area.", useDividers: false); return; } Player._mainPlayer._pSound._aSrcGeneral.PlayOneShot(Player._mainPlayer._pSound._portalInteract, 1f); string text = value.Spawnpoints.FirstOrDefault() ?? "spawnPoint"; Player._mainPlayer.Cmd_SceneTransport(value.Path, text, (ZoneDifficulty)1); } else { buildChatMessage("ERROR: Given area does not exist", useDividers: false); } return; } string text2 = string.Join("\n", availableScenes.Keys.ToArray()); buildChatMessage("Available areas:\n" + text2 + "\nUse /warp [Area name] to warp to the given area."); } if (array.Length != 2) { buildChatMessage("Usage: /warp [AREA] \n(Use /warp * to view warpable areas)"); } } } internal static class ModInfo { public const string GUID = "clearwater.atlyss.additionalfasttravel"; public const string NAME = "AdditionalFastTravel"; public const string VERSION = "1.0.1"; } } namespace ATLYSS_AdditionalFastTravel.HarmonyPatches { [HarmonyPatch(typeof(ChatBehaviour), "Cmd_SendChatMessage")] internal static class ListenForWarpCommandPatch { private static bool Prefix(string _message) { if (_message.Contains("/warp")) { WarpCommand.ProcessCommand(_message); return false; } if (_message.Contains("/goto")) { GotoCommand.ProcessCommand(_message); return false; } return true; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }