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 WhereTheCrowFlies v1.2.1
plugins/WhereTheCrowFlies.dll
Decompiled 17 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.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SharedUI; using UnityEngine; using WhereTheCrowFlies.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WhereTheCrowFlies { [BepInPlugin("com.raveniron.wherethecrowflies", "WhereTheCrowFlies", "1.2.1")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.raveniron.wherethecrowflies"; public const string PluginName = "WhereTheCrowFlies"; public const string PluginVersion = "1.2.1"; public static ManualLogSource Log; public static ConfigEntry<bool> EnableReporting; public static ConfigEntry<float> FullSyncIntervalSeconds; public static ConfigEntry<KeyCode> TitlePanelKey; private readonly Harmony _harmony = new Harmony("com.raveniron.wherethecrowflies"); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; EnableReporting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableReporting", true, "Send owner-side combat reports, world telemetry, crafting, building, harvesting, consumption, and player stats to servers running TheRavensCall."); FullSyncIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FullSyncIntervalSeconds", 300f, "How often (in seconds) to broadcast a full absolute snapshot of all vanilla player stats and skills (StatSnapshot/SkillSnapshot). These are idempotent full-state resyncs, not time-sensitive deltas, so this can be turned up if 10-second combat/damage batching feels like enough network chatter on its own — a full snapshot also always fires immediately on spawn regardless of this setting."); TitlePanelKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "TitlePanelKey", (KeyCode)0, "Key that opens the title panel (the same panel the /titles command opens). None = command only. Read through the game's own input layer (ZInput), so it works with Valheim 1.0's input system."); try { _harmony.PatchAll(); Log.LogInfo((object)"[WhereTheCrowFlies] All patches applied."); } catch (Exception ex) { Log.LogError((object)("[WhereTheCrowFlies] Harmony PatchAll failed: " + ex.Message)); } ((Component)this).gameObject.AddComponent<TelemetryTicker>(); Log.LogInfo((object)"WhereTheCrowFlies 1.2.1 loaded."); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } } internal class TelemetryTicker : MonoBehaviour { private int _onGuiThrows; private void Update() { TelemetryAccumulator.Tick(Time.deltaTime); TitlePicker.Tick(Time.deltaTime); TitlePanel.Tick(); } private void OnGUI() { try { TitlePanel.Draw(); } catch (Exception arg) { if (_onGuiThrows++ < 3) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)string.Format("[{0}] OnGUI threw: {1}", "WhereTheCrowFlies", arg)); } } } } } } namespace WhereTheCrowFlies.Patches { public static class EventType { public const byte Kill = 1; public const byte Death = 2; public const byte DamageDefenseBatch = 3; public const byte FishCatch = 4; public const byte Building = 5; public const byte Crafting = 6; public const byte Harvesting = 7; public const byte Consumables = 8; public const byte WorldEvent = 9; public const byte StatSync = 10; public const byte StatSnapshot = 11; public const byte SkillSnapshot = 12; public const byte TitleRequest = 13; } internal struct SkillEntry { public short SkillId; public float Level; public float Progress; } public static class BuildingAction { public const byte Placed = 1; public const byte Removed = 2; public const byte Repaired = 3; } public static class CraftingAction { public const byte Crafted = 1; public const byte Upgraded = 2; public const byte Repaired = 3; } public static class HarvestSourceType { public const byte Foraged = 1; public const byte Crop = 2; public const byte Beehive = 3; public const byte SapCollector = 4; } public static class ConsumableType { public const byte Food = 1; public const byte PotionOrMead = 2; public const byte Other = 3; } public static class TitleOp { public const byte List = 1; public const byte Set = 2; public const byte Clear = 3; } internal static class TelemetrySender { private const string RpcNameV1 = "RavensCall_CombatReport_V1"; private const string RpcNameV2 = "RavensCall_EventReport_V2"; internal const string RpcNameTitleReply = "RavensCall_TitleReply_V1"; private static bool IsConnected() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if ((Object)(object)ZNet.instance != (Object)null && ZRoutedRpc.instance != null) { return (int)ZNet.GetConnectionStatus() == 2; } return false; } public static string GetBiomeName(Vector3 pos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_005c: 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_0062: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Player.m_localPlayer != (Object)null) { return ((object)Player.m_localPlayer.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString(); } if ((Object)(object)EnvMan.instance != (Object)null) { return ((object)EnvMan.instance.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString(); } if (WorldGenerator.instance != null) { return ((object)WorldGenerator.instance.GetBiome(pos)/*cast due to .constrained prefix*/).ToString(); } } catch { } return "Unknown"; } public static string CleanName(string name) { if (string.IsNullOrEmpty(name)) { return ""; } return name.Replace("(Clone)", "").Trim(); } public static void SendV1(byte eventType, Vector3 position, string prefabOrCause, string attackerName, float dmgDealt = 0f, float dmgTaken = 0f) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(1); val.Write(eventType); val.Write(prefabOrCause ?? ""); val.Write(attackerName ?? ""); val.Write(position); val.Write(dmgDealt); val.Write(dmgTaken); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_CombatReport_V1", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendV1 failed: " + ex.Message)); } } } public static void SendKill(string attackerName, string victimPrefab, Vector3 pos, int level, bool isBoss, bool isTamed, string weaponOrDmgType, string biome) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: 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) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)1); val.Write(attackerName ?? ""); val.Write(victimPrefab ?? ""); val.Write(pos); val.Write(level); val.Write(isBoss); val.Write(isTamed); val.Write(weaponOrDmgType ?? ""); val.Write(biome ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); SendV1(1, pos, victimPrefab, attackerName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendKill failed: " + ex.Message)); } } } public static void SendDeath(string victimName, string cause, Vector3 pos, string killerPlayer, string biome) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)2); val.Write(victimName ?? ""); val.Write(cause ?? ""); val.Write(pos); val.Write(killerPlayer ?? ""); val.Write(biome ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); SendV1(2, pos, cause, victimName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendDeath failed: " + ex.Message)); } } } public static void SendDamageDefenseBatch(string playerName, Vector3 pos, float dealtCreatures, float dealtPlayers, float takenCreatures, float takenPlayers, float takenEnv, int hitsDealt, int hitsTaken, int blocks, int parries, float dmgBlocked) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0031: 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) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)3); val.Write(playerName ?? ""); val.Write(pos); val.Write(dealtCreatures); val.Write(dealtPlayers); val.Write(takenCreatures); val.Write(takenPlayers); val.Write(takenEnv); val.Write(hitsDealt); val.Write(hitsTaken); val.Write(blocks); val.Write(parries); val.Write(dmgBlocked); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); float dmgDealt = dealtCreatures + dealtPlayers; float dmgTaken = takenCreatures + takenPlayers + takenEnv; SendV1(3, pos, "", playerName, dmgDealt, dmgTaken); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendDamageDefenseBatch failed: " + ex.Message)); } } } public static void SendFishCatch(string playerName, string fishPrefab, Vector3 pos, int quality, float weight, string biome) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)4); val.Write(playerName ?? ""); val.Write(fishPrefab ?? ""); val.Write(pos); val.Write(quality); val.Write(weight); val.Write(biome ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); SendV1(4, pos, fishPrefab, playerName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendFishCatch failed: " + ex.Message)); } } } public static void SendBuilding(string playerName, string piecePrefab, Vector3 pos, byte action, string category) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)5); val.Write(playerName ?? ""); val.Write(piecePrefab ?? ""); val.Write(pos); val.Write(action); val.Write(category ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendBuilding failed: " + ex.Message)); } } } public static void SendCrafting(string playerName, string itemPrefab, Vector3 pos, byte action, int quality, int amount, string stationName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)6); val.Write(playerName ?? ""); val.Write(itemPrefab ?? ""); val.Write(pos); val.Write(action); val.Write(quality); val.Write(amount); val.Write(stationName ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendCrafting failed: " + ex.Message)); } } } public static void SendHarvesting(string playerName, string resourceName, Vector3 pos, byte sourceType, int amount) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)7); val.Write(playerName ?? ""); val.Write(resourceName ?? ""); val.Write(pos); val.Write(sourceType); val.Write(amount); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendHarvesting failed: " + ex.Message)); } } } public static void SendConsumable(string playerName, string itemPrefab, Vector3 pos, byte itemType, float health, float stamina, float eitr) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)8); val.Write(playerName ?? ""); val.Write(itemPrefab ?? ""); val.Write(pos); val.Write(itemType); val.Write(health); val.Write(stamina); val.Write(eitr); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendConsumable failed: " + ex.Message)); } } } public static void SendWorldEvent(string playerName, string eventName, Vector3 pos, string targetOrDetails, string biome) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { if (IsConnected()) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)9); val.Write(playerName ?? ""); val.Write(eventName ?? ""); val.Write(pos); val.Write(targetOrDetails ?? ""); val.Write(biome ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendWorldEvent failed: " + ex.Message)); } } } public static void SendStatSync(string playerName, Vector3 pos, List<KeyValuePair<short, float>> statPairs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { if (!IsConnected() || statPairs == null || statPairs.Count == 0) { return; } ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)10); val.Write(playerName ?? ""); val.Write(pos); val.Write(statPairs.Count); foreach (KeyValuePair<short, float> statPair in statPairs) { val.Write(statPair.Key); val.Write(statPair.Value); } ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendStatSync failed: " + ex.Message)); } } } public static void SendStatSnapshot(string playerName, Vector3 pos, List<KeyValuePair<short, float>> statPairs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { if (!IsConnected() || statPairs == null || statPairs.Count == 0) { return; } ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)11); val.Write(playerName ?? ""); val.Write(pos); val.Write(statPairs.Count); foreach (KeyValuePair<short, float> statPair in statPairs) { val.Write(statPair.Key); val.Write(statPair.Value); } ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendStatSnapshot failed: " + ex.Message)); } } } public static void SendSkillSnapshot(string playerName, Vector3 pos, List<SkillEntry> skills) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) try { if (!IsConnected() || skills == null || skills.Count == 0) { return; } ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)12); val.Write(playerName ?? ""); val.Write(pos); val.Write(skills.Count); foreach (SkillEntry skill in skills) { val.Write(skill.SkillId); val.Write(skill.Level); val.Write(skill.Progress); } ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendSkillSnapshot failed: " + ex.Message)); } } } public static void SendTitleRequest(byte op, string title) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown try { if (IsConnected() && !((Object)(object)Player.m_localPlayer == (Object)null)) { ZPackage val = new ZPackage(); val.Write(2); val.Write((byte)13); val.Write(Player.m_localPlayer.GetPlayerName()); val.Write(op); val.Write(title ?? ""); ZRoutedRpc.instance.InvokeRoutedRPC("RavensCall_EventReport_V2", new object[1] { val }); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] SendTitleRequest failed: " + ex.Message)); } } } } internal static class TelemetryAccumulator { private class DamageDefenseEntry { public float DealtCreatures; public float DealtPlayers; public float TakenCreatures; public float TakenPlayers; public float TakenEnv; public int HitsDealt; public int HitsTaken; public int Blocks; public int Parries; public float DmgBlocked; public bool HasData { get { if (!(DealtCreatures > 0f) && !(DealtPlayers > 0f) && !(TakenCreatures > 0f) && !(TakenPlayers > 0f) && !(TakenEnv > 0f) && HitsDealt <= 0 && HitsTaken <= 0 && Blocks <= 0 && Parries <= 0) { return DmgBlocked > 0f; } return true; } } public void Clear() { DealtCreatures = 0f; DealtPlayers = 0f; TakenCreatures = 0f; TakenPlayers = 0f; TakenEnv = 0f; HitsDealt = 0; HitsTaken = 0; Blocks = 0; Parries = 0; DmgBlocked = 0f; } } private static readonly Dictionary<string, DamageDefenseEntry> _combatAcc = new Dictionary<string, DamageDefenseEntry>(); private static readonly Dictionary<short, float> _statDeltas = new Dictionary<short, float>(); private const float FlushIntervalSeconds = 10f; private const float FlushCombatThreshold = 500f; private static float _timer; private static float _fullSyncTimer; public static void AddCombatDamage(string playerName, float dealtCreature, float dealtPlayer, float takenCreature, float takenPlayer, float takenEnv) { if (!string.IsNullOrEmpty(playerName)) { if (!_combatAcc.TryGetValue(playerName, out var value)) { value = new DamageDefenseEntry(); _combatAcc[playerName] = value; } value.DealtCreatures += dealtCreature; value.DealtPlayers += dealtPlayer; value.TakenCreatures += takenCreature; value.TakenPlayers += takenPlayer; value.TakenEnv += takenEnv; if (dealtCreature > 0f || dealtPlayer > 0f) { value.HitsDealt++; } if (takenCreature > 0f || takenPlayer > 0f || takenEnv > 0f) { value.HitsTaken++; } if (value.DealtCreatures + value.DealtPlayers + value.TakenCreatures + value.TakenPlayers + value.TakenEnv >= 500f) { FlushCombatEntry(playerName, value); } } } public static void AddBlockDefense(string playerName, bool isParry, float dmgBlocked) { if (!string.IsNullOrEmpty(playerName)) { if (!_combatAcc.TryGetValue(playerName, out var value)) { value = new DamageDefenseEntry(); _combatAcc[playerName] = value; } if (isParry) { value.Parries++; } else { value.Blocks++; } value.DmgBlocked += dmgBlocked; } } public static void AddStatDelta(short statId, float delta) { if (delta != 0f) { if (!_statDeltas.TryGetValue(statId, out var value)) { _statDeltas[statId] = delta; } else { _statDeltas[statId] = value + delta; } } } public static void Tick(float dt) { _timer += dt; if (_timer >= 10f) { _timer -= 10f; if (_timer >= 10f) { _timer = 0f; } foreach (KeyValuePair<string, DamageDefenseEntry> item in _combatAcc) { if (item.Value.HasData) { FlushCombatEntry(item.Key, item.Value); } } if (_statDeltas.Count > 0) { FlushStatDeltas(); } } float num = ((Plugin.FullSyncIntervalSeconds != null) ? Mathf.Max(10f, Plugin.FullSyncIntervalSeconds.Value) : 60f); _fullSyncTimer += dt; if (_fullSyncTimer >= num) { _fullSyncTimer -= num; if (_fullSyncTimer >= num) { _fullSyncTimer = 0f; } if (_statDeltas.Count > 0) { FlushStatDeltas(); } FlushStatSnapshot(); FlushSkillSnapshot(); } } public static void FlushFullBackfill() { if (_statDeltas.Count > 0) { FlushStatDeltas(); } FlushStatSnapshot(); FlushSkillSnapshot(); } private static void FlushStatSnapshot() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Game.instance == (Object)null) { return; } PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile == null) { return; } string playerName = Player.m_localPlayer.GetPlayerName(); Vector3 position = ((Component)Player.m_localPlayer).transform.position; PlayerStats val = ((playerProfile.m_playerStats != null && playerProfile.m_playerStats.Length != 0) ? playerProfile.m_playerStats[0] : null); if (val == null || val.m_stats == null) { return; } List<KeyValuePair<short, float>> list = new List<KeyValuePair<short, float>>(val.m_stats.Count); foreach (KeyValuePair<PlayerStatType, float> stat in val.m_stats) { list.Add(new KeyValuePair<short, float>((short)stat.Key, stat.Value)); } TelemetrySender.SendStatSnapshot(playerName, position, list); } private static void FlushSkillSnapshot() { //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_00c6: 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) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } Skills skills = ((Character)Player.m_localPlayer).GetSkills(); if ((Object)(object)skills == (Object)null) { return; } string playerName = Player.m_localPlayer.GetPlayerName(); Vector3 position = ((Component)Player.m_localPlayer).transform.position; List<SkillEntry> list = new List<SkillEntry>(); foreach (Skill skill in skills.GetSkillList()) { if (skill?.m_info != null) { list.Add(new SkillEntry { SkillId = (short)skill.m_info.m_skill, Level = skill.m_level, Progress = skill.GetLevelPercentage() }); } } TelemetrySender.SendSkillSnapshot(playerName, position, list); } private static void FlushCombatEntry(string playerName, DamageDefenseEntry e) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Vector3 pos = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero); TelemetrySender.SendDamageDefenseBatch(playerName, pos, e.DealtCreatures, e.DealtPlayers, e.TakenCreatures, e.TakenPlayers, e.TakenEnv, e.HitsDealt, e.HitsTaken, e.Blocks, e.Parries, e.DmgBlocked); e.Clear(); } private static void FlushStatDeltas() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } string playerName = Player.m_localPlayer.GetPlayerName(); Vector3 position = ((Component)Player.m_localPlayer).transform.position; List<KeyValuePair<short, float>> list = new List<KeyValuePair<short, float>>(_statDeltas.Count); foreach (KeyValuePair<short, float> statDelta in _statDeltas) { if (statDelta.Value != 0f) { list.Add(statDelta); } } _statDeltas.Clear(); if (list.Count > 0) { TelemetrySender.SendStatSync(playerName, position, list); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class Patch_ConsoleRouting { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Postfix>b__0_0(ConsoleEventArgs args) { Terminal context = args.Context; if (context != null) { context.AddString("[WhereTheCrowFlies] ravenscall runs on the server; the output is in the server console."); } } } private static void Postfix() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //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_0043: Expected O, but got Unknown try { if (Terminal.commands != null && Terminal.commands.ContainsKey("ravenscall")) { return; } object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { Terminal context = args.Context; if (context != null) { context.AddString("[WhereTheCrowFlies] ravenscall runs on the server; the output is in the server console."); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("ravenscall", "Server admin command (TheRavensCall): ravenscall season start [name] | ravenscall season end | ravenscall title <player> [<title>|clear]. Runs on the server; needs admin.", (ConsoleEvent)obj, false, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, true, false); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] console routing stub failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class Patch_TitleCommand { [CompilerGenerated] private static class <>O { public static ConsoleEvent <0>__HandleCommand; public static ConsoleOptionsFetcher <1>__GetTabOptions; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__2_0; internal void <Postfix>b__2_0(ConsoleEventArgs args) { try { TitlePanel.Open(args.Context); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] titles command failed: " + ex.Message)); } TitlePanel.Close("error"); } } } private static bool _registered; private static bool _titlesRegistered; private static void Postfix() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown try { if (!_registered) { if (Terminal.commands != null && Terminal.commands.ContainsKey("title")) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[WhereTheCrowFlies] a 'title' console command is already registered by another mod; the title picker will not run."); } } else { object obj = <>O.<0>__HandleCommand; if (obj == null) { ConsoleEvent val = TitlePicker.HandleCommand; <>O.<0>__HandleCommand = val; obj = (object)val; } object obj2 = <>O.<1>__GetTabOptions; if (obj2 == null) { ConsoleOptionsFetcher val2 = TitlePicker.GetTabOptions; <>O.<1>__GetTabOptions = val2; obj2 = (object)val2; } new ConsoleCommand("title", "Pick which of your earned titles the server shows with your name in its Discord narration, Chronicle log and web dashboard (TheRavensCall 1.7.0+); nothing changes on your in-game nameplate: title (list yours) | title <name> | title clear", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, true, false, false); _registered = true; } } if (_titlesRegistered) { return; } if (Terminal.commands != null && Terminal.commands.ContainsKey("titles")) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[WhereTheCrowFlies] a 'titles' console command is already registered by another mod; the title panel will not open from chat/console (the TitlePanelKey config still will)."); } return; } object obj3 = <>c.<>9__2_0; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { try { TitlePanel.Open(args.Context); } catch (Exception ex2) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[WhereTheCrowFlies] titles command failed: " + ex2.Message)); } TitlePanel.Close("error"); } }; <>c.<>9__2_0 = val3; obj3 = (object)val3; } new ConsoleCommand("titles", "Open the title panel (TheRavensCall 1.7.0+): pick which earned title the server shows with your name.", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); _titlesRegistered = true; } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[WhereTheCrowFlies] title command registration failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class Patch_RegisterTitleReply { private static void Postfix() { try { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.Register<ZPackage>("RavensCall_TitleReply_V1", (Action<long, ZPackage>)TitlePicker.RPC_OnTitleReply); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title reply RPC registration failed: " + ex.Message)); } } } } internal static class TitlePicker { private const float ReplyTimeoutSeconds = 5f; private static Terminal _pendingContext; private static float _pendingSince = -1f; private static List<string> _tabOptions = new List<string>(); internal static bool Send(byte op, string title, Terminal context) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 _pendingContext = context; if ((Object)(object)ZNet.instance == (Object)null || (int)ZNet.GetConnectionStatus() != 2 || ZNet.instance.IsServer()) { Print(context, "Titles are kept by the server; join a server running TheRavensCall 1.7.0 or newer."); if (TitlePanel.IsOpen) { TitlePanel.OnLocal("Titles are kept by the server; join a server running TheRavensCall 1.7.0 or newer."); } return false; } TelemetrySender.SendTitleRequest(op, title); _pendingSince = Time.realtimeSinceStartup; return true; } public static void HandleCommand(ConsoleEventArgs args) { try { string title = ""; byte op; if (args.Length < 2) { op = 1; } else if (string.Equals(args[1], "clear", StringComparison.OrdinalIgnoreCase)) { op = 3; } else { op = 2; title = (args.ArgsAll ?? "").Trim(); } Send(op, title, args.Context); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title command failed: " + ex.Message)); } } } public static void RPC_OnTitleReply(long sender, ZPackage pkg) { try { long num = ((!((Object)(object)ZNet.instance != (Object)null) || ZNet.instance.IsServer()) ? 0 : (ZNet.instance.GetServerPeer()?.m_uid ?? 0)); if (num == 0L || sender != num) { return; } _pendingSince = -1f; if (pkg == null || pkg.Size() == 0) { if (TitlePanel.IsOpen) { TitlePanel.OnLocal("The server answered, but its reply could not be read."); } return; } if (pkg.ReadInt() != 1) { if (TitlePanel.IsOpen) { TitlePanel.OnLocal("The server answered, but its reply could not be read."); } return; } byte kind = pkg.ReadByte(); string text = pkg.ReadString(); List<string> list = null; string active = null; if (pkg.GetPos() < pkg.Size()) { int num2 = Mathf.Clamp(pkg.ReadInt(), 0, 256); list = new List<string>(num2); for (int i = 0; i < num2; i++) { list.Add(pkg.ReadString()); } active = ((pkg.GetPos() < pkg.Size()) ? pkg.ReadString() : ""); } Print(_pendingContext, text); if (list != null) { _tabOptions = list; } TitlePanel.OnReply(kind, text, list, active); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title reply handling failed: " + ex.Message)); } if (TitlePanel.IsOpen) { TitlePanel.OnLocal("The server answered, but its reply could not be read."); } } } public static void Tick(float dt) { try { if (!(_pendingSince < 0f) && !(Time.realtimeSinceStartup - _pendingSince < 5f)) { _pendingSince = -1f; Print(_pendingContext, "No answer from the server — it needs TheRavensCall 1.7.0 or newer, with AcceptClientReports enabled."); if (TitlePanel.IsOpen) { TitlePanel.OnLocal("No answer from the server — it needs TheRavensCall 1.7.0 or newer, with AcceptClientReports enabled."); } } } catch (Exception ex) { _pendingSince = -1f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title timeout hint failed: " + ex.Message)); } } } public static List<string> GetTabOptions() { return _tabOptions; } private static void Print(Terminal context, string text) { string text2 = "[WhereTheCrowFlies] " + text; if ((Object)(object)context == (Object)null) { context = (Terminal)(((object)Chat.instance) ?? ((object)Console.instance)); } if (!((Object)(object)context == (Object)null)) { context.AddString(text2); Chat val = (Chat)(object)((context is Chat) ? context : null); if (val != null) { val.m_hideTimer = 0f; } } } } [HarmonyPatch(typeof(Character), "OnDeath")] internal static class Patch_CharacterDeath { private static void Prefix(Character __instance) { //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_0040: 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_00c6: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && !((Object)(object)__instance == (Object)null) && __instance.IsOwner() && !(__instance is Player)) { Vector3 position = ((Component)__instance).transform.position; string biomeName = TelemetrySender.GetBiomeName(position); HitData lastHit = __instance.m_lastHit; Character obj = ((lastHit != null) ? lastHit.GetAttacker() : null); Player val = (Player)(object)((obj is Player) ? obj : null); if (!((Object)(object)val == (Object)null)) { string playerName = val.GetPlayerName(); string victimPrefab = TelemetrySender.CleanName(((Object)((Component)__instance).gameObject).name); int level = __instance.GetLevel(); bool isBoss = __instance.IsBoss(); bool isTamed = __instance.IsTamed(); string weaponOrDmgType = ((lastHit != null) ? ((object)((DamageTypes)(ref lastHit.m_damage)).GetMajorityDamageType()/*cast due to .constrained prefix*/).ToString() : "Combat"); TelemetrySender.SendKill(playerName, victimPrefab, position, level, isBoss, isTamed, weaponOrDmgType, biomeName); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] OnDeath report failed: " + ex.Message)); } } } internal static string ComputeDeathCause(Player victim, out string killerPlayer) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010f: 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_013b: 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_0155: Unknown result type (might be due to invalid IL or missing references) killerPlayer = ""; try { HitData lastHit = ((Character)victim).m_lastHit; bool flag = false; try { flag = ((Character)victim).IsSwimming() || ((Character)victim).InWater(); } catch { } if (lastHit == null) { return flag ? "drowning" : "a fall"; } Character attacker = lastHit.GetAttacker(); if ((Object)(object)attacker != (Object)null) { Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { killerPlayer = val.GetPlayerName(); return "combat with " + val.GetPlayerName(); } string text = ((Localization.instance != null) ? Localization.instance.Localize(attacker.m_name) : attacker.m_name); return attacker.IsBoss() ? text : ("a " + text); } DamageTypes damage = lastHit.m_damage; if (damage.m_fire > 0f) { return "burning"; } if (damage.m_frost > 0f) { return "freezing"; } if (damage.m_poison > 0f) { return "poison"; } if (damage.m_spirit > 0f) { return "spirit damage"; } if (damage.m_lightning > 0f) { return "lightning damage"; } if (damage.m_blunt > 0f || damage.m_slash > 0f || damage.m_pierce > 0f) { return flag ? "drowning" : "combat"; } return flag ? "drowning" : "a fall"; } catch { return "unknown causes"; } } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class Patch_PlayerDeath { private static void Prefix(Player __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0044: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && !((Object)(object)__instance == (Object)null) && ((Character)__instance).IsOwner()) { Vector3 position = ((Component)__instance).transform.position; string biomeName = TelemetrySender.GetBiomeName(position); string killerPlayer; string cause = Patch_CharacterDeath.ComputeDeathCause(__instance, out killerPlayer); TelemetrySender.SendDeath(__instance.GetPlayerName(), cause, position, killerPlayer, biomeName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Player.OnDeath report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class Patch_Damage { private static void Prefix(Character __instance, HitData hit) { try { if (!Plugin.EnableReporting.Value || hit == null || (Object)(object)__instance == (Object)null || !__instance.IsOwner()) { return; } Character attacker = hit.GetAttacker(); float totalDamage = hit.GetTotalDamage(); if (totalDamage <= 0f) { return; } Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { string playerName = val.GetPlayerName(); if (__instance is Player) { TelemetryAccumulator.AddCombatDamage(playerName, 0f, totalDamage, 0f, 0f, 0f); } else { TelemetryAccumulator.AddCombatDamage(playerName, totalDamage, 0f, 0f, 0f, 0f); } } Player val2 = (Player)(object)((__instance is Player) ? __instance : null); if (val2 != null) { string playerName2 = val2.GetPlayerName(); if (attacker is Player) { TelemetryAccumulator.AddCombatDamage(playerName2, 0f, 0f, 0f, totalDamage, 0f); } else if ((Object)(object)attacker != (Object)null) { TelemetryAccumulator.AddCombatDamage(playerName2, 0f, 0f, totalDamage, 0f, 0f); } else { TelemetryAccumulator.AddCombatDamage(playerName2, 0f, 0f, 0f, 0f, totalDamage); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Damage report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Humanoid), "BlockAttack")] internal static class Patch_BlockAttack { private static void Postfix(Humanoid __instance, HitData hit, Character attacker, bool __result) { try { if (!Plugin.EnableReporting.Value || !__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { ItemData currentBlocker = ((Humanoid)val).GetCurrentBlocker(); if (currentBlocker != null && hit != null) { bool isParry = currentBlocker.m_shared.m_timedBlockBonus > 1f && ((Humanoid)val).m_blockTimer != -1f && ((Humanoid)val).m_blockTimer < 0.25f; float totalBlockableDamage = hit.GetTotalBlockableDamage(); TelemetryAccumulator.AddBlockDefense(val.GetPlayerName(), isParry, totalBlockableDamage); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Block report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(FishingFloat), "Catch")] internal static class Patch_FishCatch { private static void Postfix(Fish fish, Character owner) { //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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) try { if (!Plugin.EnableReporting.Value || (Object)(object)fish == (Object)null) { return; } Player val = (Player)(object)((owner is Player) ? owner : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { ItemDrop component = ((Component)fish).GetComponent<ItemDrop>(); string name = component?.m_itemData?.m_shared?.m_name ?? ((Object)((Component)fish).gameObject).name; name = TelemetrySender.CleanName(name); if (!string.IsNullOrEmpty(name)) { int quality = ((!((Object)(object)component != (Object)null)) ? 1 : component.m_itemData.m_quality); float weight = (((Object)(object)component != (Object)null) ? component.m_itemData.GetWeight(-1) : 1f); Vector3 position = ((Component)val).transform.position; string biomeName = TelemetrySender.GetBiomeName(position); TelemetrySender.SendFishCatch(val.GetPlayerName(), name, position, quality, weight, biomeName); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] FishCatch report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "PlacePiece")] internal static class Patch_PlayerPlacePiece { private static void Postfix(Player __instance, Piece piece, Vector3 pos, Quaternion rot, bool doAttack) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && !((Object)(object)piece == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { string piecePrefab = TelemetrySender.CleanName(((Object)((Component)piece).gameObject).name); string category = ((object)Unsafe.As<PieceCategory, PieceCategory>(ref piece.m_category)/*cast due to .constrained prefix*/).ToString(); TelemetrySender.SendBuilding(__instance.GetPlayerName(), piecePrefab, pos, 1, category); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] PlacePiece report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class Patch_PlayerRemovePiece { private static void Postfix(Player __instance, bool __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && __result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { TelemetrySender.SendBuilding(__instance.GetPlayerName(), "Piece", ((Component)__instance).transform.position, 2, "Structure"); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] RemovePiece report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] internal static class Patch_Crafting { private sealed class CraftState { public string SharedName; public int TargetQuality; public int CountBefore; public bool IsUpgrade; } private static void Prefix(InventoryGui __instance, Player player, out CraftState __state) { __state = null; try { if (Plugin.EnableReporting.Value && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_craftRecipe == (Object)null) && !((Object)(object)__instance.m_craftRecipe.m_item == (Object)null)) { SharedData shared = __instance.m_craftRecipe.m_item.m_itemData.m_shared; bool flag = __instance.m_craftUpgradeItem != null; int num = ((!flag) ? 1 : (__instance.m_craftUpgradeItem.m_quality + 1)); __state = new CraftState { SharedName = shared.m_name, TargetQuality = num, CountBefore = ((Humanoid)player).GetInventory().CountItems(shared.m_name, num, true), IsUpgrade = flag }; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] DoCrafting prefix failed: " + ex.Message)); } } } private static void Postfix(InventoryGui __instance, Player player, CraftState __state) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) try { if (__state != null && !((Object)(object)player == (Object)null) && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_craftRecipe == (Object)null)) { int num = ((Humanoid)player).GetInventory().CountItems(__state.SharedName, __state.TargetQuality, true) - __state.CountBefore; if (num > 0) { Recipe craftRecipe = __instance.m_craftRecipe; string itemPrefab = (((Object)(object)craftRecipe.m_item != (Object)null) ? TelemetrySender.CleanName(((Object)((Component)craftRecipe.m_item).gameObject).name) : "Unknown"); byte action = (byte)((!__state.IsUpgrade) ? 1 : 2); int amount = (__state.IsUpgrade ? 1 : num); string stationName = (((Object)(object)player.GetCurrentCraftingStation() != (Object)null) ? TelemetrySender.CleanName(((Object)((Component)player.GetCurrentCraftingStation()).gameObject).name) : "Hand"); TelemetrySender.SendCrafting(player.GetPlayerName(), itemPrefab, ((Component)player).transform.position, action, __state.TargetQuality, amount, stationName); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] DoCrafting report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(InventoryGui), "OnRepairPressed")] internal static class Patch_Repair { private static void Postfix(InventoryGui __instance) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { string stationName = (((Object)(object)localPlayer.GetCurrentCraftingStation() != (Object)null) ? TelemetrySender.CleanName(((Object)((Component)localPlayer.GetCurrentCraftingStation()).gameObject).name) : "Hand"); TelemetrySender.SendCrafting(localPlayer.GetPlayerName(), "RepairedEquipment", ((Component)localPlayer).transform.position, 3, 1, 1, stationName); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] OnRepairPressed report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Pickable), "Interact")] internal static class Patch_Pickable { private static readonly Dictionary<int, float> _lastPickReport = new Dictionary<int, float>(); private const float PickDebounceSeconds = 2f; private static void Prefix(Pickable __instance, out bool __state) { __state = (Object)(object)__instance != (Object)null && __instance.m_picked; } private static void Postfix(Pickable __instance, Humanoid character, bool __state) { //IL_01d1: Unknown result type (might be due to invalid IL or missing references) try { if (!Plugin.EnableReporting.Value || (Object)(object)__instance == (Object)null || __state) { return; } Player val = (Player)(object)((character is Player) ? character : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || __instance.m_enabled == 0) { return; } if (__instance.m_tarPreventsPicking) { Floating component = ((Component)__instance).GetComponent<Floating>(); if ((Object)(object)component != (Object)null && component.IsInTar()) { return; } } string text = __instance.GetHoverName(); if (string.IsNullOrEmpty(text) && (Object)(object)__instance.m_itemPrefab != (Object)null) { text = TelemetrySender.CleanName(((Object)__instance.m_itemPrefab).name); } if (string.IsNullOrEmpty(text)) { text = "Pickable"; } byte sourceType = (byte)((!__instance.m_harvestable) ? 1 : 2); int num = ((__instance.m_dontScale || (Object)(object)Game.instance == (Object)null || (Object)(object)__instance.m_itemPrefab == (Object)null) ? __instance.m_amount : Mathf.Max(__instance.m_minAmountScaled, Game.instance.ScaleDrops(__instance.m_itemPrefab, __instance.m_amount))); num = Mathf.Max(1, num); int instanceID = ((Object)__instance).GetInstanceID(); float realtimeSinceStartup = Time.realtimeSinceStartup; if (_lastPickReport.TryGetValue(instanceID, out var value) && realtimeSinceStartup - value < 2f) { return; } foreach (int item in new List<int>(_lastPickReport.Keys)) { if (realtimeSinceStartup - _lastPickReport[item] > 2f) { _lastPickReport.Remove(item); } } _lastPickReport[instanceID] = realtimeSinceStartup; TelemetrySender.SendHarvesting(val.GetPlayerName(), text, ((Component)__instance).transform.position, sourceType, num); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Pickable report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "ConsumeItem")] internal static class Patch_ConsumeItem { private static void Postfix(Player __instance, Inventory inventory, ItemData item, bool checkWorldLevel, bool __result) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && __result && item != null && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { string itemPrefab = (((Object)(object)item.m_dropPrefab != (Object)null) ? TelemetrySender.CleanName(((Object)item.m_dropPrefab).name) : item.m_shared.m_name); byte itemType = (byte)((item.m_shared.m_food > 0f) ? 1 : 2); float food = item.m_shared.m_food; float foodStamina = item.m_shared.m_foodStamina; float foodEitr = item.m_shared.m_foodEitr; TelemetrySender.SendConsumable(__instance.GetPlayerName(), itemPrefab, ((Component)__instance).transform.position, itemType, food, foodStamina, foodEitr); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] ConsumeItem report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(OfferingBowl), "InitiateSpawnBoss")] internal static class Patch_OfferingBowl { private static void Prefix(OfferingBowl __instance, Vector3 point, bool removeItemsFromInventory) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && !((Object)(object)__instance == (Object)null)) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { string targetOrDetails = (((Object)(object)__instance.m_bossPrefab != (Object)null) ? TelemetrySender.CleanName(((Object)__instance.m_bossPrefab).name) : "UnknownBoss"); string biomeName = TelemetrySender.GetBiomeName(point); TelemetrySender.SendWorldEvent(localPlayer.GetPlayerName(), "BossSummoned", point, targetOrDetails, biomeName); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Boss summon report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static class Patch_TeleportWorld { private static void Prefix(TeleportWorld __instance, Player player) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_005c: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && !((Object)(object)__instance == (Object)null) && __instance.TargetFound()) { string text = __instance.GetText(); Vector3 position = ((Component)player).transform.position; string biomeName = TelemetrySender.GetBiomeName(position); TelemetrySender.SendWorldEvent(player.GetPlayerName(), "PortalTraversed", position, text, biomeName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Portal report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "StartGuardianPower")] internal static class Patch_GuardianPower { private static void Postfix(Player __instance, bool __result) { //IL_0045: 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_004b: 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) try { if (Plugin.EnableReporting.Value && __result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)__instance.m_guardianSE == (Object)null)) { string prefabName = Utils.GetPrefabName(((Object)__instance.m_guardianSE).name); Vector3 position = ((Component)__instance).transform.position; string biomeName = TelemetrySender.GetBiomeName(position); TelemetrySender.SendWorldEvent(__instance.GetPlayerName(), "GuardianPowerUsed", position, prefabName, biomeName); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] Guardian power report failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(PlayerProfile), "IncrementStat")] internal static class Patch_PlayerProfileIncrementStat { private static void Postfix(PlayerProfile __instance, PlayerStatType stat, float amount) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.EnableReporting.Value && amount != 0f && !((Object)(object)Game.instance == (Object)null) && Game.instance.GetPlayerProfile() == __instance) { TelemetryAccumulator.AddStatDelta((short)stat, amount); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] StatIncrement delta capture failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class Patch_PlayerOnSpawned { private static void Postfix(Player __instance) { try { if (Plugin.EnableReporting.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { TelemetryAccumulator.FlushFullBackfill(); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] OnSpawned backfill failed: " + ex.Message)); } } } } internal static class TitlePanel { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawWindow; } private static readonly Color Gold = new Color(0.8f, 0.62f, 0.26f, 1f); private static readonly int WindowId = "WhereTheCrowFlies_TitlePanel".GetHashCode(); private static bool _open; private static int _gateUntilFrame = -1; private static bool _rectInitialised; private static Rect _rect; private static Vector2 _scroll; private static string _status = ""; private static List<string> _titles = new List<string>(); private static string _active = ""; private static bool _haveList; private static Terminal _context; private static KeyCode _unreadableKey = (KeyCode)0; public static bool GateActive { get { if (!_open) { return Time.frameCount <= _gateUntilFrame; } return true; } } public static bool IsOpen => _open; private static bool PollKey(KeyCode key) { //IL_0000: 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_000c: 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) try { return ZInput.GetKeyDown(key, false); } catch (Exception ex) { _unreadableKey = key; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"[WhereTheCrowFlies] TitlePanelKey '{key}' cannot be read by the game's input layer ({ex.GetType().Name}); the key is ignored until the config changes. /titles still opens the panel."); } return false; } } public static void Open(Terminal context) { _context = context; _status = "Asking the server…"; _haveList = false; _open = true; TitlePicker.Send(1, "", context); } public static void Close(string why) { if (_open) { _open = false; _gateUntilFrame = Time.frameCount + 1; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[WhereTheCrowFlies] title panel closed: " + why)); } } } public static void Tick() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) try { KeyCode value = Plugin.TitlePanelKey.Value; if ((int)value != 0 && value != _unreadableKey && PollKey(value)) { if (!_open) { if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).TakeInput()) { Open(null); } } else if (!Console.IsVisible() && ((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus())) { Close("key"); } } else if (_open) { if (ZInput.GetKeyDown((KeyCode)27, true)) { Close("escape"); } else if (InventoryGui.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || StoreGui.IsVisible()) { Close("a vanilla window opened"); } else if ((Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).IsDead() || (Object)(object)ZNet.instance == (Object)null) { Close("player gone"); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title panel tick failed: " + ex.Message)); } Close("error"); } } public static void Draw() { //IL_0009: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown if (!_open) { return; } try { GiltFrameTheme.EnsureBuilt(Gold); if (!_rectInitialised) { float num = GiltFrameTheme.S(380f); float num2 = Mathf.Min(GiltFrameTheme.S(480f), (float)Screen.height - 40f); _rect = new Rect(Mathf.Round(((float)Screen.width - num) * 0.5f), Mathf.Round(((float)Screen.height - num2) * 0.5f), num, num2); _rectInitialised = true; } ((Rect)(ref _rect)).x = Mathf.Clamp(((Rect)(ref _rect)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref _rect)).width)); ((Rect)(ref _rect)).y = Mathf.Clamp(((Rect)(ref _rect)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref _rect)).height)); int windowId = WindowId; Rect rect = _rect; object obj = <>O.<0>__DrawWindow; if (obj == null) { WindowFunction val = DrawWindow; <>O.<0>__DrawWindow = val; obj = (object)val; } _rect = GUI.Window(windowId, rect, (WindowFunction)obj, GUIContent.none, GUIStyle.none); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[WhereTheCrowFlies] title panel draw failed: " + ex.Message)); } Close("error"); } } private static void DrawWindow(int id) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0220: Unknown result type (might be due to invalid IL or missing references) Rect win = default(Rect); ((Rect)(ref win))..ctor(0f, 0f, ((Rect)(ref _rect)).width, ((Rect)(ref _rect)).height); GiltFrameTheme.DrawWindow(win, "YOUR TITLES"); GUILayout.BeginArea(GiltFrameTheme.Body(win)); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label(_status, GiltFrameTheme.Note, Array.Empty<GUILayoutOption>()); GUILayout.Space(GiltFrameTheme.S(6f)); if (_haveList && _titles.Count > 0) { _scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>()); foreach (string title in _titles) { bool flag = string.Equals(title, _active, StringComparison.Ordinal); if (GUILayout.Button(flag ? (title + " ✓") : title, flag ? GiltFrameTheme.Primary : GiltFrameTheme.Button, Array.Empty<GUILayoutOption>()) && !flag && TitlePicker.Send(2, title, _context)) { _status = "Asking the server…"; } } GUILayout.EndScrollView(); GUILayout.Space(GiltFrameTheme.S(6f)); GUI.enabled = _active != ""; if (GUILayout.Button("No title", GiltFrameTheme.Button, Array.Empty<GUILayoutOption>()) && TitlePicker.Send(3, "", _context)) { _status = "Asking the server…"; } GUI.enabled = true; } else if (_haveList) { GUILayout.Label("You have earned no titles yet — they come from creature kills and bosses.", GiltFrameTheme.Note, Array.Empty<GUILayoutOption>()); } GUILayout.Space(GiltFrameTheme.S(8f)); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Close", GiltFrameTheme.Button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(GiltFrameTheme.S(80f)) })) { Close("close button"); } GUILayout.Label("Esc closes · /title works in chat too", GiltFrameTheme.Note, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndArea(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref win)).width, 18f + GiltFrameTheme.TitleHeight)); } public static void OnReply(byte kind, string text, List<string> titles, string active) { _status = text; if (titles != null) { _titles = titles; _active = active ?? ""; _haveList = true; } } public static void OnLocal(string text) { if (_open) { _status = text; } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] internal static class Patch_TitlePanelInputGate { private static void Postfix(ref bool __result) { if (TitlePanel.GateActive) { __result = true; } } } } namespace SharedUI { internal enum FrameStyle { Gilt, Runic, Serpent, Ironbound } internal struct ThemeOptions { public Color Metal; public bool DeriveTones; public Color Deep; public Color Bright; public Color Panel; public float PanelOpacity; public Color Text; public Color MutedText; public float Scale; public int BodyDelta; public int TitleDelta; public int SubTitleDelta; public int HeaderDelta; public int ButtonDelta; public int RowDelta; public int FooterDelta; public int FieldDelta; public FrameStyle Frame; public static ThemeOptions Default => new ThemeOptions { Metal = new Color(0.8f, 0.62f, 0.26f, 1f), DeriveTones = true, Deep = new Color(0.26f, 0.17f, 0.05f, 1f), Bright = new Color(1f, 0.94f, 0.72f, 1f), Panel = new Color(0.075f, 0.065f, 0.051f, 1f), PanelOpacity = 0.955f, Text = new Color(0.9f, 0.86f, 0.75f, 1f), MutedText = new Color(0.6f, 0.56f, 0.48f, 1f), Scale = 1f, BodyDelta = 0, TitleDelta = 0, SubTitleDelta = 0, HeaderDelta = 0, ButtonDelta = 0, RowDelta = 0, FooterDelta = 0, FieldDelta = 0, Frame = FrameStyle.Gilt }; } internal static class GiltFrameTheme { private enum Edge { Top, Bottom, Left, Right } private sealed class Painter { public bool MirrorX; public bool MirrorY; public bool Transpose; private readonly int _w; private readonly int _h; private readonly float[] _a; private readonly float[] _z; public Painter(int w, int h) { _w = w; _h = h; _a = new float[w * h]; _z = new float[w * h]; } private void Put(float fx, float fy, float a, float z) { if (a <= 0f) { return; } if (Transpose) { float num = fx; fx = fy; fy = num; } int num2 = Mathf.RoundToInt(fx); int num3 = Mathf.RoundToInt(fy); if (MirrorX) { num2 = _w - 1 - num2; } if (MirrorY) { num3 = _h - 1 - num3; } if (num2 >= 0 && num3 >= 0 && num2 < _w && num3 < _h) { int num4 = num3 * _w + num2; if (a > _a[num4]) { _a[num4] = a; } if (z > _z[num4]) { _z[num4] = z; } } } public void Disc(float cx, float cy, float r) { if (r <= 0f) { return; } int num = Mathf.FloorToInt(cx - r - 1f); int num2 = Mathf.CeilToInt(cx + r + 1f); int num3 = Mathf.FloorToInt(cy - r - 1f); int num4 = Mathf.CeilToInt(cy + r + 1f); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { float num5 = (float)j - cx; float num6 = (float)i - cy; float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6); float num8 = Mathf.Clamp01(r + 0.5f - num7); if (!(num8 <= 0f)) { Put(j, i, num8, Mathf.Sqrt(Mathf.Max(0f, 1f - num7 / r * (num7 / r)))); } } } } public void Lozenge(float cx, float cy, float r) { int num = Mathf.FloorToInt(cx - r - 1f); int num2 = Mathf.CeilToInt(cx + r + 1f); int num3 = Mathf.FloorToInt(cy - r - 1f); int num4 = Mathf.CeilToInt(cy + r + 1f); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { float num5 = Mathf.Abs((float)j - cx) + Mathf.Abs((float)i - cy); float num6 = Mathf.Clamp01(r + 0.5f - num5); if (!(num6 <= 0f)) { Put(j, i, num6, Mathf.Sqrt(Mathf.Max(0f, 1f - num5 / r * (num5 / r)))); } } } } public void Taper(Vector2 a, Vector2 b, float w0, float w1) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(8, Mathf.CeilToInt(Vector2.Distance(a, b) * 3f)); for (int i = 0; i <= num; i++) { float num2 = (float)i / (float)num; Vector2 val = Vector2.Lerp(a, b, num2); Disc(val.x, val.y, Mathf.Lerp(w0, w1, num2)); } } public void Bezier(Vector2 a, Vector2 b, Vector2 c, float w0, float w1) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0055: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(16, Mathf.CeilToInt((Vector2.Distance(a, b) + Vector2.Distance(b, c)) * 3f)); for (int i = 0; i <= num; i++) { float num2 = (float)i / (float)num; float num3 = 1f - num2; Vector2 val = num3 * num3 * a + 2f * num3 * num2 * b + num2 * num2 * c; Disc(val.x, val.y, Mathf.Lerp(w0, w1, num2)); } } public void Spiral(Vector2 eye, float r0, float growth, float t0, float t1, float phase, float w0, float w1, bool mirror = false) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(48, Mathf.CeilToInt((t1 - t0) * 40f)); for (int i = 0; i <= num; i++) { float num2 = (float)i / (float)num; float num3 = Mathf.Lerp(t0, t1, num2); float num4 = r0 * Mathf.Exp(growth * num3); float num5 = num3 + phase; float num6 = Mathf.Cos(num5) * num4; float num7 = Mathf.Sin(num5) * num4; if (mirror) { num6 = 0f - num6; } Disc(eye.x + num6, eye.y + num7, Mathf.Lerp(w0, w1, num2)); } } public void RailPixel(int x, int y, float d, float half) { float num = Mathf.Clamp01(half + 0.5f - d); if (!(num <= 0f)) { Put(x, y, num, Mathf.Sqrt(Mathf.Max(0f, 1f - d / half * (d / half)))); } } public void SquareElbow(float mid, float half, float centre) { for (int i = 0; i < _h; i++) { for (int j = 0; j < _w; j++) { float d = Mathf.Min(Mathf.Abs((float)j - mid), Mathf.Abs((float)i - mid)); if (!((float)j > centre) || !((float)i > centre)) { RailPixel(j, i, d, half); } } } } public void RailElbow(float mid, float half, float centre) { float num = centre - mid; for (int i = 0; i < _h; i++) { for (int j = 0; j < _w; j++) { float d; if (!((float)j <= centre) || !((float)i <= centre)) { d = ((!((float)i <= centre)) ? ((!((float)j <= centre)) ? Mathf.Min(Mathf.Abs((float)i - mid), Mathf.Abs((float)j - mid)) : Mathf.Abs((float)j - mid)) : Mathf.Abs((float)i - mid)); } else { float num2 = (float)j - centre; float num3 = (float)i - centre; d = Mathf.Abs(Mathf.Sqrt(num2 * num2 + num3 * num3) - num); } RailPixel(j, i, d, half); } } } public Texture2D Bake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0129: 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) Texture2D val = New(_w, _h, (TextureWrapMode)1, (FilterMode)1); Color[] array = (Color[])(object)new Color[_w * _h]; for (int i = 0; i < _h; i++) { for (int j = 0; j < _w; j++) { int num = i * _w + j; float num2 = _a[num]; int num3 = (_h - 1 - i) * _w + j; if (num2 <= 0f) { array[num3] = Color.clear; continue; } float num4 = Z(j - 1, i) - Z(j + 1, i) + (Z(j, i - 1) - Z(j, i + 1)); float num5 = Mathf.Clamp01(0.42f + 0.5f * num4 + 0.18f * _z[num]); Color val2 = ((num5 < 0.5f) ? Color.Lerp(GoldDeep, Gold, num5 * 2f) : Color.Lerp(Gold, GoldBright, (num5 - 0.5f) * 2f)); array[num3] = new Color(val2.r, val2.g, val2.b, num2); } } val.SetPixels(array); val.Apply(false); return val; } private float Z(int x, int y) { return _z[Mathf.Clamp(y, 0, _h - 1) * _w + Mathf.Clamp(x, 0, _w - 1)]; } } public static Color GoldDeep = new Color(0.26f, 0.17f, 0.05f, 1f); public static Color Gold = new Color(0.8f, 0.62f, 0.26f, 1f); public static Color GoldBright = new Color(1f, 0.94f, 0.72f, 1f); public static Color Parchment = new Color(0.9f, 0.86f, 0.75f, 1f); public static Color Muted = new Color(0.6f, 0.56f, 0.48f, 1f); private static ThemeOptions _bakedFrom = ThemeOptions.Default; private static bool _everBaked; private static int _appliedFrame = -1; private static bool _conflictLogged; private static readonly ManualLogSource Log = Logger.CreateLogSource("SharedUI.GiltFrameTheme"); public const string HexMuted = "#9A9182"; public const string HexLocked = "#E0736B"; public const string HexOpen = "#87D278"; public const float Band = 18f; public const float Pad = 22f; public static float TitleHeight = 54f; public static float FooterHeight = 30f; private static int _fontDelta; private static ThemeOptions _styledFrom = ThemeOptions.Default; private static bool _everStyled; private const int CornerTile = 84; private const float Overhang = 10f; private const float CornerExtent = 74f; private const int CrestW = 56; private const int CrestH = 34; private const float CrestOverhang = 8f; private const float OuterMid = 4.4f; private const float OuterHalf = 2.7f; private const float InnerMid = 12.4f; private const float InnerHalf = 1.6f; private const float BendCentre = 32f; public static GUIStyle Title; public static GUIStyle SubTitle; public static GUIStyle Header; public static GUIStyle Key; public static GUIStyle Value; public static GUIStyle Note; public static GUIStyle Footer; public static GUIStyle Button; public static GUIStyle Primary; public static GUIStyle Row; public static GUIStyle Field; public static GUIStyle ImageButton; private static Texture2D _railTop; private static Texture2D _railBottom; private static Texture2D _railLeft; private static Texture2D _railRight; private static Texture2D _cornerTL; private static Texture2D _cornerTR; private static Texture2D _cornerBL; private static Texture2D _cornerBR; private static Texture2D _crestTop; private static Texture2D _crestBottom; private static Texture2D _diamond; private static Texture2D _heart; private static Texture2D _dot; private static Texture2D _panel; private static Texture2D _white; private static Texture2D _btnNormal; private static Texture2D _btnHover; private static Texture2D _btnActive; private static Texture2D _rowNormal; private static Texture2D _rowHover; private static Texture2D _rowActive; private static Texture2D _selection; private static Texture2D _fieldTex; private static bool _railRepeats; private static float _railTileLength = 4f; public static float TextScale { get; private set; } = 1f; public static Color Metal(float alpha) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) return new Color(Gold.r, Gold.g, Gold.b, alpha); } public static Color MetalBright(float alpha) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) return new Color(GoldBright.r, GoldBright.g, GoldBright.b, alpha); } public static Color MetalDeep(float alpha) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) return new Color(GoldDeep.r, GoldDeep.g, GoldDeep.b, alpha); } private static bool BakeInputsMatch(ThemeOptions o) { //IL_0020: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (_everBaked && o.Frame == _bakedFrom.Frame && o.Metal == _bakedFrom.Metal && o.DeriveTones == _bakedFrom.DeriveTones && (o.DeriveTones || (o.Deep == _bakedFrom.Deep && o.Bright == _bakedFrom.Bright)) && o.Panel == _bakedFrom.Panel) { return Mathf.Approximately(o.PanelOpacity, _bakedFrom.PanelOpacity); } return false; } private static bool StyleInputsMatch(ThemeOptions o) { //IL_00c8: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (_everStyled && Title != null && Mathf.Approximately(o.Scale, _styledFrom.Scale) && o.BodyDelta == _styledFrom.BodyDelta && o.TitleDelta == _styledFrom.TitleDelta && o.SubTitleDelta == _styledFrom.SubTitleDelta && o.HeaderDelta == _styledFrom.HeaderDelta && o.ButtonDelta == _styledFrom.ButtonDelta && o.RowDelta == _styledFrom.RowDelta && o.FooterDelta == _styledFrom.FooterDelta && o.FieldDelta == _styledFrom.FieldDelta && o.Text == _styledFrom.Text) { return o.MutedText == _styledFrom.MutedText; } return false; } public static float S(float v) { return Mathf.Round(v * TextScale); } public static void EnsureBuilt(Color goldColour, float textScale = 1f, int fontSizeDelta = 0, int headingDelta = 0) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) ThemeOptions o = ThemeOptions.Default; o.Metal = goldColour; o.Scale = textScale; o.BodyDelta = fontSizeDelta; o.TitleDelta = headingDelta; o.SubTitleDelta = headingDelta; o.HeaderDelta = headingDelta; EnsureBuilt(o); } public static void EnsureBuilt(ThemeOptions o) { //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_0196: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_railTop != (Object)null && BakeInputsMatch(o) && StyleInputsMatch(o)) { _appliedFrame = Time.frameCount; return; } if ((Object)(object)_railTop != (Object)null && _appliedFrame == Time.frameCount) { if (!_conflictLogged) { _conflictLogged = true; Log.LogWarning((object)("Two consumers of SharedUI.GiltFrameTheme asked for different values in the same " + $"frame (live: metal={_bakedFrom.Metal}, frame={_bakedFrom.Frame}, scale={TextScale}, " + $"delta={_fontDelta}; requested: metal={o.Metal}, frame={o.Frame}, scale={o.Scale}, " + $"delta={o.BodyDelta}). The theme is a single shared bake, so the first caller each " + "frame wins. Set the same UI theme values in every mod that uses this theme to resolve it.")); } return; } if ((Object)(object)_railTop != (Object)null && !BakeInputsMatch(o)) { DestroyTextures(); } if ((Object)(object)_railTop != (Object)null) { if (!StyleInputsMatch(o)) { BuildStyles(o); } _appliedFrame = Time.frameCount; return; } _bakedFrom = o; _everBaked = true; Gold = new Color(o.Metal.r, o.Metal.g, o.Metal.b, 1f); Parchment = o.Text; Muted = o.MutedText; if (!o.DeriveTones) { GoldDeep = o.Deep; GoldBright = o.Bright; } else if (Mathf.Approximately(Gold.r, 0.8f) && Mathf.Approximately(Gold.g, 0.62f) && Mathf.Approximately(Gold.b, 0.26f)) { GoldDeep = new Color(0.26f, 0.17f, 0.05f, 1f); GoldBright = new Color(1f, 0.94f, 0.72f, 1f); } else { GoldDeep = new Color(Gold.r * 0.325f, Gold.g * 0.274f, Gold.b * 0.192f, 1f); GoldBright = Color.Lerp(Gold, Color.white, 0.72f); } _railTop = BuildRail(o.Frame, Edge.Top); _railBottom = BuildRail(o.Frame, Edge.Bottom); _railLeft = BuildRail(o.Frame, Edge.Left); _railRight = BuildRail(o.Frame, Edge.Right); _railRepeats = RailRepeats(o.Frame); _railTileLength = RailTile(o.Frame); if (_railRepeats) { ((Texture)_railTop).wrapMode = (TextureWrapMode)0; ((Texture)_railBottom).wrapMode = (TextureWrapMode)0; ((Texture)_railLeft).wrapMode = (TextureWrapMode)0; ((Texture)_railRight).wrapMode = (TextureWrapMode)0; } _cornerTL = BuildCorner(o.Frame, mirrorX: false, mirrorY: false); _cornerTR = BuildCorner(o.Frame, mirrorX: true, mirrorY: false); _cornerBL = BuildCorner(o.Frame, mirrorX: false, mirrorY: true); _cornerBR = BuildCorner(o.Frame, mirrorX: true, mirrorY: true); _crestTop = BuildCrest(o.Frame, flip: false); _crestBottom = BuildCrest(o.Frame, flip: true); _diamond = BuildDiamond(14); _heart = BuildHeart(28); _dot = BuildDot(24); _panel = BuildPanel(64, o.Panel, o.PanelOpacity); _white = BuildSolid(Color.white); _btnNormal = BuildPatch(Surface(o, 0.35f, 0.95f), GoldDeep); _btnHover = BuildPatch(Surface(o, 1.3f, 0.97f), Gold); _btnActive = BuildPatch(Surface(o, 2.6f, 0.98f), GoldBright); _rowNormal = BuildPatch(Color.clear, Color.clear); _rowHover = BuildPatch(new Color(Gold.r, Gold.g, Gold.b, 0.1f), new Color(Gold.r, Gold.g, Gold.b, 0.45f)); _rowActive = BuildPatch(new Color(Gold.r, Gold.g, Gold.b, 0.2f), Gold); _selection = BuildSolid(new Color(Gold.r, Gold.g, Gold.b, 0.15f)); _fieldTex = BuildPatch(Surface(o, -0.45f, 0.95f), GoldDeep); BuildStyles(o); _appliedFrame = Time.frameCount; } private static Color Surface(ThemeOptions o, float lift, float alpha) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_001c: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Color panel = o.Panel; if (lift >= 0f) { float num = Mathf.Clamp01(lift * 0.25f); panel = Color.Lerp(panel * (1f + lift * 0.55f), o.Metal, num); } else { panel *= Mathf.Clamp01(1f + lift); } return new Color(Mathf.Clamp01(panel.r), Mathf.Clamp01(panel.g), Mathf.Clamp01(panel.b), alpha); } private static void DestroyTextures() { Texture2D[] array = (Texture2D[])(object)new Texture2D[23] { _railTop, _railBottom, _railLeft, _railRight, _cornerTL, _cornerTR, _cornerBL, _cornerBR, _crestTop, _crestBottom, _diamond, _heart, _panel, _white, _dot, _btnNormal, _btnHover, _btnActive, _rowNormal, _rowHover, _rowActive, _selection, _fieldTex }; foreach (Texture2D val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } _railTop = (_railBottom = (_railLeft = (_railRight = null))); _cornerTL = (_cornerTR = (_cornerBL = (_cornerBR = null))); _crestTop = (_crestBottom = (_diamond = (_heart = (_dot = null)))); _panel = (_white = null); _btnNormal = (_btnHover = (_btnActive = null)); _rowNormal = (_rowHover = (_rowActive = (_selection = null))); _fieldTex = null; Title = null; } public static void DrawWindow(Rect win, string title) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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) DrawPanelFill(win); DrawFrame(win); DrawShadowed(new Rect(((Rect)(ref win)).x + 74f, ((Rect)(ref win)).y + 18f + 8f, ((Rect)(ref win)).width - 148f, TitleHeight - 20f), (title ?? string.Empty).ToUpperInvariant(), Title); DrawRule(new Rect(((Rect)(ref win)).x + 18f + 22f, ((Rect)(ref win)).y + 18f + TitleHeight - 12f, ((Rect)(ref win)).width - 80f, 1f)); } public static void DrawPanelFill(Rect win) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) GUI.DrawTexture(new Rect(((Rect)(ref win)).x + 1f, ((Rect)(ref win)).y + 1f, ((Rect)(ref win)).width - 2f, ((Rect)(ref win)).height - 2f), (Texture)(object)_panel, (ScaleMode)0); } public static Rect Body(Rect win) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref win)).x + 18f + 22f, ((Rect)(ref win)).y + 18f + TitleHeight, ((Rect)(ref win)).width - 80f, ((Rect)(ref win)).height - 36f - TitleHeight - FooterHeight); } public static Rect FooterLine(Rect win) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref win)).