Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MapTeleport v1.0.0
Landoria.MapTeleport.dll
Decompiled a day agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Landoria.MapTeleport")] [assembly: AssemblyDescription("Teleport by modifier-clicking the Valheim map.")] [assembly: AssemblyCompany("Landoria")] [assembly: AssemblyProduct("Landoria.MapTeleport")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.24120")] [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 Landoria.MapTeleport { internal static class ConfigWatcher { private const int ReloadDelayMilliseconds = 250; private const int MaximumReloadAttempts = 5; private static ConfigFile config; private static string configPath; private static ManualLogSource logger; private static FileSystemWatcher watcher; private static long lastChangeTicks; private static int reloadPending; private static int reloadAttempts; private static long ignoredWriteTicks; private static string displayName; private static Action restoreDefaults; private static Action applyConfiguration; internal static void Initialize(ConfigFile configFile, ManualLogSource logSource, string configurationDisplayName, Action restoreDefaultsAction, Action applyConfigurationAction = null) { Dispose(); config = configFile; logger = logSource; displayName = configurationDisplayName; restoreDefaults = restoreDefaultsAction; applyConfiguration = applyConfigurationAction; configPath = Path.GetFullPath(config.ConfigFilePath); watcher = new FileSystemWatcher(Path.GetDirectoryName(configPath), Path.GetFileName(configPath)); watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime; watcher.Changed += OnChanged; watcher.Created += OnChanged; watcher.Deleted += OnChanged; watcher.Renamed += OnRenamed; watcher.EnableRaisingEvents = true; } internal static void IgnoreCurrentFileVersion() { if (string.IsNullOrEmpty(configPath) || !File.Exists(configPath)) { return; } try { Interlocked.Exchange(ref ignoredWriteTicks, File.GetLastWriteTimeUtc(configPath).Ticks); Interlocked.Exchange(ref reloadPending, 0); } catch (IOException) { ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)"Could not mark the internal configuration write."); } } } internal static void Update() { if (Volatile.Read(in reloadPending) == 0 || !ReloadDelayElapsed()) { return; } Interlocked.Exchange(ref reloadPending, 0); try { bool flag = !File.Exists(configPath); if (flag) { restoreDefaults?.Invoke(); } else { config.Reload(); } applyConfiguration?.Invoke(); reloadAttempts = 0; logger.LogInfo((object)(flag ? "Recreated the deleted configuration with default values." : "Reloaded configuration after a file change.")); ShowReloadMessage(flag); } catch (Exception exception) { RetryReload(exception); } } internal static void Dispose() { if (watcher != null) { watcher.EnableRaisingEvents = false; watcher.Dispose(); watcher = null; } Interlocked.Exchange(ref reloadPending, 0); Interlocked.Exchange(ref ignoredWriteTicks, 0L); reloadAttempts = 0; displayName = null; restoreDefaults = null; applyConfiguration = null; } private static void OnChanged(object sender, FileSystemEventArgs eventArgs) { QueueReload(); } private static void OnRenamed(object sender, RenamedEventArgs eventArgs) { QueueReload(); } private static void QueueReload() { if (!IsIgnoredWrite()) { Interlocked.Exchange(ref lastChangeTicks, DateTime.UtcNow.Ticks); Interlocked.Exchange(ref reloadPending, 1); reloadAttempts = 0; } } private static bool IsIgnoredWrite() { try { long num = (File.Exists(configPath) ? File.GetLastWriteTimeUtc(configPath).Ticks : 0); return num != 0L && num == Interlocked.Read(in ignoredWriteTicks); } catch (IOException) { return false; } } private static bool ReloadDelayElapsed() { return DateTime.UtcNow.Ticks - Interlocked.Read(in lastChangeTicks) >= 2500000; } private static void RetryReload(Exception exception) { reloadAttempts++; logger.LogWarning((object)("Configuration reload failed: " + exception.Message)); if (reloadAttempts < 5) { Interlocked.Exchange(ref lastChangeTicks, DateTime.UtcNow.Ticks); Interlocked.Exchange(ref reloadPending, 1); } } private static void ShowReloadMessage(bool recreated) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, recreated ? (displayName + " configuration restored to defaults.") : (displayName + " configuration reloaded."), 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] internal static class MapTeleportPatch { private static readonly MethodInfo IsExploredMethod = AccessTools.Method(typeof(Minimap), "IsExplored", new Type[1] { typeof(Vector3) }, (Type[])null); private static bool Prefix(Minimap __instance) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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.m_localPlayer == (Object)null || WorldGenerator.instance == null || (Object)(object)ZoneSystem.instance == (Object)null || !IsTeleportKeyHeld() || !TryGetMapPosition(__instance, out var position)) { return true; } Player localPlayer = Player.m_localPlayer; if (!IsExplored(__instance, position)) { ((Character)localPlayer).Message((MessageType)2, "You can only teleport to explored locations.", 0, (Sprite)null, false); return false; } int value = Plugin.MinimumTeleportDistance.Value; if (IsTooClose(((Component)localPlayer).transform.position, position, value)) { ((Character)localPlayer).Message((MessageType)2, $"Select a destination at least {value} m away.", 0, (Sprite)null, false); return false; } if (!CanTeleport(localPlayer)) { return false; } position.y = WorldGenerator.instance.GetHeight(position.x, position.z); ((Character)localPlayer).TeleportTo(position, ((Component)localPlayer).transform.rotation, true); __instance.SetMapMode((MapMode)1); return false; } private static bool CanTeleport(Player player) { if (player.IsSensed()) { ((Character)player).Message((MessageType)2, "$msg_bedenemiesnearby", 0, (Sprite)null, false); return false; } if (!ZoneSystem.instance.GetGlobalKey((GlobalKeys)35) && !((Humanoid)player).IsTeleportable(false)) { ((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null, false); return false; } return true; } private static bool IsTooClose(Vector3 currentPosition, Vector3 destination, int minimumDistance) { //IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = destination.x - currentPosition.x; float num2 = destination.z - currentPosition.z; return num * num + num2 * num2 < (float)(minimumDistance * minimumDistance); } private static bool IsExplored(Minimap map, Vector3 destination) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); int num; if (IsExploredMethod != null) { object obj = IsExploredMethod.Invoke(map, new object[1] { destination }); if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static bool IsTeleportKeyHeld() { return Plugin.TeleportKey.Value switch { ModifierKey.LeftAlt => ZInput.GetKey((KeyCode)308, true), ModifierKey.LeftCtrl => ZInput.GetKey((KeyCode)306, true), ModifierKey.LeftShift => ZInput.GetKey((KeyCode)304, true), _ => false, }; } private static bool TryGetMapPosition(Minimap map, out Vector3 position) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)map.m_mapImageLarge).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Vector2 val2 = default(Vector2); if ((Object)(object)val == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.op_Implicit(ZInput.pointerPosition), (Camera)null, ref val2)) { position = Vector3.zero; return false; } Vector2 val3 = Rect.PointToNormalized(val.rect, val2); Rect uvRect = map.m_mapImageLarge.uvRect; float num = ((Rect)(ref uvRect)).xMin + val3.x * ((Rect)(ref uvRect)).width; float num2 = ((Rect)(ref uvRect)).yMin + val3.y * ((Rect)(ref uvRect)).height; float num3 = (float)map.m_textureSize / 2f; position = new Vector3((num * (float)map.m_textureSize - num3) * map.m_pixelSize, 0f, (num2 * (float)map.m_textureSize - num3) * map.m_pixelSize); return true; } } internal enum ModifierKey { LeftAlt, LeftCtrl, LeftShift } [BepInPlugin("Landoria.MapTeleport", "Landoria.MapTeleport", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "Landoria.MapTeleport"; public const string PluginName = "Landoria.MapTeleport"; public const string PluginVersion = "1.0.0"; private Harmony _harmony; internal static ConfigEntry<ModifierKey> TeleportKey { get; private set; } internal static ConfigEntry<int> MinimumTeleportDistance { get; private set; } private void Awake() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown TeleportKey = ((BaseUnityPlugin)this).Config.Bind<ModifierKey>("Controls", "TeleportKey", ModifierKey.LeftShift, "Modifier held while left-clicking the large map: LeftAlt, LeftCtrl, or LeftShift."); MinimumTeleportDistance = ((BaseUnityPlugin)this).Config.Bind<int>("Teleport", "MinimumDistance", 200, new ConfigDescription("Minimum map teleport distance in meters (100-1000).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), Array.Empty<object>())); ConfigWatcher.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, "MapTeleport", RestoreDefaults); _harmony = new Harmony("Landoria.MapTeleport"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Landoria.MapTeleport 1.0.0 loaded."); } private void Update() { ConfigWatcher.Update(); } private void RestoreDefaults() { TeleportKey.Value = ModifierKey.LeftShift; MinimumTeleportDistance.Value = 200; ((BaseUnityPlugin)this).Config.Save(); ConfigWatcher.IgnoreCurrentFileVersion(); } private void OnDestroy() { ConfigWatcher.Dispose(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } TeleportKey = null; MinimumTeleportDistance = null; } } }