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 Wayfarer v0.5.13
plugins/Wayfarer/Wayfarer.Core.dll
Decompiled 16 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ExtraPotions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (C) 2026 expDARE (ExtraPotions Meadworks)")] [assembly: AssemblyFileVersion("0.5.13.0")] [assembly: AssemblyInformationalVersion("0.5.13")] [assembly: AssemblyProduct("Wayfarer.Core")] [assembly: AssemblyTitle("Wayfarer.Core")] [assembly: AssemblyVersion("0.5.13.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Wayfarer.Core { public readonly struct DeathPinCandidate { public readonly float X; public readonly float Z; public readonly string? Name; public readonly bool Saved; public readonly bool Death; public readonly bool ForeignAuthor; public readonly long OwnerId; public DeathPinCandidate(float x, float z, string? name, bool saved, bool death, long ownerId, bool foreignAuthor) { X = x; Z = z; Name = name; Saved = saved; Death = death; OwnerId = ownerId; ForeignAuthor = foreignAuthor; } } public static class DeathPinCleanup { public const float MatchRadius = 1f; private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } public static int FindUnique(IReadOnlyList<DeathPinCandidate> pins, float originalX, float originalZ, int nativeDay, long localPlayerId) { if (pins == null || localPlayerId == 0L || nativeDay < 0 || !Finite(originalX) || !Finite(originalZ)) { return -1; } string b = "$hud_mapday " + nativeDay.ToString(CultureInfo.InvariantCulture); int num = -1; for (int i = 0; i < pins.Count; i++) { DeathPinCandidate deathPinCandidate = pins[i]; if (!deathPinCandidate.Saved || !deathPinCandidate.Death || deathPinCandidate.ForeignAuthor || (deathPinCandidate.OwnerId != 0L && deathPinCandidate.OwnerId != localPlayerId) || !string.Equals(deathPinCandidate.Name, b, StringComparison.Ordinal) || !Finite(deathPinCandidate.X) || !Finite(deathPinCandidate.Z)) { continue; } double num2 = (double)deathPinCandidate.X - (double)originalX; double num3 = (double)deathPinCandidate.Z - (double)originalZ; if (!(num2 * num2 + num3 * num3 >= 1.0)) { if (num >= 0) { return -1; } num = i; } } return num; } } public enum Category { Bed, Stones, Map, Boat, Grave, Player } public sealed class Destination { public string Id { get; } public Category Category { get; } public string LabelKey { get; } public long WorldId { get; } public bool IsLastKnown { get; set; } public string Name { get; set; } = ""; public float X { get; set; } public float Y { get; set; } public float Z { get; set; } public Destination(string id, Category category, string labelKey, long worldId) { Id = id; Category = category; LabelKey = labelKey; WorldId = worldId; } } public static class DestinationPolicy { public static bool SharedPlayer(bool online, bool sharesPosition, bool isLocal) { if (online && sharesPosition) { return !isLocal; } return false; } public static bool CanSelect(Destination d, long worldId, bool advancedEnabled) { if (d.WorldId == worldId) { if (!advancedEnabled && d.Category != Category.Bed && d.Category != Category.Stones) { return d.Category == Category.Map; } return true; } return false; } } public static class LandingPolicy { public static bool Clear(bool areaReady, float normalY, bool clear, bool water) { if (areaReady && clear) { if (!water) { return normalY >= 0.65f; } return true; } return false; } public static float CorrectHeight(float supplied, float floor, float water) { return Math.Max(floor, water) + 0.6f; } public static bool IsValid(float x, float y, float z) { if (!float.IsNaN(x) && !float.IsNaN(y) && !float.IsNaN(z) && !float.IsInfinity(x) && !float.IsInfinity(y) && !float.IsInfinity(z) && Math.Abs(x) < 12000f) { return Math.Abs(z) < 12000f; } return false; } } public sealed class SelectionState { public bool Armed { get; private set; } public bool PickerOpen { get; private set; } public bool Advanced { get; private set; } public long WorldId { get; private set; } public void ChangeWorld(long world) { if (WorldId != world) { Close(); WorldId = world; } } public void Arm() { Armed = !Armed; PickerOpen = false; } public void Close() { Armed = false; PickerOpen = false; } public void SetAdvanced(bool enabled) { Advanced = enabled; if (!enabled) { PickerOpen = false; } } public void SetEnabled(bool enabled) { if (!enabled) { Close(); } } public void OpenPicker() { if (Advanced) { PickerOpen = true; Armed = false; } } } public sealed class ObservedDestinations { private long world; private readonly Dictionary<string, Destination> entries = new Dictionary<string, Destination>(); public IReadOnlyCollection<Destination> Items => entries.Values; public void ChangeWorld(long id) { if (world != id) { entries.Clear(); world = id; } } public void Put(Destination d) { if (d.WorldId == world) { entries[d.Id] = d; } } } public static class WayfarerIdentity { public const string Version = "0.5.13"; public const string Family = "Mischief"; } public static class ConfigurationKeys { public const string Enabled = "Enabled"; public const string Language = "Language"; public const string CloseMap = "CloseMap"; public const string Messages = "ShowMessages"; public const string TombstoneHints = "TombstoneHints"; } public static class ServerConfigurationKeys { public const string Section = "Server"; public const string AllowTeleport = "AllowTeleport"; public const string AllowBed = "AllowBed"; } public static class CheatKeys { public const string Section = "Cheats"; public const string Stones = "TeleportToStones"; public const string Map = "TeleportAnywhere"; public const string Boat = "TeleportToBoat"; public const string Grave = "TeleportToGrave"; public const string Player = "TeleportToPlayer"; public static string? For(Category category) { return category switch { Category.Player => "TeleportToPlayer", Category.Grave => "TeleportToGrave", Category.Boat => "TeleportToBoat", Category.Map => "TeleportAnywhere", Category.Stones => "TeleportToStones", _ => null, }; } } public interface IWayfarerNavigation { NavigationSnapshot Snapshot(); } public sealed class NavigationSnapshot { public bool WorldReady { get; } public bool Advanced { get; } public IReadOnlyList<Category> Categories { get; } public NavigationSnapshot(bool worldReady, bool advanced, IEnumerable<Category> categories) { WorldReady = worldReady; Advanced = advanced; Categories = Array.AsReadOnly(categories.ToArray()); } } public sealed class NavigationProvider : IWayfarerNavigation { private readonly Func<NavigationSnapshot> snapshot; public NavigationProvider(Func<NavigationSnapshot> snapshot) { this.snapshot = snapshot ?? throw new ArgumentNullException("snapshot"); } public NavigationSnapshot Snapshot() { return snapshot(); } } public sealed class ProductPresentation { public string Title { get; } public string Brand { get; } public ProductPresentation(string title, string brand) { Title = title; Brand = brand; } } public readonly struct PanelRect { public float X { get; } public float Y { get; } public float Width { get; } public float Height { get; } public float Right => X + Width; public float Bottom => Y + Height; public PanelRect(float x, float y, float width, float height) { X = x; Y = y; Width = width; Height = height; } } public enum SlotKind { Text, Button, Icon, Tab, Switch } public readonly struct PanelSlot { public string Name { get; } public SlotKind Kind { get; } public PanelRect Rect { get; } public int Row { get; } public int Column { get; } public int Span { get; } public bool Focusable => Row >= 0; public PanelSlot(string name, SlotKind kind, PanelRect rect, int row = -1, int column = 0, int span = 1) { Name = name; Kind = kind; Rect = rect; Row = row; Column = column; Span = span; } public IEnumerable<(int X, int Y)> Cells() { for (int i = 0; i < Span; i++) { yield return (X: Column + i, Y: Row); } } } public sealed class PanelScreen { public string Id { get; } public float Height { get; } public int Columns { get; } public IReadOnlyList<PanelSlot> Slots { get; } public PanelSlot this[string name] => Slots.First((PanelSlot s) => s.Name == name); public PanelScreen(string id, float height, int columns, IReadOnlyList<PanelSlot> slots) { Id = id; Height = height; Columns = columns; Slots = slots; } public bool Has(string name) { return Slots.Any((PanelSlot s) => s.Name == name); } } public static class PanelLayout { public const float Width = 370f; public const float Left = 12f; public const float Inner = 346f; public const float Top = 62f; public const float Row = 46f; public const float ButtonHeight = 40f; public const float MinScale = 0.3f; public const float Edge = 24f; public const float TabHeight = 26f; public const float TabBetween = 6f; public const int PageSize = 6; public const int PickerColumns = 6; public const float DefaultLeft = 0.084f; public const float DefaultTop = 0.392f; public static readonly string[] MainActions = new string[4] { "Bed", "Stones", "Map", "Advanced" }; private static PanelSlot[] Header() { return new PanelSlot[2] { new PanelSlot("Title", SlotKind.Text, new PanelRect(12f, 4f, 270f, 30f)), new PanelSlot("Brand", SlotKind.Text, new PanelRect(12f, 31f, 270f, 20f)) }; } public static PanelScreen Main(IEnumerable<string> allowed) { string[] array = MainActions.Where(allowed.Contains<string>).ToArray(); List<PanelSlot> list = Header().ToList(); for (int i = 0; i < array.Length; i++) { list.Add(new PanelSlot(array[i], SlotKind.Button, new PanelRect(12f, 62f + 46f * (float)i, 346f, 40f), i)); } if (array.Length == 0) { list.Add(new PanelSlot("PolicyDenied", SlotKind.Text, new PanelRect(12f, 62f, 346f, 40f))); } return new PanelScreen("main", 124f + 46f * (float)Math.Max(0, array.Length - 1), 1, list); } public static PanelRect Tab(int index, int count) { if (count <= 0 || index < 0 || index >= count) { throw new ArgumentOutOfRangeException("index"); } float num = (346f - 6f * (float)(count - 1)) / (float)count; return new PanelRect(12f + (float)index * (num + 6f), 62f, num, 26f); } public static PanelScreen Picker(int categories, int shown) { if (categories < 1 || categories > 3) { throw new ArgumentOutOfRangeException("categories"); } if (shown < 0 || shown > 6) { throw new ArgumentOutOfRangeException("shown"); } List<PanelSlot> list = Header().ToList(); int num = 6 / categories; for (int i = 0; i < categories; i++) { list.Add(new PanelSlot("Category" + i, SlotKind.Tab, Tab(i, categories), 0, i * num, num)); } list.Add(new PanelSlot("Help", SlotKind.Text, new PanelRect(12f, 96f, 346f, 64f))); if (shown == 0) { list.Add(new PanelSlot("Empty", SlotKind.Text, new PanelRect(12f, 168f, 346f, 48f))); } for (int j = 0; j < shown; j++) { list.Add(new PanelSlot("Destination" + j, SlotKind.Button, new PanelRect(12f, 168 + j * 39, 346f, 34f), 1 + j, 0, 6)); } int num2 = 1 + shown; list.Add(new PanelSlot("Previous", SlotKind.Button, new PanelRect(12f, 409f, 46f, 30f), num2, 0, 2)); list.Add(new PanelSlot("Page", SlotKind.Text, new PanelRect(74f, 409f, 100f, 30f))); list.Add(new PanelSlot("Next", SlotKind.Button, new PanelRect(180f, 409f, 46f, 30f), num2, 2, 2)); list.Add(new PanelSlot("Refresh", SlotKind.Button, new PanelRect(232f, 409f, 126f, 30f), num2, 4, 2)); list.Add(new PanelSlot("Cancel", SlotKind.Button, new PanelRect(12f, 450f, 346f, 40f), num2 + 1, 0, 6)); return new PanelScreen("picker", 510f, 6, list); } public static float Scale(float parentWidth, float parentHeight, float height) { return Math.Max(0.3f, Math.Min(1f, Math.Min((parentHeight - 24f) / height, (parentWidth - 24f) / 370f))); } public static (float X, float Y) Position(float ratioX, float ratioY, float parentWidth, float parentHeight, float scaledWidth, float scaledHeight) { return (X: Clamp(ratioX * parentWidth, 0f, Math.Max(0f, parentWidth - scaledWidth)), Y: Clamp(ratioY * parentHeight, 0f, Math.Max(0f, parentHeight - scaledHeight))); } private static float Clamp(float value, float min, float max) { if (!(value < min)) { if (!(value > max)) { return value; } return max; } return min; } public static (int Pages, int Page, int Shown) Page(int count, int page) { int num = Math.Max(1, (count + 6 - 1) / 6); int num2 = Math.Max(0, Math.Min(page, num - 1)); return (Pages: num, Page: num2, Shown: Math.Max(0, Math.Min(6, count - num2 * 6))); } } public sealed class PendingTeleport { private readonly TeleportActorFacts actor; private readonly TeleportRequest request; private readonly long generation; private readonly double deadline; private readonly TeleportTargetFacts departure; private bool canceled; private bool movement; private bool recovered; private double recoveryDeadline; public PendingTeleport(TeleportActorFacts actor, TeleportRequest request, long generation, double now, float departureX, float departureY, float departureZ) { this.actor = actor; this.request = request; this.generation = generation; deadline = now + 10.0; departure = new TeleportTargetFacts(LandingPolicy.IsValid(departureX, departureY, departureZ), departureX, departureY, departureZ); } private bool Same(TeleportActorFacts live, long currentGeneration) { if (currentGeneration == generation && actor.ActorId == live.ActorId && actor.WorldId == live.WorldId && actor.SessionId == live.SessionId) { return live.Present; } return false; } public void Cancel() { canceled = true; } public bool TryAccept(TeleportGrant grant, TeleportActorFacts live, long currentGeneration, double now, bool effectiveEnabled) { if (canceled || movement || !effectiveEnabled || !Same(live, currentGeneration) || !live.Alive || live.Teleporting || !live.CooldownReady || now >= deadline || now >= grant.ExpiresAt || grant.ActorId != actor.ActorId || grant.WorldId != actor.WorldId || grant.SessionId != actor.SessionId || grant.RequestId != request.RequestId || grant.Category != request.Category || grant.DestinationId != request.DestinationId) { return false; } movement = true; recoveryDeadline = now + 30.0; return true; } public bool TryRecovery(TeleportActorFacts live, long currentGeneration, double now, out TeleportTargetFacts capturedDeparture) { capturedDeparture = departure; if (!movement || recovered || !departure.Valid || now >= recoveryDeadline || !Same(live, currentGeneration) || !live.Alive || live.Teleporting) { return false; } recovered = true; return true; } } public sealed class PerFrame<T> { private readonly Func<int> frame; private readonly Func<T> compute; private int cachedFrame; private bool cached; private T value; public T Value { get { int num = frame(); if (!cached || num != cachedFrame) { value = compute(); cachedFrame = num; cached = true; } return value; } } public PerFrame(Func<int> frame, Func<T> compute) { this.frame = frame ?? throw new ArgumentNullException("frame"); this.compute = compute ?? throw new ArgumentNullException("compute"); } } public sealed class TeleportPolicy { public IReadOnlyCollection<Category> PlayerCategories { get; } public bool AllowTeleport { get; } public bool AllowBed { get; } public bool AllowStones { get; } public bool AllowMap { get; } public bool AllowBoat { get; } public bool AllowGrave { get; } public bool AllowPlayer { get; } public TeleportPolicy(bool allowTeleport = true, bool allowBed = true, bool allowStones = false, bool allowMap = false, bool allowBoat = false, bool allowGrave = false, bool allowPlayer = false, IReadOnlyCollection<Category>? playerCategories = null) { PlayerCategories = (IReadOnlyCollection<Category>)(((object)playerCategories) ?? ((object)Array.Empty<Category>())); AllowTeleport = allowTeleport; AllowBed = allowBed; AllowStones = allowStones; AllowMap = allowMap; AllowBoat = allowBoat; AllowGrave = allowGrave; AllowPlayer = allowPlayer; } public static bool IsCheat(Category category) { return category != Category.Bed; } public bool Enables(Category category) { if (AllowTeleport) { return category switch { Category.Player => AllowPlayer, Category.Grave => AllowGrave, Category.Boat => AllowBoat, Category.Map => AllowMap, Category.Stones => AllowStones, Category.Bed => AllowBed, _ => false, }; } return false; } public bool AllowsCategory(Category category, bool travelCheats) { return Refusal(category, travelCheats) == null; } public string? Refusal(Category category, bool travelCheats) { if (AllowTeleport) { if (Enables(category)) { if (!IsCheat(category) || travelCheats || PlayerCategories.Contains(category)) { return null; } return "travelrestricted"; } return "destinationdisabled"; } return "teleportdisabled"; } } public static class TeleportRefusals { public const string TeleportDisabled = "teleportdisabled"; public const string DestinationDisabled = "destinationdisabled"; public const string TravelRestricted = "travelrestricted"; public static readonly IReadOnlyList<string> Codes = Array.AsReadOnly(new string[3] { "teleportdisabled", "destinationdisabled", "travelrestricted" }); public static bool Is(string? code) { if (code != null) { return Codes.Contains<string>(code); } return false; } } public sealed class TeleportRequest { public string RequestId { get; } public Category Category { get; } public string DestinationId { get; } public float X { get; } public float Y { get; } public float Z { get; } public bool IsLastKnown { get; } public TeleportRequest(string request, Category category, string destination, float x, float y, float z, bool isLastKnown = false) { Text(request); Text(destination); if (!Enum.IsDefined(typeof(Category), category)) { throw new ArgumentException("Unknown category."); } RequestId = request; Category = category; DestinationId = destination; X = x; Y = y; Z = z; IsLastKnown = isLastKnown; } internal static void Text(string value) { if (string.IsNullOrWhiteSpace(value) || value.Length > 128 || value.IndexOfAny(new char[3] { '\0', '\r', '\n' }) >= 0) { throw new ArgumentException("Invalid teleport correlation."); } } } public sealed class TeleportActorFacts { public string ActorId { get; } public long WorldId { get; } public string SessionId { get; } public bool TravelCheats { get; } public bool Present { get; } public bool Alive { get; } public bool Teleporting { get; } public bool CooldownReady { get; } public TeleportActorFacts(string actor, long world, string session, bool travelCheats, bool present, bool alive, bool teleporting, bool cooldownReady) { TeleportRequest.Text(actor); TeleportRequest.Text(session); ActorId = actor; WorldId = world; SessionId = session; TravelCheats = travelCheats; Present = present; Alive = alive; Teleporting = teleporting; CooldownReady = cooldownReady; } } public sealed class TeleportTargetFacts { public bool Valid { get; } public float X { get; } public float Y { get; } public float Z { get; } public TeleportTargetFacts(bool valid, float x, float y, float z) { Valid = valid; X = x; Y = y; Z = z; } } public sealed class AuthorizationDecision { public bool Allowed { get; } public string Code { get; } public TeleportTargetFacts Target { get; } internal AuthorizationDecision(bool allowed, string code, TeleportTargetFacts target) { Allowed = allowed; Code = code; Target = target; } } public static class TeleportAuthorization { public static bool Advanced(Category category) { if (category != Category.Boat && category != Category.Grave) { return category == Category.Player; } return true; } public static AuthorizationDecision Evaluate(TeleportPolicy policy, TeleportActorFacts actor, TeleportRequest request, TeleportTargetFacts target) { string text = policy.Refusal(request.Category, actor.TravelCheats) ?? ((!actor.Present || actor.WorldId == 0L) ? "unavailable" : ((!actor.Alive) ? "dead" : ((actor.Teleporting || !actor.CooldownReady) ? "busy" : ((!LandingPolicy.IsValid(request.X, request.Y, request.Z) || !target.Valid || !LandingPolicy.IsValid(target.X, target.Y, target.Z)) ? "unavailable" : "success")))); return new AuthorizationDecision(text == "success", text, target); } } public sealed class TeleportGrant { public string ActorId { get; } public long WorldId { get; } public string SessionId { get; } public string RequestId { get; } public string GrantId { get; } public Category Category { get; } public string DestinationId { get; } public float X { get; } public float Y { get; } public float Z { get; } public double ExpiresAt { get; } public TeleportGrant(string actor, long world, string session, string request, string grant, Category category, string destination, float x, float y, float z, double expires) { TeleportRequest.Text(actor); TeleportRequest.Text(session); TeleportRequest.Text(request); TeleportRequest.Text(grant); TeleportRequest.Text(destination); if (world == 0L || !Enum.IsDefined(typeof(Category), category) || !LandingPolicy.IsValid(x, y, z) || double.IsNaN(expires) || double.IsInfinity(expires)) { throw new ArgumentException("Invalid grant."); } ActorId = actor; WorldId = world; SessionId = session; RequestId = request; GrantId = grant; Category = category; DestinationId = destination; X = x; Y = y; Z = z; ExpiresAt = expires; } } public sealed class TeleportCompletion { public string RequestId { get; } public string GrantId { get; } public bool Accepted { get; } public TeleportCompletion(string request, string grant, bool accepted) { TeleportRequest.Text(request); TeleportRequest.Text(grant); RequestId = request; GrantId = grant; Accepted = accepted; } } public sealed class TeleportGrantLedger { private sealed class Entry { internal TeleportGrant Grant; internal bool Consumed; internal bool Completed; } private readonly Dictionary<(string, long, string, string), Entry> entries = new Dictionary<(string, long, string, string), Entry>(); private static (string, long, string, string) Key(TeleportGrant grant) { return (grant.ActorId, grant.WorldId, grant.SessionId, grant.RequestId); } public TeleportGrant? Issue(TeleportActorFacts actor, TeleportRequest request, AuthorizationDecision decision, double now) { (string, long, string, string) key = (actor.ActorId, actor.WorldId, actor.SessionId, request.RequestId); if (!decision.Allowed || entries.ContainsKey(key) || entries.Count >= 4096 || entries.Values.Any((Entry e) => e.Grant.ActorId == actor.ActorId && !e.Completed && now < e.Grant.ExpiresAt)) { return null; } TeleportTargetFacts target = decision.Target; TeleportGrant teleportGrant = new TeleportGrant(actor.ActorId, actor.WorldId, actor.SessionId, request.RequestId, Guid.NewGuid().ToString("N"), request.Category, request.DestinationId, target.X, target.Y, target.Z, now + 10.0); entries.Add(key, new Entry { Grant = teleportGrant }); return teleportGrant; } public bool TrackVerifiedGrant(TeleportGrant grant) { (string, long, string, string) key = Key(grant); if (entries.ContainsKey(key) || entries.Count >= 4096) { return false; } entries.Add(key, new Entry { Grant = grant }); return true; } public bool TryConsume(TeleportGrant grant, TeleportActorFacts liveActor, double now) { if (liveActor.ActorId != grant.ActorId || liveActor.WorldId != grant.WorldId || liveActor.SessionId != grant.SessionId || !liveActor.Present || !liveActor.Alive || liveActor.Teleporting || !liveActor.CooldownReady || now >= grant.ExpiresAt) { return false; } if (!entries.TryGetValue(Key(grant), out Entry value) || value.Consumed || value.Completed || value.Grant.GrantId != grant.GrantId || value.Grant.Category != grant.Category || value.Grant.DestinationId != grant.DestinationId || value.Grant.X != grant.X || value.Grant.Y != grant.Y || value.Grant.Z != grant.Z) { return false; } value.Consumed = true; return true; } public bool Complete(TeleportActorFacts actor, string request, string? grantId = null) { if (!entries.TryGetValue((actor.ActorId, actor.WorldId, actor.SessionId, request), out Entry value) || (grantId != null && value.Grant.GrantId != grantId)) { return false; } value.Completed = true; return true; } public void Reset() { entries.Clear(); } } public sealed class TombstoneNote { public string Cause { get; } public string Killer { get; } public int Day { get; } public TombstoneNote(string cause, string killer, int day) { Cause = cause ?? ""; Killer = killer ?? ""; Day = Math.Max(0, day); } } public static class TombstoneHints { public const bool DefaultEnabled = true; public const string SourceGuid = "JevMods.BetterTombstoneHints"; public const string SourceName = "BetterTombstoneHints"; public const string ModuleId = "tombstone_hints"; public const string CauseField = "JevMods_Cause"; public const string KillerField = "JevMods_Killer"; public const string DayField = "JevMods_Day"; public const int MaxName = 64; public const string Died = "died"; public const string Slain = "slain"; public const string SlainBy = "slain_by"; public const string SlainByCreature = "slain_by_creature"; private static readonly Dictionary<string, string> byHitType = new Dictionary<string, string>(StringComparer.Ordinal) { { "Fall", "fall" }, { "Drowning", "drowning" }, { "Burning", "burning" }, { "Freezing", "freezing" }, { "Poisoned", "poisoned" }, { "Water", "water" }, { "Smoke", "smoke" }, { "EdgeOfWorld", "edge_of_world" }, { "Impact", "impact" }, { "Cart", "cart" }, { "Tree", "tree" }, { "Self", "self" }, { "Structural", "structural" }, { "Turret", "turret" }, { "Boat", "boat" }, { "Stalagtite", "stalactite" }, { "Catapult", "catapult" }, { "CinderFire", "cinder_fire" }, { "AshlandsOcean", "ashlands_ocean" }, { "AshlandsLava", "ashlands_lava" }, { "Incinerator", "incinerator" }, { "DrawBridge", "drawbridge" } }; public static readonly IReadOnlyList<string> Causes = Array.AsReadOnly(new string[4] { "slain_by_creature", "slain_by", "slain", "died" }.Concat(byHitType.Values).ToArray()); private static readonly Dictionary<string, string> nativeByCause = byHitType.ToDictionary<KeyValuePair<string, string>, string, string>((KeyValuePair<string, string> p) => p.Value, (KeyValuePair<string, string> p) => "$stat_DeathBy" + p.Key, StringComparer.Ordinal); public static string Key(string cause) { return "tomb_" + cause; } public static string NativeKey(string cause) { switch (cause) { case "slain_by_creature": case "slain_by": case "slain": return "$stat_DeathByEnemyHit"; case "ashlands_lava": return "$stat_DeathByBurning"; default: { if (nativeByCause.TryGetValue(cause, out string value)) { return value; } goto case null; } case null: return ""; } } public static string ForHitType(string hitType) { if (hitType == null || !byHitType.TryGetValue(hitType, out string value)) { return "died"; } return value; } public static TombstoneNote Death(string? hitType, object? attacker, bool attackerIsPlayer, bool attackerIsBoss, string attackerName, int day) { if (hitType == null) { return new TombstoneNote("died", "", day); } if (hitType == "EnemyHit" || hitType == "PlayerHit") { if (attacker == null) { return new TombstoneNote("slain", "", day); } return new TombstoneNote((attackerIsPlayer || attackerIsBoss) ? "slain_by" : "slain_by_creature", Clean(attackerName), day); } return new TombstoneNote(ForHitType(hitType), "", day); } public static string Render(TombstoneNote note, Func<string, string> localize, string dayText) { string text = NativeKey(Causes.Contains(note.Cause) ? note.Cause : "died"); string text2 = ((text.Length == 0) ? "" : Clean(localize(text), 256)); if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal)) { text2 = ""; } string text3 = Clean(localize(Clean(note.Killer))); if (text3.Length > 0) { text2 = ((text2.Length == 0) ? text3 : (text2 + ": " + text3)); } string text4 = Clean(dayText); if (text4.Length != 0) { if (text2.Length != 0) { return text2 + ", " + text4; } return text4; } return text2; } public static string Insert(string hoverText, string note) { if (hoverText.Length == 0 || note.Length == 0) { return hoverText; } int num = hoverText.IndexOf('\n'); if (num >= 0) { return hoverText.Insert(num, "\n" + note); } return hoverText + "\n" + note; } public static bool StepsAside(IEnumerable<string> installedGuids) { return installedGuids.Contains<string>("JevMods.BetterTombstoneHints", StringComparer.Ordinal); } private static string Clean(string? value, int max = 64) { if (string.IsNullOrEmpty(value)) { return ""; } string text = new string(value.Where((char c) => c != '<' && c != '>' && c != '\r' && c != '\n').ToArray()).Trim(); if (text.Length <= max) { return text; } return text.Substring(0, max); } } public static class WayfarerLanguages { public static readonly string[] Languages = new string[7] { "English", "Spanish", "Chinese", "Russian", "French", "German", "Korean" }; public static string[] Settings => new string[1] { "Auto" }.Concat(Languages).ToArray(); public static string Normalize(string language) { if (language.IndexOf("Chinese", StringComparison.OrdinalIgnoreCase) >= 0) { return "Chinese"; } return Languages.FirstOrDefault((string l) => string.Equals(l, language, StringComparison.OrdinalIgnoreCase)) ?? "English"; } public static string NameKey(string setting) { return "language_" + (string.Equals(setting, "Auto", StringComparison.OrdinalIgnoreCase) ? "auto" : Normalize(setting).ToLowerInvariant()); } } }
plugins/Wayfarer/Wayfarer.dll
Decompiled 16 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExtraPotions.Meadworks.Crucible; using ExtraPotions.Meadworks.Crucible.UI; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using Wayfarer.Core; using Wayfarer.CrucibleIntegration; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ExtraPotions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (C) 2026 expDARE (ExtraPotions Meadworks)")] [assembly: AssemblyFileVersion("0.5.13.0")] [assembly: AssemblyInformationalVersion("0.5.13")] [assembly: AssemblyProduct("Wayfarer")] [assembly: AssemblyTitle("Wayfarer")] [assembly: AssemblyVersion("0.5.13.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Wayfarer { internal sealed class DestinationCatalog { private readonly Plugin plugin; private readonly ObservedDestinations boats = new ObservedDestinations(); private readonly Dictionary<string, Ship> liveBoats = new Dictionary<string, Ship>(); internal DestinationCatalog(Plugin plugin) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown this.plugin = plugin; } private static Vector3 Position(Destination d) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(d.X, d.Y, d.Z); } private Destination Make(string id, Category c, string key, Vector3 pos, string name = "") { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown return new Destination(id, c, key, plugin.World) { X = pos.x, Y = pos.y, Z = pos.z, Name = name }; } internal unsafe void Observe() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) boats.ChangeWorld(plugin.World); liveBoats.Clear(); if (plugin.World == 0L) { return; } foreach (Destination item in boats.Items) { item.IsLastKnown = true; } foreach (IMonoUpdater instance in Ship.Instances) { Ship val = (Ship)(object)((instance is Ship) ? instance : null); if (val != null) { ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { ZDOID uid = component.GetZDO().m_uid; string text = "boat:" + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString(); Destination val2 = Make(text, (Category)3, "boat", ((Component)val).transform.position, ((Object)val).name.Replace("(Clone)", "")); boats.Put(val2); liveBoats[text] = val; } } } } internal unsafe List<Destination> List(Category category) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) if (!plugin.CanUse(category) || plugin.World == 0L) { return new List<Destination>(); } if ((int)category == 3) { Observe(); return boats.Items.OrderBy((Destination d) => d.Id).ToList(); } List<Destination> list = new List<Destination>(); Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if ((int)category == 4) { if (val != null && val.HaveDeathPoint()) { list.Add(Make("death", category, "death", val.GetDeathPoint())); } if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { TombStone[] array = Object.FindObjectsByType<TombStone>((FindObjectsSortMode)0); foreach (TombStone val2 in array) { ZNetView component = ((Component)val2).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && AccessTools.Method(typeof(TombStone), "GetOwner", (Type[])null, (Type[])null)?.Invoke(val2, null) is long num2 && num2 == Player.m_localPlayer.GetPlayerID()) { ZDOID uid = component.GetZDO().m_uid; list.Add(Make("grave:" + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString(), category, "grave", ((Component)val2).transform.position)); } } } } else if ((int)category == 5 && Object.op_Implicit((Object)(object)ZNet.instance)) { ZNetView val3 = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).GetComponent<ZNetView>() : null); string text = ((Object.op_Implicit((Object)(object)val3) && val3.IsValid()) ? ((object)Unsafe.As<ZDOID, ZDOID>(ref val3.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString() : ""); foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { bool publicPosition = player.m_publicPosition; ZDOID uid = player.m_characterID; if (DestinationPolicy.SharedPlayer(true, publicPosition, ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString() == text) && LandingPolicy.IsValid(player.m_position.x, player.m_position.y, player.m_position.z)) { uid = player.m_characterID; list.Add(Make("player:" + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString(), category, "player", player.m_position, player.m_name)); } } } return (from d in list orderby d.Name, d.Id select d).ToList(); } internal bool TryResolve(string id, out Destination? d, out string error) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) d = null; error = "unavailable"; if (plugin.World == 0L) { return false; } Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if (id == "bed") { error = "nobed"; if (val == null || !val.HaveCustomSpawnPoint()) { return false; } d = Make(id, (Category)0, "bed", val.GetCustomSpawnPoint()); } else if (id == "stones") { error = "nostones"; string text = ((string)AccessTools.Field(typeof(Game), "m_StartLocation")?.GetValue(Game.instance)) ?? "StartTemple"; Vector3 pos = default(Vector3); if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !ZoneSystem.instance.GetLocationIcon(text, ref pos)) { return false; } d = Make(id, (Category)1, "stones", pos); } else { if (!plugin.CanAdvanced) { return false; } Category category = (Category)(id.StartsWith("boat:") ? 3 : (id.StartsWith("player:") ? 5 : 4)); d = ((IEnumerable<Destination>)List(category)).FirstOrDefault((Func<Destination, bool>)((Destination item) => item.Id == id)); if (d == null) { return false; } } if (!plugin.CanUse(d.Category)) { error = plugin.Refusal(d.Category); return false; } if (LandingPolicy.IsValid(d.X, d.Y, d.Z)) { return DestinationPolicy.CanSelect(d, plugin.World, plugin.CanAdvanced); } return false; } } internal sealed class MapUi { private static readonly Color Ink = new Color(0.92f, 0.88f, 0.76f); private static readonly Category[] EveryCategory = (Category[])Enum.GetValues(typeof(Category)); private readonly Plugin p; private RectTransform? root; private string signature = ""; private string screen = "main"; private Category category = (Category)3; private int page; private long lastWorld; private bool inputsReady; private string heldScreen = ""; private Category heldCategory; private int heldPage; private string heldLanguage = ""; private bool heldEnabled; private bool heldArmed; private bool heldTeleport; private int heldMask; private readonly Dictionary<GridCell, Selectable> focusables = new Dictionary<GridCell, Selectable>(); private GridNavigator? navigator; private GridCell? focus; private Category[] Categories { get { Category[] array = new Category[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); return ((IEnumerable<Category>)(object)array).Where(p.CanUse).ToArray(); } } internal MapUi(Plugin plugin) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) p = plugin; } internal void Destroy() { focusables.Clear(); navigator = null; if (Object.op_Implicit((Object)(object)root)) { Object.Destroy((Object)(object)((Component)root).gameObject); } root = null; signature = ""; } internal void Refresh() { //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if (p.World != lastWorld) { lastWorld = p.World; Destroy(); screen = "main"; page = 0; focus = null; } if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.m_largeRoot) || !instance.m_largeRoot.activeSelf || p.World == 0L) { p.State.Close(); if (Object.op_Implicit((Object)(object)root)) { ((Component)root).gameObject.SetActive(false); } screen = "main"; signature = ""; focus = null; return; } if (PortalPickerOpen(instance)) { p.State.Close(); if (Object.op_Implicit((Object)(object)root)) { ((Component)root).gameObject.SetActive(false); } return; } if (screen == "picker" && !p.State.PickerOpen) { screen = "main"; } string language = p.Language; bool value = p.Options.Enabled.Value; bool armed = p.State.Armed; bool canTeleport = p.CanTeleport; int num = 0; for (int i = 0; i < EveryCategory.Length; i++) { if (p.CanUse(EveryCategory[i])) { num |= 1 << i; } } string text = screen; Category val = category; int num2 = page; bool flag = inputsReady && text == heldScreen && val == heldCategory && num2 == heldPage && language == heldLanguage && value == heldEnabled && armed == heldArmed && canTeleport == heldTeleport && num == heldMask; if (Object.op_Implicit((Object)(object)root) && signature.Length > 0 && flag) { ((Component)root).gameObject.SetActive(true); } else { string text2 = string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}", text, val, num2, language, value, armed, canTeleport, string.Join(",", EveryCategory.Where(p.CanUse))); if (!Object.op_Implicit((Object)(object)root) || signature != text2) { Build(instance); signature = text2; } else { ((Component)root).gameObject.SetActive(true); } inputsReady = true; heldScreen = text; heldCategory = val; heldPage = num2; heldLanguage = language; heldEnabled = value; heldArmed = armed; heldTeleport = canTeleport; heldMask = num; } Pad(); } internal static bool PortalPickerOpen(Minimap map) { if (!Object.op_Implicit((Object)(object)map) || !Object.op_Implicit((Object)(object)map.m_mapImageLarge)) { return false; } Transform parent = ((Transform)((Graphic)map.m_mapImageLarge).rectTransform).parent; Transform val = (Object.op_Implicit((Object)(object)parent) ? parent.Find("Threshold.Destinations") : null); if (Object.op_Implicit((Object)(object)val)) { return ((Component)val).gameObject.activeInHierarchy; } return false; } private void Build(Minimap map) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c7: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Destroy(); PanelScreen val = (PanelScreen)((screen == "picker") ? ((object)PickerLayout()) : ((object)MainLayout())); if (val == null) { Build(map); return; } root = KitPanel.Create(map.m_largeRoot.transform, "WayfarerPanel", new Vector2(370f, val.Height), false); if (Object.op_Implicit((Object)(object)root)) { KitForged.SidePlate(root); RectTransform? obj = root; RectTransform? obj2 = root; RectTransform? obj3 = root; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); obj3.pivot = val2; Vector2 anchorMin = (obj2.anchorMax = val2); obj.anchorMin = anchorMin; RectTransform val4 = (RectTransform)((Transform)root).parent; RectTransform? obj4 = root; Vector3 one = Vector3.one; Rect rect = val4.rect; float width = ((Rect)(ref rect)).width; rect = val4.rect; ((Transform)obj4).localScale = one * PanelLayout.Scale(width, ((Rect)(ref rect)).height, val.Height); Position(root, 0.084f, 0.392f); TMP_Text val5 = Text(val, "Title", p.Presentation.Title, 19f); if ((Object)(object)KitCanvas.Heading != (Object)null) { val5.font = KitCanvas.Heading; } Text(val, "Brand", p.Presentation.Brand, 12f); if (screen == "picker") { Picker(val); } else { Main(val); } RestoreFocus(); } } private PanelScreen MainLayout() { List<string> list = new List<string>(); if (p.CanUse((Category)0)) { list.Add("Bed"); } if (p.CanUse((Category)1)) { list.Add("Stones"); } if (p.CanUse((Category)2)) { list.Add("Map"); } if (p.CanAdvanced) { list.Add("Advanced"); } return PanelLayout.Main((IEnumerable<string>)list); } private PanelScreen? PickerLayout() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) Category[] categories = Categories; if (categories.Length == 0) { p.State.Close(); screen = "main"; signature = ""; return null; } if (!categories.Contains(category)) { category = categories[0]; page = 0; } (int, int, int) tuple = PanelLayout.Page(p.Catalog.List(category).Count, page); page = tuple.Item2; return PanelLayout.Picker(categories.Length, tuple.Item3); } private void Main(PanelScreen layout) { if (layout.Has("Bed")) { Button(layout, "Bed", p.T("bed"), delegate { p.Teleports.TryTeleport("bed"); }); } if (layout.Has("Stones")) { Button(layout, "Stones", p.T("stones"), delegate { p.Teleports.TryTeleport("stones"); }); } if (layout.Has("Map")) { Button(layout, "Map", p.T(p.State.Armed ? "armed" : "anywhere"), delegate { p.State.Arm(); if (p.State.Armed) { p.Report("pick"); } }); } if (layout.Has("Advanced")) { Button(layout, "Advanced", p.T("destinations"), delegate { p.State.OpenPicker(); screen = "picker"; page = 0; }); } if (layout.Has("PolicyDenied")) { Text(layout, "PolicyDenied", p.T("teleportdisabled"), 16f); } } private unsafe void Picker(PanelScreen layout) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Invalid comparison between Unknown and I4 //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Invalid comparison between Unknown and I4 Category[] categories = Categories; List<KitTab> list = ((IEnumerable<Category>)categories).Select((Func<Category, KitTab>)((Category c) => new KitTab { Id = ((object)(*(Category*)(&c))/*cast due to .constrained prefix*/).ToString(), Caption = p.T(((object)(*(Category*)(&c))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant()), Click = Guard(delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) category = c; page = 0; signature = ""; }) })).ToList(); List<Button> list2 = KitTabs.Place(root, (IList<KitTab>)list, ((object)Unsafe.As<Category, Category>(ref category)/*cast due to .constrained prefix*/).ToString(), 12f, 62f, 346f); for (int num = 0; num < list2.Count && num < categories.Length; num++) { Focus(layout["Category" + num], (Selectable)(object)list2[num]); KitTooltip.Set(((Component)list2[num]).gameObject, p.T(((object)Unsafe.As<Category, Category>(ref categories[num])/*cast due to .constrained prefix*/).ToString().ToLowerInvariant()), p.T(((int)categories[num] == 3) ? "boathelp" : (((int)categories[num] == 4) ? "deathhelp" : "playerhelp"))); } Text(layout, "Help", p.T(((int)category == 3) ? "boathelp" : (((int)category == 4) ? "deathhelp" : "playerhelp")), 14f); List<Destination> list3 = p.Catalog.List(category); (int Pages, int Page, int Shown) paging = PanelLayout.Page(list3.Count, page); if (layout.Has("Empty")) { Text(layout, "Empty", p.T("none"), 16f); } for (int num2 = 0; num2 < paging.Shown; num2++) { int num3 = paging.Page * 6 + num2; Destination d = list3[num3]; string text = p.T(d.LabelKey) + (string.IsNullOrEmpty(d.Name) ? "" : (" · " + d.Name)) + (d.IsLastKnown ? (" · " + p.T("lastknown")) : ""); if ((int)d.Category == 4 && d.Id != "death") { text = text + " · " + (num3 + 1); } Button val = Button(layout, "Destination" + num2, text, delegate { p.Teleports.TryTeleport(d.Id); }); if (Object.op_Implicit((Object)(object)val)) { KitTooltip.Set(((Component)val).gameObject, p.T(((object)Unsafe.As<Category, Category>(ref category)/*cast due to .constrained prefix*/).ToString().ToLowerInvariant()), text + "\n" + p.T("destination_help")); } } Button(layout, "Previous", "‹", delegate { page = Mathf.Max(0, page - 1); signature = ""; }); Text(layout, "Page", $"{paging.Page + 1} / {paging.Pages}", 16f).alignment = (TextAlignmentOptions)514; Button(layout, "Next", "›", delegate { page = Mathf.Min(paging.Pages - 1, page + 1); signature = ""; }); Button(layout, "Refresh", p.T("refresh"), delegate { signature = ""; }); Button(layout, "Cancel", p.T("cancel"), delegate { p.State.Close(); screen = "main"; signature = ""; }); } private static Vector2 At(PanelRect rect) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return new Vector2(((PanelRect)(ref rect)).X, 0f - ((PanelRect)(ref rect)).Y); } private static void Place(RectTransform rect, PanelRect at) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect.pivot = val; Vector2 anchorMin = (rect.anchorMax = val); rect.anchorMin = anchorMin; rect.anchoredPosition = At(at); rect.sizeDelta = new Vector2(((PanelRect)(ref at)).Width, ((PanelRect)(ref at)).Height); } private Action Guard(Action action) { return delegate { try { action(); } catch (Exception error) { p.Error(error); } }; } private TMP_Text Text(PanelScreen layout, string name, string words, float size) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) TMP_Text obj = KitCanvas.Text((Transform)(object)root, name, words, size, Ink, (TextAlignmentOptions)4097, true); obj.enableAutoSizing = true; obj.fontSizeMin = Mathf.Min(12f, size); obj.fontSizeMax = size; obj.overflowMode = (TextOverflowModes)3; RectTransform rectTransform = obj.rectTransform; PanelSlot val = layout[name]; Place(rectTransform, ((PanelSlot)(ref val)).Rect); return obj; } private Button? Button(PanelScreen layout, string name, string caption, Action action) { //IL_0002: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0056: Unknown result type (might be due to invalid IL or missing references) PanelSlot slot = layout[name]; RectTransform? obj = root; Action action2 = Guard(action); Vector2 val = At(((PanelSlot)(ref slot)).Rect); PanelRect rect = ((PanelSlot)(ref slot)).Rect; float width = ((PanelRect)(ref rect)).Width; rect = ((PanelSlot)(ref slot)).Rect; Button val2 = KitButton.Create(obj, name, caption, action2, val, new Vector2(width, ((PanelRect)(ref rect)).Height)); if (Object.op_Implicit((Object)(object)val2)) { Focus(slot, (Selectable)(object)val2); KitTooltip.Set(((Component)val2).gameObject, caption, ButtonHelp(name)); } return val2; } private string ButtonHelp(string name) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Invalid comparison between Unknown and I4 //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Invalid comparison between Unknown and I4 switch (name) { case "Bed": case "Stones": return p.T("usagehelp"); case "Map": return p.T("pick") + "\n" + p.T("usagehelp"); case "Advanced": return p.T("cheathelp"); case "Previous": return p.T("previous_help"); case "Next": return p.T("next_help"); case "Refresh": return p.T(((int)category == 3) ? "boathelp" : (((int)category == 4) ? "deathhelp" : "playerhelp")); case "Cancel": return p.T("back_help"); default: return p.T("destination_help"); } } private void Focus(PanelSlot slot, Selectable control) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!((PanelSlot)(ref slot)).Focusable) { return; } foreach (var (num, num2) in ((PanelSlot)(ref slot)).Cells()) { focusables[new GridCell(num, num2)] = control; } navigator = null; } private bool Usable(GridCell cell) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (focusables.TryGetValue(cell, out Selectable value) && Object.op_Implicit((Object)(object)value) && ((Component)value).gameObject.activeInHierarchy) { return value.IsInteractable(); } return false; } private GridNavigator? Navigator() { //IL_0091: 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_0098: Expected O, but got Unknown //IL_009d: Expected O, but got Unknown if (navigator != null || focusables.Count == 0) { return navigator; } int num = focusables.Keys.Max((GridCell c) => ((GridCell)(ref c)).X) + 1; int num2 = focusables.Keys.Max((GridCell c) => ((GridCell)(ref c)).Y) + 1; GridNavigator val = new GridNavigator(num, num2, (Func<GridCell, bool>)Usable, (Func<GridCell, GridCell>)null, false); GridNavigator result = val; navigator = val; return result; } private void RestoreFocus() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (focus.HasValue) { if (!focusables.ContainsKey(focus.Value)) { GridNavigator val = Navigator(); focus = ((val == null) ? ((GridCell?)null) : KitPad.Start(val)); } Select(); } } private void Select() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (focus.HasValue && (Object)(object)EventSystem.current != (Object)null && focusables.TryGetValue(focus.Value, out Selectable value) && Object.op_Implicit((Object)(object)value)) { EventSystem.current.SetSelectedGameObject(((Component)value).gameObject); } } private void Pad() { //IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0045: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)root) || !((Component)root).gameObject.activeInHierarchy || !MeadworksInput.GamepadActive) { return; } foreach (PadButton item in KitPad.Polled) { if ((int)item == 1 || !MeadworksInput.PadDown(item)) { continue; } if ((int)KitPad.ActionOf(item) == 2) { if (focus.HasValue && Usable(focus.Value)) { MeadworksInput.PadConsume(item); Selectable obj = focusables[focus.Value]; Button val = (Button)(object)((obj is Button) ? obj : null); if (val != null) { ((UnityEvent)val.onClick).Invoke(); } } } else { GridNavigator val2 = Navigator(); if (val2 != null) { MeadworksInput.PadConsume(item); focus = (focus.HasValue ? new GridCell?(KitPad.Next(val2, focus.Value, item)) : KitPad.Start(val2)); Select(); } } break; } } internal static void Position(RectTransform panel, float x, float y) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0042: 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_004e: 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_006e: Unknown result type (might be due to invalid IL or missing references) Rect rect = ((RectTransform)((Transform)panel).parent).rect; Vector2 size = ((Rect)(ref rect)).size; Vector2 val = Vector2.Scale(panel.sizeDelta, new Vector2(((Transform)panel).localScale.x, ((Transform)panel).localScale.y)); (float, float) tuple = PanelLayout.Position(x, y, size.x, size.y, val.x, val.y); panel.anchoredPosition = new Vector2(tuple.Item1, 0f - tuple.Item2); } } [BepInPlugin("com.meadworks.wayfarer", "Wayfarer", "0.5.13")] [BepInDependency("com.meadworks.crucible", "0.3.32")] [BepInDependency("com.meadworks.crucible.ui", "0.3.21")] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Id = "com.meadworks.wayfarer"; internal static Plugin? Instance; internal Settings Options; internal readonly SelectionState State = new SelectionState(); internal DestinationCatalog Catalog; internal TeleportService Teleports; internal MapUi? Ui; private MeadworksLog? log; private Harmony? harmony; private float nextScan; private float nextError; private ProductRegistration? registration; private CrucibleServices? integration; internal ProductPresentation Presentation = new ProductPresentation("Wayfarer", "Meadworks"); internal CrucibleServices Integration => integration; internal bool CanTeleport { get { if (Options != null && Options.Enabled.Value && integration != null && integration.Session.AuthorityReady) { return integration.EffectivePolicy.AllowTeleport; } return false; } } internal bool CanAdvanced { get { if (!CanUse((Category)3) && !CanUse((Category)4)) { return CanUse((Category)5); } return true; } } internal long World { get { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.GetWorld() == null) { return 0L; } return ZNet.instance.GetWorldUID(); } } internal string Language { get { if (!(Options.Language.Value != "Auto")) { return MeadworksTranslations.GameLanguage(); } return WayfarerLanguages.Normalize(Options.Language.Value); } } internal bool CanUse(Category category) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (CanTeleport) { return integration.EffectivePolicy.AllowsCategory(category, integration.TravelCheats); } return false; } internal string Refusal(Category category) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) object obj; if (integration != null && integration.Session.AuthorityReady) { obj = integration.EffectivePolicy.Refusal(category, integration.TravelCheats); if (obj == null) { return "unavailable"; } } else { obj = "authorityunavailable"; } return (string)obj; } internal string TeleportRefusal() { if (integration != null && integration.Session.AuthorityReady) { return "teleportdisabled"; } return "authorityunavailable"; } internal void Refuse(Category category) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (integration == null || !TeleportPolicy.IsCheat(category) || !integration.EffectivePolicy.Enables(category) || MeadworksMischief.TryUse("com.meadworks.wayfarer", "Cheats." + CheatKeys.For(category), (MischiefCategory)4, (string)null)) { Report(Refusal(category)); } } internal string T(string key) { return integration?.Text(key, Language) ?? key; } private void Awake() { //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown log = MeadworksLog.For(((BaseUnityPlugin)this).Logger, "Wayfarer"); try { if (!Plugin.IsReady) { throw new InvalidOperationException("Required Crucible is not ready"); } MeadworksConfig.EnsureSchema(((BaseUnityPlugin)this).Config, 1, (IReadOnlyList<MigrationStep>)null); registration = Plugin.Services.Register(MeadworksIntegration.Metadata()); integration = new CrucibleServices(registration, ((BaseUnityPlugin)this).Info.Metadata, ((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, Navigation); } catch (Exception ex) { integration?.Dispose(); integration = null; ProductRegistration? obj = registration; if (obj != null) { obj.Dispose(); } registration = null; ((Behaviour)this).enabled = false; log.Error((object)("Wayfarer initialization rejected: " + ex.GetType().Name + ": " + ex.Message)); return; } Options = new Settings(((BaseUnityPlugin)this).Config, integration); if (!MeadworksHeadless.AllowsUi) { InfoMessage("Wayfarer server policy and authority handlers ready"); return; } Instance = this; Catalog = new DestinationCatalog(this); Teleports = new TeleportService(this); Ui = new MapUi(this); harmony = new Harmony("com.meadworks.wayfarer"); harmony.PatchAll(typeof(Plugin).Assembly); InfoMessage("Wayfarer 0.5.13 | ExtraPotions | expDARE | Crucible API 0.1 ready"); } private NavigationSnapshot Navigation() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown return new NavigationSnapshot(integration != null && integration.Session.AuthorityReady, CanAdvanced, Enum.GetValues(typeof(Category)).Cast<Category>().Where(CanUse)); } private void InfoMessage(string message) { MeadworksLog? obj = log; if (obj != null) { obj.Info(message); } } private void LogError(object error) { MeadworksLog? obj = log; if (obj != null) { obj.Error(error); } } private void Update() { if (Options == null || !MeadworksHeadless.AllowsUi) { return; } try { State.ChangeWorld(World); State.SetAdvanced(CanAdvanced); State.SetEnabled(CanTeleport); if (State.Armed && !CanUse((Category)2)) { State.Close(); } Teleports?.UpdateLanding(); integration?.Update(); if (Time.unscaledTime >= nextScan) { Catalog.Observe(); nextScan = Time.unscaledTime + 2f; } Ui?.Refresh(); } catch (Exception error) { if (Time.unscaledTime >= nextError) { LogError(error); nextError = Time.unscaledTime + 10f; } } } internal void Report(string key) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (Options.ShowMessages.Value) { string text = T(key); if ((int)MeadworksHeadless.Channel == 0 && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, true); } else { InfoMessage(text); } } } internal void Error(Exception error) { LogError(error); Report("error"); } private void OnDestroy() { Teleports?.Dispose(); Ui?.Destroy(); Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } integration?.Dispose(); ProductRegistration? obj2 = registration; if (obj2 != null) { obj2.Dispose(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] internal static class MapPatches { private static bool Prefix(Minimap __instance) { //IL_00c0: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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) Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null || !instance.Options.Enabled.Value || !instance.State.Armed || MapUi.PortalPickerOpen(__instance) || instance.Teleports == null) { return true; } try { MethodInfo methodInfo = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", (Type[])null, (Type[])null); if (methodInfo == null) { instance.Report("unavailable"); return false; } Type type = AccessTools.TypeByName("ZInput"); object obj = ((type == null) ? null : AccessTools.Property(type, "pointerPosition")?.GetValue(null)); Vector3 position = (Vector3)methodInfo.Invoke(__instance, new object[1] { (obj is Vector3 val) ? val : Input.mousePosition }); instance.Teleports.ToMap(position); } catch (Exception error) { instance.Error(error); } return false; } } internal sealed class Settings { public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<bool> CloseMap; public readonly ConfigEntry<bool> ShowMessages; public readonly ConfigEntry<bool> TombstoneHints; public readonly ConfigEntry<string> Language; private readonly CrucibleServices integration; private ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T value, string description) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return Bind(config, section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } private ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T value, ConfigDescription description) { return integration.Bind(config, section, key, value, description); } public Settings(ConfigFile config, CrucibleServices integration) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown this.integration = integration; Enabled = Bind(config, "General", "Enabled", value: true, "Master switch for Wayfarer travel and tombstone hints on this client."); Language = Bind(config, "General", "Language", "Auto", new ConfigDescription("Auto follows the game. Other supported languages fall back to English.", (AcceptableValueBase)(object)new AcceptableValueList<string>(WayfarerLanguages.Settings), Array.Empty<object>())); CloseMap = Bind(config, "General", "CloseMap", value: true, new ConfigDescription("Close the map after a teleport is accepted.", (AcceptableValueBase)null, new object[1] { (object)new ConfigDependency((Func<bool>)(() => Enabled.Value), (Func<string>)(() => "Requires General: Enabled."), (Func<bool>)null) })); ShowMessages = Bind(config, "General", "ShowMessages", value: true, new ConfigDescription("Show translated screen messages.", (AcceptableValueBase)null, new object[1] { (object)new ConfigDependency((Func<bool>)(() => Enabled.Value), (Func<string>)(() => "Requires General: Enabled."), (Func<bool>)null) })); TombstoneHints = Bind(config, "General", "TombstoneHints", value: true, new ConfigDescription("Client-side: show the cause of death and the day on tombstones in your game language (adapted from BetterTombstoneHints, MIT). Steps aside while BetterTombstoneHints is installed.", (AcceptableValueBase)null, new object[1] { (object)new ConfigDependency((Func<bool>)(() => Enabled.Value), (Func<string>)(() => "Requires General: Enabled."), (Func<bool>)null) })); } } internal sealed class TeleportService { private readonly Plugin p; private Vector3? pending; private Vector3? recovery; private long pendingWorld; private float expires; private long generation = -1L; private Task<OperationResult<TeleportGrant>>? authorization; private CancellationTokenSource? cancellation; private PendingTeleport? lifecycle; private TeleportRequest? request; private readonly TeleportGrantLedger grants = new TeleportGrantLedger(); internal bool AwaitingAuthorization => authorization != null; internal TeleportService(Plugin plugin) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown p = plugin; } internal void ToMap(Vector3 position) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) position.y = 30f; Start(position, (Category)2, "map", lastKnown: false); } internal void TryTeleport(string id) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (!p.CanTeleport) { p.Report(p.TeleportRefusal()); return; } if (!p.Catalog.TryResolve(id, out Destination d, out string error) || d == null) { p.Report(error); return; } Vector3 target = default(Vector3); ((Vector3)(ref target))..ctor(d.X, d.Y, d.Z); if ((int)d.Category == 2 || (int)d.Category == 1) { target.y = 30f; } Start(target, d.Category, d.Id, d.IsLastKnown); } private TeleportActorFacts? Actor() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; SessionSnapshot session = p.Integration.Session; if (!Object.op_Implicit((Object)(object)localPlayer) || p.World == 0L || !session.AuthorityReady || session.WorldId != p.World) { return null; } ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner()) { return null; } float num = (float)(AccessTools.Field(typeof(Player), "m_teleportCooldown")?.GetValue(localPlayer) ?? ((object)0f)); return new TeleportActorFacts(localPlayer.GetPlayerID().ToString(CultureInfo.InvariantCulture), p.World, session.SessionId, session.IsAdmin, true, !((Character)localPlayer).IsDead(), ((Character)localPlayer).IsTeleporting(), num >= 2f); } private void Start(Vector3 target, Category category, string destination, bool lastKnown) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown if (!p.CanUse(category)) { p.Refuse(category); return; } if (authorization != null || pending.HasValue || recovery.HasValue) { p.Report("busy"); return; } if (!LandingPolicy.IsValid(target.x, target.y, target.z)) { p.Report("unsafe"); return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { p.Report("unavailable"); return; } if (((Character)localPlayer).IsDead()) { p.Report("dead"); return; } if (((Character)localPlayer).IsTeleporting()) { p.Report("busy"); return; } TeleportActorFacts val = Actor(); if (val == null) { p.Report("unavailable"); return; } if (!val.CooldownReady) { p.Report("rejected"); return; } SessionSnapshot session = p.Integration.Session; generation = session.Generation; Vector3 position = ((Component)localPlayer).transform.position; request = new TeleportRequest(Guid.NewGuid().ToString("N"), category, destination, target.x, target.y, target.z, lastKnown); lifecycle = new PendingTeleport(val, request, generation, p.Integration.MonotonicTime, position.x, position.y, position.z); cancellation = new CancellationTokenSource(); authorization = p.Integration.AuthorizeAsync(request, cancellation.Token); p.Report("authorizing"); } private void CancelAuthorization() { cancellation?.Cancel(); PendingTeleport? obj = lifecycle; if (obj != null) { obj.Cancel(); } authorization = null; cancellation?.Dispose(); cancellation = null; request = null; } internal void Dispose() { CancelAuthorization(); pending = null; recovery = null; grants.Reset(); } private void Acknowledge(TeleportGrant grant, bool accepted) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown p.Integration.CompleteAsync(new TeleportCompletion(grant.RequestId, grant.GrantId, accepted), CancellationToken.None); } private void PumpAuthorization() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Invalid comparison between Unknown and I4 //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Invalid comparison between Unknown and I4 //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Invalid comparison between Unknown and I4 //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Invalid comparison between Unknown and I4 //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) SessionSnapshot session = p.Integration.Session; if (generation != session.Generation) { CancelAuthorization(); pending = null; recovery = null; lifecycle = null; grants.Reset(); generation = session.Generation; } else { if (authorization == null) { return; } if (!p.CanTeleport || (request != null && !p.CanUse(request.Category))) { string key = ((request != null) ? p.Refusal(request.Category) : p.TeleportRefusal()); CancelAuthorization(); p.Report(key); } else { if (!authorization.IsCompleted) { return; } Task<OperationResult<TeleportGrant>> task = authorization; authorization = null; cancellation?.Dispose(); cancellation = null; if (task.IsFaulted || task.IsCanceled) { PendingTeleport? obj = lifecycle; if (obj != null) { obj.Cancel(); } p.Report("authorityunavailable"); return; } OperationResult<TeleportGrant> result = task.Result; if ((int)result.State != 2 || result.Reply == null) { PendingTeleport? obj2 = lifecycle; if (obj2 != null) { obj2.Cancel(); } p.Report((TeleportRefusals.Is(result.Code) || result.Code == "dead" || result.Code == "busy") ? result.Code : "authorityunavailable"); return; } TeleportGrant reply = result.Reply; TeleportActorFacts val = Actor(); Player localPlayer = Player.m_localPlayer; if (val == null || request == null || lifecycle == null || !Object.op_Implicit((Object)(object)localPlayer)) { Acknowledge(reply, accepted: false); return; } if ((int)reply.Category != 2 && !p.Catalog.TryResolve(reply.DestinationId, out Destination _, out string _)) { lifecycle.Cancel(); Acknowledge(reply, accepted: false); p.Report("unavailable"); return; } Vector3 landing = default(Vector3); ((Vector3)(ref landing))..ctor(reply.X, reply.Y, reply.Z); if (((int)reply.Category == 3 || (int)reply.Category == 5) && !LandingResolver.TryResolve(landing, out landing)) { lifecycle.Cancel(); Acknowledge(reply, accepted: false); p.Report("unsafe"); return; } if (!grants.TrackVerifiedGrant(reply) || !grants.TryConsume(reply, val, p.Integration.MonotonicTime) || !lifecycle.TryAccept(reply, val, session.Generation, p.Integration.MonotonicTime, p.CanUse(reply.Category))) { Acknowledge(reply, accepted: false); p.Report("rejected"); return; } bool flag = ((Character)localPlayer).TeleportTo(landing, ((Component)localPlayer).transform.rotation, true); Acknowledge(reply, flag); if (!flag) { lifecycle.Cancel(); p.Report("rejected"); return; } pending = landing; pendingWorld = p.World; expires = Time.unscaledTime + 30f; p.State.Close(); p.Report("success"); if (p.Options.CloseMap.Value && Object.op_Implicit((Object)(object)Minimap.instance)) { Minimap.instance.SetMapMode((MapMode)1); } } } } internal void UpdateLanding() { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0241: 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_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) PumpAuthorization(); if (recovery.HasValue) { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || p.World != pendingWorld || Time.unscaledTime > expires) { recovery = null; return; } TeleportActorFacts val = Actor(); TeleportTargetFacts val2 = default(TeleportTargetFacts); if (val != null && val.Alive && !val.Teleporting && val.CooldownReady && lifecycle != null && lifecycle.TryRecovery(val, p.Integration.Session.Generation, p.Integration.MonotonicTime, ref val2)) { ((Character)localPlayer).TeleportTo(new Vector3(val2.X, val2.Y, val2.Z), ((Component)localPlayer).transform.rotation, true); recovery = null; p.Report("unsafe"); } } else { if (!pending.HasValue) { return; } Player localPlayer2 = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer2) || p.World != pendingWorld || Time.unscaledTime > expires) { pending = null; } else { if (((Character)localPlayer2).IsTeleporting()) { return; } Vector3 landing = pending.Value; pending = null; if (((Character)localPlayer2).IsDead() || Vector2.Distance(new Vector2(landing.x, landing.z), new Vector2(((Component)localPlayer2).transform.position.x, ((Component)localPlayer2).transform.position.z)) > 2f || !Object.op_Implicit((Object)(object)ZNetScene.instance) || !ZNetScene.instance.IsAreaReady(landing)) { return; } int mask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); RaycastHit val3 = default(RaycastHit); if (!Physics.Raycast(landing + Vector3.up * 2f, Vector3.down, ref val3, 2000f, mask, (QueryTriggerInteraction)1) && !Physics.Raycast(landing + Vector3.up * 1000f, Vector3.down, ref val3, 2000f, mask, (QueryTriggerInteraction)1)) { Recover(); return; } landing.y = LandingPolicy.CorrectHeight(landing.y, ((RaycastHit)(ref val3)).point.y, 30f); if (!LandingResolver.Clear(landing, ((RaycastHit)(ref val3)).normal.y) && !LandingResolver.TryResolve(landing, out landing)) { Recover(); return; } ((Component)localPlayer2).transform.position = landing; Rigidbody component = ((Component)localPlayer2).GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.position = landing; component.linearVelocity = Vector3.zero; } AccessTools.Field(typeof(Character), "m_maxAirAltitude")?.SetValue(localPlayer2, landing.y); } } } private void Recover() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) recovery = Vector3.zero; expires = Time.unscaledTime + 30f; p.Report("unsafe"); } } internal static class LandingResolver { internal static bool Clear(Vector3 pos, float normalY) { //IL_002d: 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_0032: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_00a5: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; CapsuleCollider val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<CapsuleCollider>() : null); Vector3 val2 = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).transform.lossyScale : Vector3.one); float num = (Object.op_Implicit((Object)(object)val) ? (val.radius * Mathf.Max(val2.x, val2.z)) : 0.4f); float num2 = (Object.op_Implicit((Object)(object)val) ? Mathf.Max(val.height * val2.y, num * 2f) : 1.8f); Vector3 val3 = pos + (Object.op_Implicit((Object)(object)val) ? Vector3.Scale(val.center, val2) : (Vector3.up * 0.9f)); Vector3 val4 = Vector3.up * (num2 * 0.5f - num); int mask = LayerMask.GetMask(new string[8] { "Default", "static_solid", "Default_small", "piece", "terrain", "character", "character_net", "character_ghost" }); bool flag = false; Collider[] array = Physics.OverlapCapsule(val3 - val4, val3 + val4, num, mask, (QueryTriggerInteraction)1); foreach (Collider val5 in array) { if (!Object.op_Implicit((Object)(object)localPlayer) || !((Component)val5).transform.IsChildOf(((Component)localPlayer).transform)) { flag = true; break; } } return LandingPolicy.Clear(Object.op_Implicit((Object)(object)ZNetScene.instance) && ZNetScene.instance.IsAreaReady(pos), normalY, !flag, pos.y <= 30.61f); } internal static bool TryResolve(Vector3 target, out Vector3 landing) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) landing = target; if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !ZNetScene.instance.IsAreaReady(target)) { return false; } int mask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); float[] array = new float[2] { 5f, 8f }; RaycastHit val2 = default(RaycastHit); foreach (float num in array) { for (int j = 0; j < 8; j++) { float num2 = (float)j * MathF.PI / 4f; Vector3 val = target + new Vector3(Mathf.Cos(num2) * num, 0f, Mathf.Sin(num2) * num); if (Physics.Raycast(val + Vector3.up * 80f, Vector3.down, ref val2, 180f, mask, (QueryTriggerInteraction)1) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Ship>())) { val.y = Mathf.Max(((RaycastHit)(ref val2)).point.y, 30f) + 0.6f; if (Clear(val, ((RaycastHit)(ref val2)).normal.y)) { landing = val; return true; } } } } return false; } } internal static class TombstoneHintsFeature { private static readonly int causeKey = StringExtensionMethods.GetStableHashCode("JevMods_Cause"); private static readonly int killerKey = StringExtensionMethods.GetStableHashCode("JevMods_Killer"); private static readonly int dayKey = StringExtensionMethods.GetStableHashCode("JevMods_Day"); private static readonly FieldRef<TombStone, ZNetView> nview = AccessTools.FieldRefAccess<TombStone, ZNetView>("m_nview"); private static readonly FieldRef<Character, HitData> lastHit = AccessTools.FieldRefAccess<Character, HitData>("m_lastHit"); private static readonly MethodInfo? currentDay = AccessTools.Method(typeof(EnvMan), "GetCurrentDay", (Type[])null, (Type[])null); private static bool? steppedAside; private static bool SteppedAside(Plugin p) { if (!steppedAside.HasValue) { steppedAside = TombstoneHints.StepsAside((IEnumerable<string>)Chainloader.PluginInfos.Keys); if (steppedAside.Value) { p.Integration.ReportStepAside("tombstone_hints", "JevMods.BetterTombstoneHints", "BetterTombstoneHints"); } } return steppedAside.Value; } internal static bool Active() { Plugin instance = Plugin.Instance; if ((Object)(object)instance != (Object)null && instance.Options != null && instance.Options.Enabled.Value && instance.Options.TombstoneHints.Value) { return !SteppedAside(instance); } return false; } internal static bool HasZdo(TombStone tombstone) { ZNetView val = nview.Invoke(tombstone); if ((Object)(object)val != (Object)null) { return val.IsValid(); } return false; } private static string Localize(string text) { if (Localization.instance == null) { return text; } return Localization.instance.Localize(text); } internal static void Write(TombStone tombstone) { ZNetView val = nview.Invoke(tombstone); Player localPlayer = Player.m_localPlayer; if (!((Object)(object)val == (Object)null) && val.IsValid() && val.IsOwner() && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)EnvMan.instance == (Object)null)) { int num = ((currentDay?.Invoke(EnvMan.instance, null) is int num2) ? num2 : 0); HitData val2 = lastHit.Invoke((Character)(object)localPlayer); Character val3 = ((val2 != null) ? val2.GetAttacker() : null); Player val4 = (Player)(object)((val3 is Player) ? val3 : null); string text = ((val4 != null) ? val4.GetPlayerName() : (((Object)(object)val3 != (Object)null) ? val3.m_name : "")); TombstoneNote val5 = TombstoneHints.Death(((object)Unsafe.As<HitType, HitType>(ref val2?.m_hitType)/*cast due to .constrained prefix*/).ToString(), (object)val3, val3 is Player, (Object)(object)val3 != (Object)null && val3.IsBoss(), text, num); ZDO zDO = val.GetZDO(); zDO.Set(causeKey, val5.Cause); zDO.Set(killerKey, val5.Killer); zDO.Set(dayKey, val5.Day, false); } } internal static string? Read(TombStone tombstone) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown ZNetView val = nview.Invoke(tombstone); if ((Object)(object)Plugin.Instance == (Object)null || (Object)(object)val == (Object)null || !val.IsValid()) { return null; } ZDO zDO = val.GetZDO(); string text = zDO.GetString(causeKey, ""); if (text.Length == 0) { return null; } TombstoneNote val2 = new TombstoneNote(text, zDO.GetString(killerKey, ""), zDO.GetInt(dayKey, 0)); string text2 = ((Localization.instance != null) ? Localization.instance.Localize("$msg_newday", new string[1] { val2.Day.ToString(CultureInfo.InvariantCulture) }) : ""); return TombstoneHints.Render(val2, (Func<string, string>)Localize, text2); } } internal sealed class TombstoneNameplate : MonoBehaviour { private TombStone? tombstone; private TextWrappingModes wrapping; private float next; private bool shown; internal void Initialize(TombStone owner) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) tombstone = owner; wrapping = owner.m_worldText.textWrappingMode; } private void Update() { if ((Object)(object)tombstone == (Object)null || Time.time < next) { return; } next = Time.time + 0.5f; try { string text = (TombstoneHintsFeature.Active() ? TombstoneHintsFeature.Read(tombstone) : null); if (text == null) { if (shown) { Restore(); shown = false; } return; } tombstone.m_worldText.textWrappingMode = (TextWrappingModes)0; if (Readable()) { Show(tombstone.GetOwnerName() + "\n" + text); shown = true; } } catch (Exception error) { ((Behaviour)this).enabled = false; Plugin.Instance?.Error(error); } } private bool Readable() { if ((Object)(object)tombstone != (Object)null) { return TombstoneHintsFeature.HasZdo(tombstone); } return false; } private void OnDestroy() { if (shown && Readable()) { Restore(); } } private void Restore() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)tombstone == (Object)null)) { tombstone.m_worldText.textWrappingMode = wrapping; if (Readable()) { Show(tombstone.GetOwnerName()); } } } private void Show(string text) { if ((Object)(object)tombstone != (Object)null && tombstone.m_worldText.text != text) { tombstone.m_worldText.text = text; } } } [HarmonyPatch] internal static class TombstonePatches { [HarmonyPatch(typeof(TombStone), "Setup")] [HarmonyPostfix] private static void Setup(TombStone __instance) { try { if (TombstoneHintsFeature.Active()) { TombstoneHintsFeature.Write(__instance); } } catch (Exception error) { Plugin.Instance?.Error(error); } } [HarmonyPatch(typeof(TombStone), "Start")] [HarmonyPostfix] private static void Start(TombStone __instance) { try { if ((Object)(object)Plugin.Instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<TombstoneNameplate>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<TombstoneNameplate>().Initialize(__instance); } } catch (Exception error) { Plugin.Instance?.Error(error); } } [HarmonyPatch(typeof(TombStone), "GetHoverText")] [HarmonyPostfix] private static void GetHoverText(TombStone __instance, ref string __result) { try { if (__result.Length != 0 && TombstoneHintsFeature.Active()) { string text = TombstoneHintsFeature.Read(__instance); if (text != null) { __result = TombstoneHints.Insert(__result, text); } } } catch (Exception error) { Plugin.Instance?.Error(error); } } } internal static class TombstonePinCleanup { internal sealed class Retrieval { internal TombStone Tomb; internal Container Container; internal Inventory Inventory; internal Player Player; internal Game Game; internal Minimap Map; internal ZDO Zdo; internal long World; internal long PlayerId; internal long Generation; internal long Ticks; internal Vector3 Original; internal int Day; internal bool PinMetadata; } private static readonly FieldRef<TombStone, ZNetView> tombView = AccessTools.FieldRefAccess<TombStone, ZNetView>("m_nview"); private static readonly FieldRef<InventoryGui, Container> currentContainer = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer"); private static readonly FieldRef<InventoryGui, Inventory> dragInventory = AccessTools.FieldRefAccess<InventoryGui, Inventory>("m_dragInventory"); private static readonly FieldRef<InventoryGui, GameObject> dragObject = AccessTools.FieldRefAccess<InventoryGui, GameObject>("m_dragGo"); private static readonly FieldRef<Minimap, List<PinData>> mapPins = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins"); private static readonly MethodInfo? getDay = AccessTools.Method(typeof(EnvMan), "GetDay", new Type[1] { typeof(double) }, (Type[])null); private static int removed; private static string lastResult = "idle"; private static bool Enabled { get { Plugin? instance = Plugin.Instance; if (instance == null) { return false; } return instance.Options?.Enabled.Value == true; } } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static Retrieval? Capture(TombStone tomb, bool requireItems) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)tomb) || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)Game.instance) || !Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.GetWorld() == null || ZNet.instance.IsDedicated()) { return null; } Player localPlayer = Player.m_localPlayer; Game instance = Game.instance; PlayerProfile playerProfile = instance.GetPlayerProfile(); ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>(); ZNetView val = tombView.Invoke(tomb); Container component2 = ((Component)tomb).GetComponent<Container>(); long worldUID = ZNet.instance.GetWorldUID(); long playerID = localPlayer.GetPlayerID(); if (((Character)localPlayer).IsDead() || playerID == 0L || playerProfile == null || playerProfile.GetPlayerID() != playerID || worldUID == 0L || !Plugin.Session.AuthorityReady || Plugin.Session.WorldId != worldUID || !Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner() || !Object.op_Implicit((Object)(object)val) || !val.IsValid() || !val.IsOwner() || !Object.op_Implicit((Object)(object)component2)) { return null; } ZDO zDO = val.GetZDO(); Inventory inventory = component2.GetInventory(); if (zDO == null || zDO.GetLong(ZDOVars.s_owner, 0L) != playerID || inventory == null || (requireItems && inventory.NrOfItems() == 0)) { return null; } long num = zDO.GetLong(ZDOVars.s_timeOfDeath, 0L); Vector3 val2 = default(Vector3); int day = -1; bool pinMetadata = false; if (Object.op_Implicit((Object)(object)EnvMan.instance) && num > 0 && num <= DateTime.MaxValue.Ticks && zDO.GetVec3(ZDOVars.s_spawnPoint, ref val2) && Finite(val2.x) && Finite(val2.y) && Finite(val2.z) && getDay != null) { pinMetadata = getDay.Invoke(EnvMan.instance, new object[1] { (double)num / 10000000.0 }) is int num2 && (day = num2) >= 0; } return new Retrieval { Tomb = tomb, Container = component2, Inventory = inventory, Player = localPlayer, Game = instance, Map = Minimap.instance, Zdo = zDO, World = worldUID, PlayerId = playerID, Generation = Plugin.Session.Generation, Ticks = num, Original = val2, Day = day, PinMetadata = pinMetadata }; } internal static Retrieval? FromTakeAll(TombStone tomb) { try { return Capture(tomb, requireItems: false); } catch (Exception error) { Plugin.Instance?.Error(error); return null; } } internal static Retrieval? FromGui(InventoryGui gui, InventoryGrid? grid = null, ItemData? item = null, Modifier? modifier = null) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Invalid comparison between Unknown and I4 try { Container val = currentContainer.Invoke(gui); if (!Object.op_Implicit((Object)(object)val)) { return null; } TombStone component = ((Component)val).GetComponent<TombStone>(); if (!Object.op_Implicit((Object)(object)component)) { return null; } Retrieval retrieval = Capture(component, requireItems: true); if (retrieval == null || retrieval.Container != val) { return null; } if ((Object)(object)grid == (Object)null) { return retrieval; } Inventory inventory = grid.GetInventory(); if (Object.op_Implicit((Object)(object)dragObject.Invoke(gui))) { return (dragInventory.Invoke(gui) == retrieval.Inventory && inventory == ((Humanoid)retrieval.Player).GetInventory()) ? retrieval : null; } return ((int)modifier.GetValueOrDefault() == 2 && item != null && inventory == retrieval.Inventory) ? retrieval : null; } catch (Exception error) { Plugin.Instance?.Error(error); return null; } } internal static void Complete(Retrieval? capture, bool original) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Invalid comparison between Unknown and I4 //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) if (capture == null || !original) { return; } try { Retrieval retrieval = Capture(capture.Tomb, requireItems: false); if (retrieval == null || retrieval.Player != capture.Player || retrieval.Game != capture.Game || retrieval.Container != capture.Container || retrieval.Inventory != capture.Inventory || retrieval.Zdo != capture.Zdo || retrieval.World != capture.World || retrieval.PlayerId != capture.PlayerId || retrieval.Generation != capture.Generation || retrieval.Ticks != capture.Ticks) { lastResult = "scope-changed"; return; } if (retrieval.Inventory.NrOfItems() != 0) { lastResult = "items-remain"; return; } NotifyFoodRetrieved(retrieval); if (!Enabled || !Object.op_Implicit((Object)(object)retrieval.Map) || retrieval.Map != capture.Map || !retrieval.PinMetadata || !capture.PinMetadata || retrieval.Day != capture.Day || !((Vector3)(ref retrieval.Original)).Equals(capture.Original)) { lastResult = "pin-unavailable"; return; } PinData[] array = mapPins.Invoke(retrieval.Map).ToArray(); List<DeathPinCandidate> list = new List<DeathPinCandidate>(array.Length); PinData[] array2 = array; foreach (PinData val in array2) { bool flag = ((PlatformUserID)(ref val.m_author)).IsValid && (PlatformManager.DistributionPlatform == null || val.m_author != ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID); list.Add(new DeathPinCandidate(val.m_pos.x, val.m_pos.z, val.m_name, val.m_save, (int)val.m_type == 4, val.m_ownerID, flag)); } int num = DeathPinCleanup.FindUnique((IReadOnlyList<DeathPinCandidate>)list, retrieval.Original.x, retrieval.Original.z, retrieval.Day, retrieval.PlayerId); if (num < 0) { lastResult = "no-unique-pin"; return; } PinData val2 = array[num]; if (!mapPins.Invoke(retrieval.Map).Contains(val2)) { lastResult = "pin-changed"; return; } retrieval.Map.RemovePin(val2); removed++; lastResult = "removed"; } catch (Exception error) { lastResult = "error"; Plugin.Instance?.Error(error); } } private static void NotifyFoodRetrieved(Retrieval now) { try { CapabilityRegistry capabilities = Plugin.Services.Capabilities; IReadOnlyList<CapabilityMetadata> readOnlyList = capabilities.Providers("meadworks.larder.food.retrieved"); Action<long, long, string> action = default(Action<long, long, string>); if (readOnlyList.Count == 1 && readOnlyList[0].Owner == "com.meadworks.larder" && capabilities.TryResolve<Action<long, long, string>>("meadworks.larder.food.retrieved", new Version(1, 0), ref action)) { action(now.World, now.PlayerId, ((object)Unsafe.As<ZDOID, ZDOID>(ref now.Zdo.m_uid)/*cast due to .constrained prefix*/).ToString()); } } catch (Exception error) { Plugin.Instance?.Error(error); } } internal static object Status() { return new { enabled = Enabled, removed = removed, lastResult = lastResult }; } } [HarmonyPatch(typeof(TombStone), "OnTakeAllSuccess")] internal static class TombstonePinTakeAllPatch { [HarmonyPrefix] private static void Before(TombStone __instance, out TombstonePinCleanup.Retrieval? __state) { __state = TombstonePinCleanup.FromTakeAll(__instance); } [HarmonyPostfix] private static void After(TombstonePinCleanup.Retrieval? __state, bool __runOriginal) { TombstonePinCleanup.Complete(__state, __runOriginal); } } [HarmonyPatch(typeof(InventoryGui), "OnTakeAll")] internal static class TombstonePinGuiTakeAllPatch { [HarmonyPrefix] private static void Before(InventoryGui __instance, out TombstonePinCleanup.Retrieval? __state) { __state = TombstonePinCleanup.FromGui(__instance); } [HarmonyPostfix] private static void After(TombstonePinCleanup.Retrieval? __state, bool __runOriginal) { TombstonePinCleanup.Complete(__state, __runOriginal); } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class TombstonePinGuiTransferPatch { [HarmonyPrefix] private static void Before(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod, out TombstonePinCleanup.Retrieval? __state) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) __state = TombstonePinCleanup.FromGui(__instance, grid, item, mod); } [HarmonyPostfix] private static void After(TombstonePinCleanup.Retrieval? __state, bool __runOriginal) { TombstonePinCleanup.Complete(__state, __runOriginal); } } } namespace Wayfarer.Core { public static class MeadworksIntegration { public static ProductMetadata Metadata() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown return new ProductMetadata("com.meadworks.wayfarer", "Wayfarer", new Version("0.5.13"), new Version(0, 1), new Version(0, 1), (MultiplayerPolicy)2, "Mischief"); } public static UiDescriptor Ui() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown return new UiDescriptor("Wayfarer", "Meadworks", "M"); } } } namespace Wayfarer.CrucibleIntegration { public sealed class CrucibleServices : IDisposable { private readonly ProductRegistration registration; private MeadworksTranslations? localization; private readonly MeadworksLog log; private TeleportAuthorityAdapter? authority; private ConfigEntry<bool> allowTeleport; private ConfigEntry<bool> allowBed; private ConfigEntry<bool> stones; private ConfigEntry<bool> map; private ConfigEntry<bool> boat; private ConfigEntry<bool> grave; private ConfigEntry<bool> player; private readonly PerFrame<bool> travelCheats; private static readonly string ProductId = MeadworksIntegration.Metadata().Id; public SessionSnapshot Session => Plugin.Session; public TeleportPolicy EffectivePolicy => new TeleportPolicy(allowTeleport.Value, allowBed.Value, stones.Value, map.Value, boat.Value, grave.Value, player.Value, PlayerCategories()); public bool TravelCheats => travelCheats.Value; public double MonotonicTime => SessionIntegration.Now; private IReadOnlyCollection<Category> PlayerCategories() { List<Category> list = new List<Category>(); if (MeadworksMischief.PlayersMay((ConfigEntryBase)(object)stones)) { list.Add((Category)1); } if (MeadworksMischief.PlayersMay((ConfigEntryBase)(object)map)) { list.Add((Category)2); } if (MeadworksMischief.PlayersMay((ConfigEntryBase)(object)boat)) { list.Add((Category)3); } if (MeadworksMischief.PlayersMay((ConfigEntryBase)(object)grave)) { list.Add((Category)4); } if (MeadworksMischief.PlayersMay((ConfigEntryBase)(object)player)) { list.Add((Category)5); } return list; } public CrucibleServices(ProductRegistration registration, BepInPlugin metadata, ConfigFile config, ManualLogSource logger, Func<NavigationSnapshot> navigation) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown this.registration = registration; travelCheats = new PerFrame<bool>((Func<int>)(() => Time.frameCount), (Func<bool>)(() => MeadworksMischief.Decide(ProductId, (MischiefCategory)4).Allowed)); log = MeadworksLog.For(logger, "Wayfarer"); try { allowTeleport = Bind(config, "Server", "AllowTeleport", defaultValue: true, "Master switch for every Wayfarer destination on this server.", (ConfigScope)1); allowBed = Bind(config, "Server", "AllowBed", defaultValue: true, "Allow Bed teleport for every player.", (ConfigScope)1); stones = MeadworksConfig.BindCheat<bool>(config, "Cheats", "TeleportToStones", false, "Travel cheat: teleport to discovered Sacrificial Stones. Admins only on a server unless the admin lets players use it.", (MischiefCategory)4, (AcceptableValueBase)null); map = MeadworksConfig.BindCheat<bool>(config, "Cheats", "TeleportAnywhere", false, "Travel cheat: teleport to any clicked map point. Admins only on a server unless the admin lets players use it.", (MischiefCategory)4, (AcceptableValueBase)null); boat = MeadworksConfig.BindCheat<bool>(config, "Cheats", "TeleportToBoat", false, "Travel cheat: teleport to a seen boat. Admins only on a server unless the admin lets players use it.", (MischiefCategory)4, (AcceptableValueBase)null); grave = MeadworksConfig.BindCheat<bool>(config, "Cheats", "TeleportToGrave", false, "Travel cheat: teleport to your own grave. Admins only on a server unless the admin lets players use it.", (MischiefCategory)4, (AcceptableValueBase)null); player = MeadworksConfig.BindCheat<bool>(config, "Cheats", "TeleportToPlayer", false, "Travel cheat: teleport to a player who shares their map position. Admins only on a server unless the admin lets players use it.", (MischiefCategory)4, (AcceptableValueBase)null); authority = new TeleportAuthorityAdapter(registration, () => EffectivePolicy); if (MeadworksHeadless.AllowsUi) { registration.AddUi(MeadworksIntegration.Ui()); } NavigationProvider val = new NavigationProvider(navigation); registration.AddCapability<IWayfarerNavigation>("meadworks.navigation", new Version(1, 0), (IWayfarerNavigation)(object)val); registration.AddCapability<IWayfarerNavigation>("meadworks.mischief", new Version(1, 0), (IWayfarerNavigation)(object)val); if (MeadworksHeadless.AllowsUi) { localization = MeadworksTranslations.Register(metadata, new ProductTranslations("wayfarer", EmbeddedCatalog()), (string)null, logger); } } catch { Dispose(); throw; } } public ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T defaultValue, ConfigDescription description) { return MeadworksConfig.Bind<T>(config, section, key, defaultValue, description); } public ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T defaultValue, string description, ConfigScope scope) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return MeadworksConfig.Bind<T>(config, section, key, defaultValue, description, scope, (AcceptableValueBase)null); } public Task<OperationResult<TeleportGrant>> AuthorizeAsync(TeleportRequest request, CancellationToken cancellation) { return Plugin.RequestClient.InvokeAsync<TeleportRequest, TeleportGrant>("meadworks.wayfarer.teleport.authorize", request, cancellation); } public Task<OperationResult<bool>> CompleteAsync(TeleportCompletion completion, CancellationToken cancellation) { return Plugin.RequestClient.InvokeAsync<TeleportCompletion, bool>("meadworks.wayfarer.teleport.complete", completion, cancellation); } private static IReadOnlyDictionary<string, string> EmbeddedCatalog() { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); Assembly assembly = typeof(CrucibleServices).Assembly; foreach (string item in MeadworksLanguages.Supported) { using Stream stream = assembly.GetManifestResourceStream("Wayfarer.localization." + item + ".json"); if (stream != null) { using StreamReader streamReader = new StreamReader(stream); dictionary.Add(item, streamReader.ReadToEnd()); } } return dictionary; } public string Text(string key, string language) { MeadworksTranslations? obj = localization; return ((obj != null) ? obj.Translations.Text(key, language) : null) ?? key; } public void Update() { MeadworksTranslations? obj = localization; if (obj != null) { obj.Update(); } } public void ReportStepAside(string moduleId, string sourceGuid, string sourceName) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown MeadworksStepAside.ReportModule(ProductId, moduleId, new SourceMod(sourceGuid, sourceName), "wayfarer", (string)null); } public void Info(string message) { log.Info(message); } public void Error(object error) { log.Error(error); } public void Dispose() { authority?.Dispose(); MeadworksTranslations? obj = localization; if (obj != null) { obj.Dispose(); } authority = null; localization = null; } } internal static class SessionIntegration { internal const string Authorize = "meadworks.wayfarer.teleport.authorize"; internal const string Complete = "meadworks.wayfarer.teleport.complete"; private static readonly Stopwatch clock = Stopwatch.StartNew(); internal static double Now => clock.Elapsed.TotalSeconds; internal static byte[] Write(Action<BinaryWriter> write) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true), leaveOpen: true); write(binaryWriter); binaryWriter.Flush(); if (memoryStream.Length > 16384) { throw new InvalidDataException(); } return memoryStream.ToArray(); } internal static T Read<T>(byte[] bytes, Func<BinaryReader, T> read) { if (bytes.Length > 16384) { throw new InvalidDataException(); } using MemoryStream memoryStream = new MemoryStream(bytes, writable: false); using BinaryReader arg = new BinaryReader(memoryStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true)); T result = read(arg); if (memoryStream.Position != memoryStream.Length) { throw new InvalidDataException(); } return result; } internal static string Text(BinaryReader reader) { string text = reader.ReadString(); if (string.IsNullOrWhiteSpace(text) || text.Length > 128 || text.IndexOfAny(new char[3] { '\0', '\r', '\n' }) >= 0) { throw new InvalidDataException(); } return text; } } internal sealed class TeleportCodec : IOperationCodec<TeleportRequest, TeleportGrant> { public byte[] EncodeRequest(TeleportRequest r) { return SessionIntegration.Write(delegate(BinaryWriter w) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown w.Write(r.RequestId); w.Write((int)r.Category); w.Write(r.DestinationId); w.Write(r.X); w.Write(r.Y); w.Write(r.Z); w.Write(r.IsLastKnown); }); } public TeleportRequest DecodeRequest(byte[] bytes) { return SessionIntegration.Read(bytes, (Func<BinaryReader, TeleportRequest>)((BinaryReader r) => new TeleportRequest(SessionIntegration.Text(r), (Category)r.ReadInt32(), SessionIntegration.Text(r), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadBoolean()))); } public byte[] EncodeReply(TeleportGrant g) { return SessionIntegration.Write(delegate(BinaryWriter w) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected I4, but got Unknown w.Write(g.ActorId); w.Write(g.WorldId); w.Write(g.SessionId); w.Write(g.RequestId); w.Write(g.GrantId); w.Write((int)g.Category); w.Write(g.DestinationId); w.Write(g.X); w.Write(g.Y); w.Write(g.Z); w.Write(Math.Max(0.0, Math.Min(10.0, g.ExpiresAt - SessionIntegration.Now))); }); } public TeleportGrant DecodeReply(byte[] bytes) { return SessionIntegration.Read(bytes, (Func<BinaryReader, TeleportGrant>)delegate(BinaryReader r) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown string text = SessionIntegration.Text(r); long num = r.ReadInt64(); string text2 = SessionIntegration.Text(r); string text3 = SessionIntegration.Text(r); string text4 = SessionIntegration.Text(r); Category val = (Category)r.ReadInt32(); string text5 = SessionIntegration.Text(r); float num2 = r.ReadSingle(); float num3 = r.ReadSingle(); float num4 = r.ReadSingle(); double num5 = r.ReadDouble(); if (double.IsNaN(num5) || double.IsInfinity(num5) || num5 < 0.0 || num5 > 10.0) { throw new InvalidDataException(); } return new TeleportGrant(text, num, text2, text3, text4, val, text5, num2, num3, num4, SessionIntegration.Now + num5); }); } } internal sealed class CompletionCodec : IOperationCodec<TeleportCompletion, bool> { public byte[] EncodeRequest(TeleportCompletion c) { return SessionIntegration.Write(delegate(BinaryWriter w) { w.Write(c.RequestId); w.Write(c.GrantId); w.Write(c.Accepted); }); } public TeleportCompletion DecodeRequest(byte[] bytes) { return SessionIntegration.Read(bytes, (Func<BinaryReader, TeleportCompletion>)(