using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.WebSockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using InControl; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Steamworks; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering.PostProcessing; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: AssemblyCompany("CompetitiveRounds")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+878af82075371aad57e60ea72a1f31862239cca9")] [assembly: AssemblyProduct("CompetitiveRounds")] [assembly: AssemblyTitle("CompetitiveRounds")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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 CompetitiveRounds { public static class ApiClient { public class RecentSeriesEntry { public string winner_name; public string p1_name; public string p2_name; public int p1_wins; public int p2_wins; public int p1_rating; public int p2_rating; public float p1_rating_change; public float p2_rating_change; public string winner_steam_id; public string p1_steam_id; public string p2_steam_id; public string completed_at; public List bets = new List(); } public class SeriesBetEntry { public string bettor_name; public string bet_on_name; public string bettor_steam_id; public string bet_on_steam_id; public int amount; public int payout; public float odds_multiplier; public bool won; } [Serializable] public class MatchResponse { public string match_id; public string winner_steam_id; public string message; } [Serializable] public class LeaderboardData { public LeaderboardEntry[] entries; public int total_players; } [Serializable] public class LeaderboardEntry { public int rank; public string steam_id; public string display_name; public int rating; public int rd; public int total_matches; public int wins; public int losses; public float win_rate; public int level; public int gold; public string title; public string title_color; } [Serializable] public class PlayerStatsData { public string steam_id; public string display_name; public float rating; public float rating_deviation; public float peak_rating; public int total_matches; public int wins; public int losses; public float win_rate; public bool ranked_enabled; public int level; public int total_xp; public int xp_into_level; public int xp_for_next_level; public int best_ranked_streak; public int best_casual_streak; public int ranked_series_wins; public int ranked_series_losses; public int ranked_dc_count; public string discord_id; public string discord_username; public int gold_earned; public int gold_spent; public long bullets_fired; public long bullets_hit; public long blocks_activated; public long blocks_successful; public string active_title; public string active_title_color; public string active_trail_sku; public string active_trail_color; public int active_trail_price; public string active_color_sku; public List active_color_skus; public string active_player_color_sku; public string active_player_color_hex; public string active_player_color_name; public string active_cursor_color_sku; public string active_cursor_color_hex; public string active_player_effect_sku; public bool hide_gold; public List active_nametag_skus; public List top_card_names; public List top_card_picks; public List top_card_win_rates; public List recent_form; public List rating_history; public int avg_fps; public float avg_cards_per_game; public int achievements_unlocked; public List worst_card_names; public List worst_card_picks; public List worst_card_win_rates; public List region_names; public List region_matches; public string mod_version; public int h2h_ranked_wins; public int h2h_ranked_losses; public int h2h_casual_wins; public int h2h_casual_losses; public int h2h_series_wins; public int h2h_series_losses; } [Serializable] public class CardStatData { public string card_name; public string card_rarity; public int times_picked; public int wins_with_card; public float win_rate; public int times_offered; public float pass_rate; } [Serializable] private class CardStatsWrapper { public CardStatData[] items; } [Serializable] public class ModCheckResponse { public bool registered; public bool ranked; public string display_name; public bool banned; public string ban_reason; } [Serializable] public class MatchHistoryEntry { public string match_id; public string opponent_steam_id; public string opponent_name; public string opponent_title; public string opponent_title_color; public int player_rounds_won; public int opponent_rounds_won; public int player_points; public int opponent_points; public bool won; public bool is_ranked; public string ended_at; public string cards_display; public string opp_cards_display; public string series_id; public string series_score; public float series_rating_change; public int xp_gained; public int gold_gained; public int series_gold_gained; public int player_fps_avg; public int opponent_fps_avg; } [Serializable] private class MatchHistoryWrapper { public MatchHistoryEntry[] items; } [Serializable] public class AchievementData { public string achievement_key; public bool unlocked; public string unlocked_at; } [Serializable] public class ActiveSeriesEntry { public string series_id; public string p1_steam_id; public string p1_name; public int p1_rating; public int p1_wins; public float p1_odds; public string p2_steam_id; public string p2_name; public int p2_rating; public int p2_wins; public float p2_odds; public int live_p1_points; public int live_p2_points; public bool bets_locked; public string lock_reason; public bool is_private; public bool is_tournament; public string tournament_kind; public string phase; } public class MyBetEntry { public string series_id; public string bet_on_steam_id; public string bet_on_name; public string series_status; public string series_score; public int amount; public float odds_multiplier; } [Serializable] public class ActiveTeamSeriesEntry { public string series_id; public string t1a_steam; public string t1a_name; public string t1b_steam; public string t1b_name; public string t2a_steam; public string t2a_name; public string t2b_steam; public string t2b_name; public int t1_rating; public int t2_rating; public int t1a_rating; public int t1b_rating; public int t2a_rating; public int t2b_rating; public int t1_wins; public int t2_wins; public float t1_odds; public float t2_odds; public bool bets_locked; public string lock_reason; public string started_at; public string dc_grace_until; } [Serializable] public class ShopItemData { public long id; public string sku; public string kind; public string name; public string description; public int price; public string rarity; public string preview_color; public bool owned; } public class FlaggedMatchEntry { public string id; public string match_id; public string series_id; public string flag_reason; public string p1_name; public string p2_name; public List player_steam_ids = new List(); public bool auto_invalidated; public bool match_invalidated; public bool is_ranked; public int duration_seconds; public string review_action; public string created_at; public string flag_details_summary; } public class BannedUserEntry { public string id; public string steam_id; public string display_name; public string reason; public string banned_by_steam_id; public string banned_at; } [Serializable] public class BugReportSummary { public string id; public int bug_number; public string created_at; public string steam_id; public string display_name; public string mod_version; public string severity; public string category; public string status; public string description; public bool has_log; public int log_bytes; } [Serializable] public class BugReportEventEntry { public string id; public string actor_steam_id; public string actor_name; public string event_type; public string old_status; public string new_status; public string comment; public string created_at; } [Serializable] public class BugReportDetail { public string id; public int bug_number; public string steam_id; public string display_name; public string mod_version; public string game_version; public string severity; public string category; public string description; public string repro_steps; public string status; public string triage_notes; public string created_at; public string log_text; public int log_bytes; public List events = new List(); } public enum QueueState { Idle, Searching, Matched, ReadySent } [Serializable] public class QueuePollData { public string status; public int wait_time; public int queue_size; public int elo_range; public string opponent_steam_id; public string opponent_name; public float opponent_rating; public bool opponent_ready; public string room_name; public string photon_region; } public enum TeamQueueState { Idle, Searching, Matched, ReadySent } [Serializable] public class TeamQueueMember { public string steam_id; public string display_name; public int rating; public string region; public int team_assigned; public bool using_fallback_rating; public int balance_rating; public int completed_series; public bool ready; } [Serializable] public class TeamQueuePollData { public string status; public int queue_count; public int elo_range; public string series_id; public int team_assigned; public List teammates = new List(); public List opponents = new List(); public string room_name; public string room_region; public int match_age_seconds; public bool my_ready; } [Serializable] public class TeamQueueListEntry { public string steam_id; public string display_name; public int rating; public int balance_rating; public bool using_fallback_rating; public int completed_series; public string region; public string status; public int team_assigned; public string series_id; public int wait_seconds; public bool manual_pick_enabled; public int preferred_team; public string queue_type; } [Serializable] public class TeamLeaderboardEntry { public int rank; public string steam_id; public string display_name; public int rating; public int rd; public int completed_series; public int series_wins; public int series_losses; public float win_rate; public int level; public string title; public string title_color; public int avg_teammate_elo; public int team_gold_earned; public int team_xp_earned; } [Serializable] public class TeamSeriesSlot { public string steam_id; public string name; public string title; public string title_color; public int rating; public float rating_change; public int gold_earned; public int xp_earned; } [Serializable] public class TeamSeriesMatch { public string match_id; public string ended_at; public int t1_rounds_won; public int t2_rounds_won; public int t1_points_total; public int t2_points_total; public Dictionary> cards_by_player = new Dictionary>(); } [Serializable] public class TeamSeriesPagedEntry { public string series_id; public string completed_at; public int winner_team; public int t1_series_wins; public int t2_series_wins; public TeamSeriesSlot t1a; public TeamSeriesSlot t1b; public TeamSeriesSlot t2a; public TeamSeriesSlot t2b; public List matches = new List(); } public class TeamMatchHistoryEntry { public string match_id; public string series_id; public string ended_at; public bool won; public int my_team; public string t1a_steam_id; public string t1a_name; public string t1b_steam_id; public string t1b_name; public string t2a_steam_id; public string t2a_name; public string t2b_steam_id; public string t2b_name; public int t1_rounds_won; public int t2_rounds_won; public int t1_points_total; public int t2_points_total; public string series_score; public float series_rating_change; public Dictionary fps_by_player = new Dictionary(); public Dictionary> cards_by_player = new Dictionary>(); } [Serializable] public class TeamStatsData { public string steam_id; public string display_name; public float rating; public float rating_deviation; public float peak_rating; public int completed_series; public int series_wins; public int series_losses; public float series_win_rate; public int match_wins; public int match_losses; public int current_streak; } [Serializable] public class TournamentSnapshot { public string tournament_id; public string status; public string kind; public string default_start_ts; public string scheduled_start_ts; public string lock_at; public string started_at; public string ended_at; public int min_players; public int max_players; public string my_signup_id; public bool my_ready; public float my_penalty_pct; public bool my_discord_linked; public int force_vote_count; public string photon_region; public string[] my_votes; public string[] time_slot_options; public TimeVoteTally[] time_slot_tallies; public TournamentSignupRow[] signups; public TournamentMatchRow[] matches; } [Serializable] public class TimeVoteTally { public string slot_ts; public int votes; } [Serializable] public class TournamentSignupRow { public string signup_id; public string steam_id; public string display_name; public bool is_speculative; public int seed; public float penalty_at_signup; public bool ready; public bool forfeited; public int placed_rank; public string progress_label; } [Serializable] public class TournamentMatchRow { public string match_id; public int round; public string bracket_side; public int slot_idx; public string p1_signup_id; public string p2_signup_id; public string p1_display_name; public string p2_display_name; public bool is_bye; public string status; public string series_id; public string winner_signup_id; public int p1_series_wins; public int p2_series_wins; public string deadline_at; public string[] prereq_match_ids; public string photon_room_name; } [Serializable] public class PlayerTournamentHistory { public string steam_id; public int winner_count; public int runner_up_count; public int third_place_count; public int participant_count; public PlayerTournamentEntry[] recent; } [Serializable] public class PlayerTournamentEntry { public string tournament_id; public string ended_at; public int placed_rank; public string kind; public int signup_count; public string winner_display_name; } [Serializable] public class ActiveTournamentMatch { public string tournament_id; public string kind; public string match_id; public string status; public string bracket_side; public int round; public string opponent_steam_id; public string opponent_display_name; public string photon_room_name; public string photon_region; public bool my_ready; public bool opp_ready; } private static string baseUrl = ""; private static float lastFetchTime = 0f; private static float fetchCooldown = 5f; public static readonly Dictionary AchievementDefs = new Dictionary { { "untouchable", new string[2] { "Untouchable", "Win a game without taking any damage" } }, { "silent_assassin", new string[2] { "Silent Assassin", "5-0 someone with Sneaky" } }, { "total_mayhem", new string[2] { "Total Mayhem", "5-0 someone with Mayhem" } }, { "fragile_perfection", new string[2] { "Fragile Perfection", "5-0 someone with Glass Cannon" } }, { "no_escape", new string[2] { "No Escape", "5-0 someone with Chase" } }, { "rise_from_the_ashes", new string[2] { "Rise from the Ashes", "Win 5-0 with Phoenix without losing a life" } }, { "the_comeback_kid", new string[2] { "The Comeback Kid", "Win after being down 0-4" } }, { "stacked_deck", new string[2] { "Stacked Deck", "Get 5 copies of one card in a game" } }, { "regicide", new string[2] { "Regicide", "Win against Sid in a ranked series" } }, { "pacifist", new string[2] { "Pacifist", "Win a game without firing a single shot" } }, { "immovable_object", new string[2] { "Immovable Object", "Win a game without moving or jumping" } }, { "master_rank", new string[2] { "Master", "Reach 2030 rating in ranked (1v1 or 2v2)" } }, { "team_sweep", new string[2] { "Tag Team Sweep", "Win a 2v2 game 5-0" } } }; private static readonly HashSet _heartbeatDispatchedMatches = new HashSet(); private const string GITHUB_API_LATEST = "https://api.github.com/repos/SidNDeed/SidsCompetitiveRounds/releases/latest"; private static readonly byte[] _hkE = new byte[48] { 226, 96, 125, 70, 209, 29, 174, 212, 243, 51, 60, 47, 71, 237, 154, 50, 215, 106, 11, 24, 165, 4, 227, 236, 220, 80, 34, 24, 21, 166, 231, 46, 216, 70, 3, 51, 167, 90, 209, 209, 253, 120, 28, 58, 2, 144, 239, 45 }; private static readonly byte[] _hkX = new byte[16] { 178, 25, 79, 119, 230, 111, 150, 181, 186, 10, 106, 95, 119, 223, 174, 75 }; private static string selectedAchSteamId = ""; public static string ActiveRankedSeriesId; private static float queuePollTimer = 0f; private static float queuePollInterval = 3f; private static float queueCountTimer = 0f; private static float queueCountInterval = 10f; private static float teamQueueListTimer = 0f; private const float TEAM_QUEUE_LIST_INTERVAL = 2f; private static float teamQueuePollTimer = 0f; private static float teamQueueCountTimer = 0f; private const float TEAM_QUEUE_POLL_INTERVAL = 3f; private const float TEAM_QUEUE_COUNT_INTERVAL = 10f; public static string LastSeriesStateStatus = null; public static string LastSeriesStateReason = null; public static int LastSeriesStateConfirmations = 0; public static int LastSeriesDcGraceSeconds = 0; public static int LastSeriesDcTeamRemaining = 0; public static int LastSeriesT1Wins = 0; public static int LastSeriesT2Wins = 0; private static float teamSeriesStateTimer = 0f; private const float TEAM_SERIES_STATE_INTERVAL = 2f; private static bool blocksLoaded = false; public static float LastApiSuccessAt = -999f; public static float LastApiAttemptAt = -999f; public static bool LastResponseWasMaintenance = false; public const int BUG_REPORT_LOG_CAP_CHARS = 3500000; public static string CachedTournamentJson; public static TournamentSnapshot CachedTournament; private static float _tournamentRefreshAt; public static string TournamentKind = "sync"; public static readonly Dictionary CachedPlayerTournaments = new Dictionary(); public static List CachedMyActiveTournamentMatches = new List(); private static float _myActiveMatchesRefreshAt; public static PlayerTournamentEntry[] CachedSiteTournamentHistory; public static string[] CachedSiteTournamentHistoryNames; public static LeaderboardData CachedLeaderboard { get; private set; } public static PlayerStatsData CachedPlayerStats { get; private set; } public static List CachedCardStats { get; private set; } public static bool IsLoading { get; private set; } = false; public static string LastError { get; private set; } = ""; public static string LatestModVersion { get; private set; } = null; public static string MinModVersion { get; private set; } = null; public static bool ForceUpdateRequired { get; private set; } = false; public static List CachedRecentSeries { get; private set; } public static List CachedMatchHistory { get; private set; } public static Dictionary CachedAchievements { get; private set; } public static bool IsUpdating { get; private set; } = false; public static bool UpdateReady { get; private set; } = false; public static List CachedActiveSeries { get; private set; } public static List CachedMyBets { get; private set; } = new List(); public static List CachedActiveTeamSeries { get; private set; } = new List(); public static List CachedShopItems { get; private set; } public static List CachedInventory { get; private set; } public static bool IsAdmin { get; private set; } public static List CachedFlaggedMatches { get; private set; } = new List(); public static List CachedBannedUsers { get; private set; } = new List(); public static List CachedBugReports { get; private set; } = new List(); public static BugReportDetail CachedBugReportDetail { get; set; } public static Dictionary SelectedPlayerAchievements { get; private set; } public static QueueState CurrentQueueState { get; private set; } = QueueState.Idle; public static QueuePollData LastPollData { get; private set; } public static bool IsQueuePolling { get; private set; } = false; public static int CachedQueueSearching { get; private set; } = 0; public static int CachedQueueTotal { get; private set; } = 0; public static List CachedTeamQueueList { get; private set; } = new List(); public static List CachedTeamQueueAuto { get; private set; } = new List(); public static List CachedTeamQueueManual { get; private set; } = new List(); public static TeamQueueState CurrentTeamQueueState { get; private set; } = TeamQueueState.Idle; public static TeamQueuePollData LastTeamPollData { get; private set; } public static string ActiveTeamSeriesId { get; set; } public static bool IsTeamQueuePolling { get; private set; } = false; public static int CachedTeamQueueSearching { get; private set; } = 0; public static string CurrentTeamQueueType { get; private set; } = "auto"; public static List CachedTeamLeaderboard { get; private set; } = new List(); public static int CachedTeamLeaderboardTotal { get; private set; } = 0; public static string CachedTeamLeaderboardSort { get; private set; } = "rating"; public static List CachedTeamSeriesPaged { get; private set; } = new List(); public static int CachedTeamSeriesTotal { get; private set; } = 0; public static int CachedTeamSeriesPage { get; private set; } = 0; public static int CachedTeamSeriesPageSize { get; private set; } = 3; public static int CachedTeamSeriesTotalPages { get; private set; } = 0; public static List CachedTeamMatchHistory { get; private set; } = new List(); public static TeamStatsData CachedTeamStats { get; private set; } public static HashSet BlockedSteamIds { get; private set; } = new HashSet(); public static bool ApiLooksDown { get { if (LastApiAttemptAt < 0f) { return false; } float unscaledTime = Time.unscaledTime; if (unscaledTime - LastApiAttemptAt > 15f) { return false; } return unscaledTime - LastApiSuccessAt > 10f; } } public static void Initialize(string url) { baseUrl = url.TrimEnd('/'); Plugin.Log.LogInfo((object)("API client initialized: " + baseUrl)); CheckModVersion(); ((MonoBehaviour)Plugin.Instance).StartCoroutine(TournamentHeartbeatLoop()); } private static IEnumerator TournamentHeartbeatLoop() { yield return (object)new WaitForSeconds(10f); while (true) { yield return (object)new WaitForSeconds(20f); string sid = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(sid) || sid == "unknown") { continue; } FetchMyActiveTournamentMatches(sid); if (CachedMyActiveTournamentMatches == null) { continue; } HashSet seen = new HashSet(); foreach (ActiveTournamentMatch m in CachedMyActiveTournamentMatches) { if (!string.IsNullOrEmpty(m.tournament_id) && !seen.Contains(m.tournament_id)) { seen.Add(m.tournament_id); TournamentReady(m.tournament_id, sid); yield return (object)new WaitForSeconds(0.2f); if (m.kind == "sync" && m.status == "ready" && m.my_ready && m.opp_ready && !string.IsNullOrEmpty(m.photon_room_name) && !string.IsNullOrEmpty(m.match_id) && !_heartbeatDispatchedMatches.Contains(m.match_id) && Plugin.PendingRankedRoom != m.photon_room_name) { _heartbeatDispatchedMatches.Add(m.match_id); Plugin.SetPendingRoom(m.photon_room_name, m.photon_region); Plugin.Log.LogInfo((object)("[TOURNAMENT-HB] Dispatch from heartbeat loop: room=" + m.photon_room_name + " region=" + (m.photon_region ?? "default") + " match=" + m.match_id)); } } } if (CachedMyActiveTournamentMatches.Count == 0) { _heartbeatDispatchedMatches.Clear(); continue; } HashSet stillActive = new HashSet(); foreach (ActiveTournamentMatch cachedMyActiveTournamentMatch in CachedMyActiveTournamentMatches) { if (!string.IsNullOrEmpty(cachedMyActiveTournamentMatch.match_id)) { stillActive.Add(cachedMyActiveTournamentMatch.match_id); } } _heartbeatDispatchedMatches.RemoveWhere((string id) => !stillActive.Contains(id)); } } public static void CheckModVersion() { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DoCheckModVersion()); } private static IEnumerator DoCheckModVersion() { UnityWebRequest req = UnityWebRequest.Get(baseUrl + "/api/v1/mod-version"); yield return req.SendWebRequest(); if ((int)req.result != 1) { yield break; } string text = ExtractJsonString(req.downloadHandler.text, "version"); string text2 = ExtractJsonString(req.downloadHandler.text, "min_version"); if (!string.IsNullOrEmpty(text)) { LatestModVersion = text; if (text != "1.28.2") { Plugin.Log.LogWarning((object)("[VERSION] Update available: v1.28.2 → v" + text)); } else { Plugin.Log.LogInfo((object)("[VERSION] Mod is up to date (v" + text + ")")); } } if (!string.IsNullOrEmpty(text2)) { MinModVersion = text2; if (CompareVersion("1.28.2", text2) < 0) { ForceUpdateRequired = true; Plugin.Log.LogWarning((object)("[VERSION] Mod is BELOW server minimum (v1.28.2 < v" + text2 + ") — update required")); } } if (!string.IsNullOrEmpty(LatestModVersion) && CompareVersion("1.28.2", LatestModVersion) < 0 && !IsUpdating && !UpdateReady) { Plugin.Log.LogInfo((object)"[VERSION] Auto-firing update on launch"); StartAutoUpdate(); } } private static int CompareVersion(string a, string b) { if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b)) { return 0; } string[] array = a.Split('.'); string[] array2 = b.Split('.'); int num = Math.Max(array.Length, array2.Length); for (int i = 0; i < num; i++) { int.TryParse((i < array.Length) ? array[i] : "0", out var result); int.TryParse((i < array2.Length) ? array2[i] : "0", out var result2); if (result != result2) { if (result >= result2) { return 1; } return -1; } } return 0; } public static void StartAutoUpdate() { if (!IsUpdating && !UpdateReady) { IsUpdating = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(DoAutoUpdate()); } } private static IEnumerator DoAutoUpdate() { Plugin.Log.LogInfo((object)"[UPDATE] Thunderstore build — auto-update disabled, use mod manager"); CompetitiveUI.ShowNotification("Update available — update through your mod manager", Color.cyan, 6f); IsUpdating = false; NativeUI.MarkDirty(); yield break; } private static byte[] GetHmacKeyBytes() { byte[] array = new byte[_hkE.Length]; for (int i = 0; i < _hkE.Length; i++) { array[i] = (byte)(_hkE[i] ^ _hkX[i % _hkX.Length]); } return array; } private static string ComputeHmac(string p1SteamId, string p2SteamId, int p1Rounds, int p2Rounds, bool isRanked, string reporterSteamId, string roomId) { string s = $"{p1SteamId}:{p2SteamId}:{p1Rounds}:{p2Rounds}:" + (isRanked ? "true" : "false") + ":" + reporterSteamId + ":" + roomId; try { using HMACSHA256 hMACSHA = new HMACSHA256(GetHmacKeyBytes()); byte[] array = hMACSHA.ComputeHash(Encoding.UTF8.GetBytes(s)); StringBuilder stringBuilder = new StringBuilder(array.Length * 2); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[HMAC] Computation failed: " + ex.Message)); return ""; } } private static string ComputeHmacHex(string message) { try { using HMACSHA256 hMACSHA = new HMACSHA256(GetHmacKeyBytes()); byte[] array = hMACSHA.ComputeHash(Encoding.UTF8.GetBytes(message)); StringBuilder stringBuilder = new StringBuilder(array.Length * 2); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } catch { return ""; } } public static void FetchActiveSeries() { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/series/active", delegate(bool ok, string resp) { if (ok) { List list = new List(); try { string[] array = resp.Split(new string[1] { "\"series_id\":" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = "\"series_id\":" + array[i]; ActiveSeriesEntry activeSeriesEntry = new ActiveSeriesEntry { series_id = ExtractJsonString(text, "series_id"), p1_steam_id = ExtractJsonString(text, "p1_steam_id"), p1_name = ExtractJsonString(text, "p1_name"), p1_rating = ExtractJsonInt(text, "p1_rating"), p1_wins = ExtractJsonInt(text, "p1_wins"), p1_odds = ExtractJsonFloat(text, "p1_odds"), p2_steam_id = ExtractJsonString(text, "p2_steam_id"), p2_name = ExtractJsonString(text, "p2_name"), p2_rating = ExtractJsonInt(text, "p2_rating"), p2_wins = ExtractJsonInt(text, "p2_wins"), p2_odds = ExtractJsonFloat(text, "p2_odds"), live_p1_points = ExtractJsonInt(text, "live_p1_points"), live_p2_points = ExtractJsonInt(text, "live_p2_points"), bets_locked = (text.Contains("\"bets_locked\":true") || text.Contains("\"bets_locked\": true")), lock_reason = ExtractJsonString(text, "lock_reason"), is_private = (text.Contains("\"is_private\":true") || text.Contains("\"is_private\": true")), is_tournament = (text.Contains("\"is_tournament\":true") || text.Contains("\"is_tournament\": true")), tournament_kind = ExtractJsonString(text, "tournament_kind"), phase = ExtractJsonString(text, "phase") }; if (!string.IsNullOrEmpty(activeSeriesEntry.series_id)) { list.Add(activeSeriesEntry); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BET] active-series parse: " + ex.Message)); } CachedActiveSeries = list; NativeUI.MarkDirty(); } })); } public static void FetchMyBets(string steamId) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/players/" + steamId + "/bets?limit=50", delegate(bool ok, string resp) { if (ok) { List list = new List(); try { string[] array = resp.Split(new string[1] { "\"id\":" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string json = array[i]; MyBetEntry myBetEntry = new MyBetEntry { amount = ExtractJsonInt(json, "amount"), odds_multiplier = ExtractJsonFloat(json, "odds_multiplier"), series_id = ExtractJsonString(json, "series_id"), bet_on_steam_id = ExtractJsonString(json, "bet_on_steam_id"), bet_on_name = ExtractJsonString(json, "bet_on_name"), series_status = ExtractJsonString(json, "series_status"), series_score = ExtractJsonString(json, "series_score") }; if (!string.IsNullOrEmpty(myBetEntry.series_id)) { list.Add(myBetEntry); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BET] my-bets parse: " + ex.Message)); } CachedMyBets = list; NativeUI.MarkDirty(); } })); } public static MyBetEntry GetMyBetForSeries(string seriesId) { if (string.IsNullOrEmpty(seriesId) || CachedMyBets == null) { return null; } foreach (MyBetEntry cachedMyBet in CachedMyBets) { if (cachedMyBet.series_id == seriesId) { return cachedMyBet; } } return null; } public static void PostLivePoints(string seriesId, string reporterSteamId, int p1Points, int p2Points) { if (!string.IsNullOrEmpty(seriesId) && !string.IsNullOrEmpty(reporterSteamId)) { string text = ComputeHmacHex($"live-points:{seriesId}:{reporterSteamId}:{p1Points}:{p2Points}"); string url = baseUrl + "/api/v1/series/" + Escape(seriesId) + "/live-points" + $"?p1_points={p1Points}&p2_points={p2Points}" + "&reporter_steam_id=" + Escape(reporterSteamId) + "&sig=" + text; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[LIVE-POINTS] series={seriesId.Substring(0, Math.Min(8, seriesId.Length))} {p1Points}-{p2Points} ok={ok}"); })); } } public static void PlaceBet(string bettorSteamId, string seriesId, string betOnSteamId, int amount, Action callback) { string text = ComputeHmacHex($"bet:{bettorSteamId}:{seriesId}:{betOnSteamId}:{amount}"); string url = $"{baseUrl}/api/v1/bets?steam_id={Escape(bettorSteamId)}&series_id={Escape(seriesId)}&bet_on_steam_id={Escape(betOnSteamId)}&amount={amount}&sig={text}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[BET] place {amount} on {betOnSteamId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(bettorSteamId); FetchActiveSeries(); } })); } public static void FetchActiveTeamSeries() { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/team/series/active", delegate(bool success, string response) { if (!success) { return; } try { ParseActiveTeamSeries(response); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TEAM-BET] active parse: " + ex.Message)); } })); } private static void ParseActiveTeamSeries(string response) { List list = new List(); int num = response.IndexOf("\"series\""); if (num < 0) { CachedActiveTeamSeries = list; return; } int num2 = response.IndexOf('[', num); int num3 = FindMatchingBracket(response, num2); if (num2 < 0 || num3 < 0) { CachedActiveTeamSeries = list; return; } string text = response.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = 1; int i; for (i = num5 + 1; i < text.Length; i++) { if (num6 <= 0) { break; } if (text[i] == '{') { num6++; } else if (text[i] == '}') { num6--; } } if (num6 != 0) { break; } string json = text.Substring(num5, i - num5); list.Add(new ActiveTeamSeriesEntry { series_id = ExtractJsonString(json, "series_id"), t1a_steam = ExtractJsonString(json, "t1a_steam"), t1a_name = ExtractJsonString(json, "t1a_name"), t1b_steam = ExtractJsonString(json, "t1b_steam"), t1b_name = ExtractJsonString(json, "t1b_name"), t2a_steam = ExtractJsonString(json, "t2a_steam"), t2a_name = ExtractJsonString(json, "t2a_name"), t2b_steam = ExtractJsonString(json, "t2b_steam"), t2b_name = ExtractJsonString(json, "t2b_name"), t1_rating = ExtractJsonInt(json, "t1_rating"), t2_rating = ExtractJsonInt(json, "t2_rating"), t1a_rating = ExtractJsonInt(json, "t1a_rating"), t1b_rating = ExtractJsonInt(json, "t1b_rating"), t2a_rating = ExtractJsonInt(json, "t2a_rating"), t2b_rating = ExtractJsonInt(json, "t2b_rating"), t1_wins = ExtractJsonInt(json, "t1_wins"), t2_wins = ExtractJsonInt(json, "t2_wins"), t1_odds = ExtractJsonFloat(json, "t1_odds"), t2_odds = ExtractJsonFloat(json, "t2_odds"), bets_locked = ExtractJsonBool(json, "bets_locked"), lock_reason = ExtractJsonString(json, "lock_reason"), started_at = ExtractJsonString(json, "started_at"), dc_grace_until = ExtractJsonString(json, "dc_grace_until") }); num4 = i; } CachedActiveTeamSeries = list; } public static void PlaceTeamBet(string bettorSteamId, string seriesId, int betOnTeam, int amount, Action callback) { string text = ComputeHmacHex($"team-bet:{bettorSteamId}:{seriesId}:{betOnTeam}:{amount}"); string url = $"{baseUrl}/api/v1/team-bets?steam_id={Escape(bettorSteamId)}&team_series_id={Escape(seriesId)}&bet_on_team={betOnTeam}&amount={amount}&sig={text}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[TEAM-BET] place {amount} on team {betOnTeam}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(bettorSteamId); FetchActiveTeamSeries(); } })); } public static void FetchShopItems(string steamId = null) { string text = baseUrl + "/api/v1/shop/items"; if (!string.IsNullOrEmpty(steamId)) { text = text + "?steam_id=" + Escape(steamId); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(text, delegate(bool success, string response) { if (!success) { Plugin.Log.LogWarning((object)("[SHOP] list failed: " + response)); } else { CachedShopItems = ParseShopItems(response); Plugin.Log.LogInfo((object)$"[SHOP] loaded {CachedShopItems.Count} items"); NativeUI.MarkDirty(); } })); } public static void FetchInventory(string steamId) { if (string.IsNullOrEmpty(steamId)) { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/players/" + steamId + "/inventory", delegate(bool success, string response) { if (success) { CachedInventory = ParseShopItems(response); NativeUI.MarkDirty(); } })); } public static void PurchaseItem(string steamId, string sku, Action callback) { Plugin.Log.LogInfo((object)("[SHOP] PurchaseItem ENTRY sku=" + sku + " steamId=" + steamId)); try { string text = ComputeHmacHex("buy:" + steamId + ":" + sku); Plugin.Log.LogInfo((object)$"[SHOP] sig computed ({text?.Length ?? 0} chars)"); string text2 = baseUrl + "/api/v1/shop/purchase?steam_id=" + steamId + "&sku=" + sku + "&sig=" + text; Plugin.Log.LogInfo((object)("[SHOP] POST " + text2.Substring(0, Math.Min(text2.Length, 100)) + "...")); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)string.Format("[SHOP] purchase callback {0}: ok={1} resp={2}", sku, ok, (resp != null && resp.Length > 120) ? (resp.Substring(0, 120) + "...") : resp)); try { callback?.Invoke(ok, resp); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[SHOP] callback threw: " + ex2.Message)); } if (ok) { FetchPlayerStats(steamId); FetchShopItems(steamId); FetchInventory(steamId); } })); Plugin.Log.LogInfo((object)"[SHOP] coroutine dispatched"); } catch (Exception ex) { Plugin.Log.LogError((object)$"[SHOP] PurchaseItem threw: {ex}"); try { callback?.Invoke(arg1: false, ex.Message); } catch { } } } public static void SetActiveTitle(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"title:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-title?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set title {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetActiveTrail(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"trail:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-trail?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set trail {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetActiveColor(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"color:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-color?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set color {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetActivePlayerColor(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"player_color:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-player-color?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set player_color {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetActiveCursorColor(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"cursor_color:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-cursor-color?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set cursor_color {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetActivePlayerEffect(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"player_effect:{steamId}:{itemId}"); string text2 = baseUrl + "/api/v1/players/" + steamId + "/active-player-effect?sig=" + text; if (itemId > 0) { text2 += $"&item_id={itemId}"; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(text2, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set player_effect {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void SetHideGold(string steamId, bool on, Action callback = null) { string text = ComputeHmacHex($"hide_gold:{steamId}:{(on ? 1 : 0)}"); string url = baseUrl + "/api/v1/players/" + steamId + "/hide-gold?on=" + (on ? "true" : "false") + "&sig=" + text; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] set hide_gold {on}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); FetchLeaderboard(); } })); } public static void ToggleNametagStyle(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"nametag:{steamId}:{itemId}"); string url = $"{baseUrl}/api/v1/players/{steamId}/nametag-toggle?item_id={itemId}&sig={text}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] toggle nametag {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } public static void ToggleMapColor(string steamId, long itemId, Action callback = null) { string text = ComputeHmacHex($"color:{steamId}:{itemId}"); string url = $"{baseUrl}/api/v1/players/{steamId}/color-toggle?item_id={itemId}&sig={text}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] toggle color {itemId}: ok={ok} resp={resp}"); callback?.Invoke(ok, resp); if (ok) { FetchPlayerStats(steamId); } })); } private static List ParseShopItems(string response) { List list = new List(); if (string.IsNullOrEmpty(response)) { return list; } string[] array = response.Split(new string[1] { "{\"id\":" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string json = "{\"id\":" + array[i]; ShopItemData shopItemData = new ShopItemData(); shopItemData.id = ExtractJsonInt(json, "id"); shopItemData.sku = ExtractJsonString(json, "sku"); shopItemData.kind = ExtractJsonString(json, "kind"); shopItemData.name = ExtractJsonString(json, "name"); shopItemData.description = ExtractJsonString(json, "description"); shopItemData.price = ExtractJsonInt(json, "price"); shopItemData.rarity = ExtractJsonString(json, "rarity"); shopItemData.preview_color = ExtractJsonString(json, "preview_color"); shopItemData.owned = ExtractJsonBool(json, "owned"); if (!string.IsNullOrEmpty(shopItemData.sku) || !string.IsNullOrEmpty(shopItemData.name)) { list.Add(shopItemData); } } return list; } public static void FetchRecentChat(int limit = 50) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/chat/recent?limit={limit}", delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { string[] array = response.Split(new string[1] { "{\"source\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = "{\"source\"" + array[i]; int num = text.IndexOf("\"}"); if (num >= 0) { string obj = text.Substring(0, num + 2); try { ChatClient.OnMessage?.Invoke(obj); } catch { } } } Plugin.Log.LogInfo((object)$"[CHAT] Scrollback loaded: {array.Length - 1} messages"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CHAT] Scrollback parse error: " + ex.Message)); } })); } public static void DeletePlayerData(string steamId, Action callback) { if (string.IsNullOrEmpty(steamId)) { callback(arg1: false, "no-steam-id"); return; } string text = ComputeHmacHex("delete:" + steamId); string url = baseUrl + "/api/v1/players/" + steamId + "/data?sig=" + text; ((MonoBehaviour)Plugin.Instance).StartCoroutine(DoDelete(url, callback)); } private static IEnumerator DoDelete(string url, Action callback) { UnityWebRequest request = UnityWebRequest.Delete(url); try { request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); StampVersionHeader(request); request.timeout = 20; yield return request.SendWebRequest(); bool flag = (int)request.result == 1; object arg; if (!flag) { arg = request.error; } else { DownloadHandler downloadHandler = request.downloadHandler; arg = ((downloadHandler != null) ? downloadHandler.text : null) ?? ""; } callback(flag, (string)arg); } finally { ((IDisposable)request)?.Dispose(); } } public static void CheckAdminStatus(string steamId, Action callback = null) { if (string.IsNullOrEmpty(steamId)) { IsAdmin = false; callback?.Invoke(obj: false); return; } string url = baseUrl + "/api/v1/admin/check-status?steam_id=" + steamId; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string body) { bool flag = false; if (ok && !string.IsNullOrEmpty(body)) { flag = body.Contains("\"is_admin\":true") || body.Contains("\"is_admin\": true"); } IsAdmin = flag; Plugin.Log.LogInfo((object)$"[ADMIN] check-status for {steamId}: is_admin={flag}"); callback?.Invoke(flag); })); } public static void FetchFlaggedMatches(string adminSteamId, bool includeReviewed = false, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId)) { callback?.Invoke(obj: false); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":list_flagged:"); string url = baseUrl + "/api/v1/admin/flagged-matches?admin_steam_id=" + adminSteamId + "&hmac_signature=" + text + "&include_reviewed=" + (includeReviewed ? "true" : "false") + "&limit=50"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string body) { if (!ok) { Plugin.Log.LogWarning((object)("[ADMIN] flagged fetch failed: " + body)); callback?.Invoke(obj: false); return; } try { CachedFlaggedMatches = ParseFlaggedMatches(body); callback?.Invoke(obj: true); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ADMIN] flagged parse: " + ex.Message)); callback?.Invoke(obj: false); } })); } public static void FetchBannedUsers(string adminSteamId, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId)) { callback?.Invoke(obj: false); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":list_bans:"); string url = baseUrl + "/api/v1/admin/banned-users?admin_steam_id=" + adminSteamId + "&hmac_signature=" + text; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string body) { if (!ok) { Plugin.Log.LogWarning((object)("[ADMIN] bans fetch failed: " + body)); callback?.Invoke(obj: false); return; } try { CachedBannedUsers = ParseBannedUsers(body); callback?.Invoke(obj: true); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ADMIN] bans parse: " + ex.Message)); callback?.Invoke(obj: false); } })); } public static void AdminBan(string adminSteamId, string targetSteamId, string reason, Action callback = null) { string text = ComputeHmacHex("admin:" + adminSteamId + ":ban:" + targetSteamId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"target_steam_id\":\"" + Escape(targetSteamId) + "\",\"reason\":\"" + Escape(reason) + "\",\"hmac_signature\":\"" + text + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/admin/ban", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void AdminUnban(string adminSteamId, string targetSteamId, Action callback = null) { string text = ComputeHmacHex("admin:" + adminSteamId + ":unban:" + targetSteamId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"target_steam_id\":\"" + Escape(targetSteamId) + "\",\"hmac_signature\":\"" + text + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/admin/unban", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void AdminGrantAchievement(string adminSteamId, string targetSteamId, string achievementKey, Action callback = null) { string text = ComputeHmacHex("admin:" + adminSteamId + ":grant_achievement:" + targetSteamId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"target_steam_id\":\"" + Escape(targetSteamId) + "\",\"achievement_key\":\"" + Escape(achievementKey) + "\",\"hmac_signature\":\"" + text + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/admin/grant-achievement", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void AdminReverseSeries(string adminSteamId, string seriesId, string reason, Action callback = null) { string text = ComputeHmacHex("admin:" + adminSteamId + ":reverse_series:" + seriesId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"series_id\":\"" + Escape(seriesId) + "\",\"reason\":\"" + Escape(reason) + "\",\"hmac_signature\":\"" + text + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/admin/reverse-series", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void AdminReviewFlag(string adminSteamId, string flagId, string action, Action callback = null) { string text = ComputeHmacHex("admin:" + adminSteamId + ":review_flag:" + flagId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"flag_id\":\"" + Escape(flagId) + "\",\"review_action\":\"" + Escape(action) + "\",\"hmac_signature\":\"" + text + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/admin/review-flag", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void FetchBugReports(string adminSteamId, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId)) { callback?.Invoke(obj: false); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":bug_reports:list"); string url = baseUrl + "/api/v1/bug-reports?admin_steam_id=" + adminSteamId + "&hmac_signature=" + text + "&limit=100"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string body) { if (!ok) { Plugin.Log.LogWarning((object)("[BUG-REPORTS] fetch failed: " + body)); callback?.Invoke(obj: false); return; } try { CachedBugReports = ParseBugReportList(body); callback?.Invoke(obj: true); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BUG-REPORTS] parse: " + ex.Message)); callback?.Invoke(obj: false); } })); } public static void FetchBugReportDetail(string adminSteamId, string reportId, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId) || string.IsNullOrEmpty(reportId)) { callback?.Invoke(obj: false); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":bug_reports:" + reportId); string url = baseUrl + "/api/v1/bug-reports/" + reportId + "?admin_steam_id=" + adminSteamId + "&hmac_signature=" + text + "&include_log=true"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string body) { if (!ok) { Plugin.Log.LogWarning((object)("[BUG-REPORTS] detail fetch failed: " + body)); callback?.Invoke(obj: false); return; } try { CachedBugReportDetail = ParseBugReportDetail(body); callback?.Invoke(obj: true); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BUG-REPORTS] detail parse: " + ex.Message)); callback?.Invoke(obj: false); } })); } private static List ParseBugReportList(string json) { List list = new List(); if (string.IsNullOrEmpty(json)) { return list; } int num = json.IndexOf("\"reports\":["); if (num < 0) { return list; } int num2 = num + "\"reports\":[".Length; int num3 = 1; int i; for (i = num2; i < json.Length; i++) { if (num3 <= 0) { break; } if (json[i] == '[') { num3++; } else if (json[i] == ']') { num3--; } } if (num3 != 0) { return list; } string text = json.Substring(num2, i - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = 1; int j; for (j = num5 + 1; j < text.Length; j++) { if (num6 <= 0) { break; } if (text[j] == '{') { num6++; } else if (text[j] == '}') { num6--; } } if (num6 != 0) { break; } string json2 = text.Substring(num5, j - num5); list.Add(new BugReportSummary { id = ExtractJsonString(json2, "id"), bug_number = ExtractJsonInt(json2, "bug_number"), created_at = ExtractJsonString(json2, "created_at"), steam_id = ExtractJsonString(json2, "steam_id"), display_name = ExtractJsonString(json2, "display_name"), mod_version = ExtractJsonString(json2, "mod_version"), severity = ExtractJsonString(json2, "severity"), category = ExtractJsonString(json2, "category"), status = ExtractJsonString(json2, "status"), description = ExtractJsonString(json2, "description"), has_log = ExtractJsonBool(json2, "has_log"), log_bytes = ExtractJsonInt(json2, "log_bytes") }); num4 = j; } return list; } private static BugReportDetail ParseBugReportDetail(string json) { BugReportDetail bugReportDetail = new BugReportDetail { id = ExtractJsonString(json, "id"), bug_number = ExtractJsonInt(json, "bug_number"), steam_id = ExtractJsonString(json, "steam_id"), display_name = ExtractJsonString(json, "display_name"), mod_version = ExtractJsonString(json, "mod_version"), game_version = ExtractJsonString(json, "game_version"), severity = ExtractJsonString(json, "severity"), category = ExtractJsonString(json, "category"), description = ExtractJsonString(json, "description"), repro_steps = ExtractJsonString(json, "repro_steps"), status = ExtractJsonString(json, "status"), triage_notes = ExtractJsonString(json, "triage_notes"), created_at = ExtractJsonString(json, "created_at"), log_text = ExtractJsonString(json, "log_text"), log_bytes = ExtractJsonInt(json, "log_bytes") }; try { int num = json.IndexOf("\"events\":["); if (num >= 0) { int num2 = num + "\"events\":[".Length; int num3 = 1; int i; for (i = num2; i < json.Length; i++) { if (num3 <= 0) { break; } if (json[i] == '[') { num3++; } else if (json[i] == ']') { num3--; } } if (num3 == 0) { string text = json.Substring(num2, i - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = 1; int j; for (j = num5 + 1; j < text.Length; j++) { if (num6 <= 0) { break; } if (text[j] == '{') { num6++; } else if (text[j] == '}') { num6--; } } if (num6 == 0) { string json2 = text.Substring(num5, j - num5); bugReportDetail.events.Add(new BugReportEventEntry { id = ExtractJsonString(json2, "id"), actor_steam_id = ExtractJsonString(json2, "actor_steam_id"), actor_name = ExtractJsonString(json2, "actor_name"), event_type = ExtractJsonString(json2, "event_type"), old_status = ExtractJsonString(json2, "old_status"), new_status = ExtractJsonString(json2, "new_status"), comment = ExtractJsonString(json2, "comment"), created_at = ExtractJsonString(json2, "created_at") }); num4 = j; continue; } break; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BUG-REPORTS] events parse: " + ex.Message)); } return bugReportDetail; } public static void AdminBugReportComment(string adminSteamId, string reportId, string comment, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId) || string.IsNullOrEmpty(reportId)) { callback?.Invoke(arg1: false, "missing args"); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":bug_reports_comment:" + reportId); string json = "{\"admin_steam_id\":\"" + Escape(adminSteamId) + "\",\"hmac_signature\":\"" + text + "\",\"comment\":\"" + Escape(comment ?? "") + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/bug-reports/" + reportId + "/comment", json, delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } public static void AdminBugReportStatus(string adminSteamId, string reportId, string newStatus, string comment, Action callback = null) { if (string.IsNullOrEmpty(adminSteamId) || string.IsNullOrEmpty(reportId) || string.IsNullOrEmpty(newStatus)) { callback?.Invoke(arg1: false, "missing args"); return; } string text = ComputeHmacHex("admin:" + adminSteamId + ":bug_reports_status:" + reportId); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{"); stringBuilder.Append("\"admin_steam_id\":\"" + Escape(adminSteamId) + "\""); stringBuilder.Append(",\"hmac_signature\":\"" + text + "\""); stringBuilder.Append(",\"new_status\":\"" + Escape(newStatus) + "\""); if (!string.IsNullOrEmpty(comment)) { stringBuilder.Append(",\"comment\":\"" + Escape(comment) + "\""); } stringBuilder.Append("}"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/bug-reports/" + reportId + "/status", stringBuilder.ToString(), delegate(bool ok, string resp) { callback?.Invoke(ok, resp); })); } private static List ParseFlaggedMatches(string json) { List list = new List(); if (string.IsNullOrEmpty(json)) { return list; } string[] array = json.Split(new string[1] { "\"id\":\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = array[i]; int num = text.IndexOf('"'); if (num >= 0) { FlaggedMatchEntry flaggedMatchEntry = new FlaggedMatchEntry(); flaggedMatchEntry.id = text.Substring(0, num); flaggedMatchEntry.match_id = ExtractJsonString(text, "match_id"); flaggedMatchEntry.series_id = ExtractJsonString(text, "series_id"); flaggedMatchEntry.flag_reason = ExtractJsonString(text, "flag_reason"); flaggedMatchEntry.p1_name = ExtractJsonString(text, "p1_name"); flaggedMatchEntry.p2_name = ExtractJsonString(text, "p2_name"); flaggedMatchEntry.auto_invalidated = text.Contains("\"auto_invalidated\":true") || text.Contains("\"auto_invalidated\": true"); flaggedMatchEntry.match_invalidated = text.Contains("\"match_invalidated\":true") || text.Contains("\"match_invalidated\": true"); flaggedMatchEntry.is_ranked = text.Contains("\"is_ranked\":true") || text.Contains("\"is_ranked\": true"); flaggedMatchEntry.duration_seconds = ExtractJsonInt(text, "duration_seconds"); flaggedMatchEntry.review_action = ExtractJsonString(text, "review_action"); flaggedMatchEntry.created_at = ExtractJsonString(text, "created_at"); flaggedMatchEntry.flag_details_summary = string.Format("{0} {1} {2}s {3}", flaggedMatchEntry.flag_reason, flaggedMatchEntry.is_ranked ? "R" : "C", flaggedMatchEntry.duration_seconds, flaggedMatchEntry.auto_invalidated ? "[auto-inv]" : "[advisory]"); list.Add(flaggedMatchEntry); } } return list; } private static List ParseBannedUsers(string json) { List list = new List(); if (string.IsNullOrEmpty(json)) { return list; } string[] array = json.Split(new string[1] { "\"id\":\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = array[i]; int num = text.IndexOf('"'); if (num >= 0) { BannedUserEntry bannedUserEntry = new BannedUserEntry(); bannedUserEntry.id = text.Substring(0, num); bannedUserEntry.steam_id = ExtractJsonString(text, "steam_id"); bannedUserEntry.display_name = ExtractJsonString(text, "display_name"); bannedUserEntry.reason = ExtractJsonString(text, "reason"); bannedUserEntry.banned_by_steam_id = ExtractJsonString(text, "banned_by_steam_id"); bannedUserEntry.banned_at = ExtractJsonString(text, "banned_at"); list.Add(bannedUserEntry); } } return list; } public static void CheckOpponentRanked(string steamId, Action callback) { if (string.IsNullOrEmpty(steamId) || steamId.StartsWith("photon_") || steamId == "unknown") { callback(obj: false); return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/mod/check/" + steamId, delegate(bool success, string response) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (success) { try { ModCheckResponse modCheckResponse = JsonUtility.FromJson(response); if (modCheckResponse.banned) { Plugin.Log.LogWarning((object)("[BAN] Opponent " + steamId + " is mod-banned (" + modCheckResponse.ban_reason + ") — leaving match")); CompetitiveUI.ShowNotification("Opponent is banned from the mod for cheating - leaving match.", new Color(1f, 0.3f, 0.3f), 8f); try { if (PhotonNetwork.InRoom) { PhotonNetwork.LeaveRoom(true); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BAN] LeaveRoom failed: " + ex.Message)); } callback(obj: false); } else { bool obj = modCheckResponse.registered && modCheckResponse.ranked; Plugin.Log.LogInfo((object)$"Opponent ranked check: registered={modCheckResponse.registered}, ranked={modCheckResponse.ranked}"); callback(obj); } return; } catch { callback(obj: false); return; } } Plugin.Log.LogWarning((object)("Opponent rank check failed: " + response)); callback(obj: false); })); } public static void ReportMatch(string p1SteamId, string p1Name, string p2SteamId, string p2Name, int p1RoundsWon, int p2RoundsWon, int p1PointsTotal, int p2PointsTotal, List p1Cards, List p2Cards, List p1Offers, List p2Offers, string photonRoomId, string region, int durationSeconds, DateTime startedAt, string reporterSteamId, bool isRanked, int localShotsFired = 0, int localBlocksRaised = 0, int localBulletsFired = 0, int localBulletsHit = 0, int localBlocksActivated = 0, int localBlocksSuccessful = 0, int localAvgFps = 0, int opponentAvgFps = 0) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{"); stringBuilder.Append("\"player1\":{\"steam_id\":\"" + Escape(p1SteamId) + "\",\"display_name\":\"" + Escape(p1Name) + "\",\"cards\":["); AppendCards(stringBuilder, p1Cards); stringBuilder.Append("],\"card_offers\":["); AppendOffers(stringBuilder, p1Offers); stringBuilder.Append("]},"); stringBuilder.Append("\"player2\":{\"steam_id\":\"" + Escape(p2SteamId) + "\",\"display_name\":\"" + Escape(p2Name) + "\",\"cards\":["); AppendCards(stringBuilder, p2Cards); stringBuilder.Append("],\"card_offers\":["); AppendOffers(stringBuilder, p2Offers); stringBuilder.Append("]},"); stringBuilder.Append($"\"p1_rounds_won\":{p1RoundsWon},"); stringBuilder.Append($"\"p2_rounds_won\":{p2RoundsWon},"); stringBuilder.Append($"\"p1_points_total\":{p1PointsTotal},"); stringBuilder.Append($"\"p2_points_total\":{p2PointsTotal},"); stringBuilder.Append("\"photon_room_id\":\"" + Escape(photonRoomId) + "\","); stringBuilder.Append("\"game_version\":\"v" + Application.version + "\","); stringBuilder.Append("\"region\":\"" + Escape(region) + "\","); stringBuilder.Append($"\"match_duration\":{durationSeconds},"); stringBuilder.Append($"\"started_at\":\"{startedAt:yyyy-MM-ddTHH:mm:ssZ}\","); stringBuilder.Append("\"is_ranked\":" + (isRanked ? "true" : "false") + ","); stringBuilder.Append("\"reported_by_steam_id\":\"" + Escape(reporterSteamId) + "\","); stringBuilder.Append($"\"local_shots_fired\":{localShotsFired},"); stringBuilder.Append($"\"local_blocks_raised\":{localBlocksRaised},"); stringBuilder.Append($"\"local_bullets_fired\":{localBulletsFired},"); stringBuilder.Append($"\"local_bullets_hit\":{localBulletsHit},"); stringBuilder.Append($"\"local_blocks_activated\":{localBlocksActivated},"); stringBuilder.Append($"\"local_blocks_successful\":{localBlocksSuccessful},"); stringBuilder.Append($"\"local_avg_fps\":{localAvgFps},"); stringBuilder.Append($"\"opponent_avg_fps\":{opponentAvgFps},"); string text = ComputeHmac(p1SteamId, p2SteamId, p1RoundsWon, p2RoundsWon, isRanked, reporterSteamId, photonRoomId); stringBuilder.Append("\"hmac_signature\":\"" + text + "\""); stringBuilder.Append("}"); string json = stringBuilder.ToString(); string text2 = (isRanked ? "RANKED" : "CASUAL"); Plugin.Log.LogInfo((object)("Reporting " + text2 + " match to API...")); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/matches", json, delegate(bool success, string response) { //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) if (success) { Plugin.Log.LogInfo((object)("Match reported successfully: " + response)); int num = ExtractJsonInt(response, "xp_gained"); int num2 = ExtractJsonInt(response, "level"); ExtractJsonInt(response, "total_xp"); int lastKnownLevel = CompetitiveUI.LastKnownLevel; string text3 = $"+{num} XP"; List list = new List(); if (response.Contains("Win x")) { list.Add("Win x1.5"); } if (response.Contains("Ranked x")) { list.Add("Ranked x1.2"); } if (response.Contains("Sweep")) { list.Add("Sweep +100"); } if (response.Contains("Top 5")) { list.Add("Top 5 +150"); } if (list.Count > 0) { text3 = text3 + " [" + string.Join(", ", list.ToArray()) + "]"; } CompetitiveUI.ShowNotification(text3, new Color(0.4f, 0.8f, 1f), 4f); int num3 = ExtractJsonInt(response, "gold_gained"); if (num3 > 0) { List list2 = new List(); int num4 = response.IndexOf("\"gold_bonuses\":"); if (num4 >= 0) { int num5 = response.IndexOf('[', num4); int num6 = ((num5 >= 0) ? response.IndexOf(']', num5) : (-1)); if (num5 >= 0 && num6 > num5) { string[] array = response.Substring(num5 + 1, num6 - num5 - 1).Split(','); for (int i = 0; i < array.Length; i++) { string text4 = array[i].Trim().Trim('"').Trim(); if (!string.IsNullOrEmpty(text4)) { list2.Add(text4); } } } } string text5 = $"+{num3} gold"; if (list2.Count > 0) { text5 = text5 + " [" + string.Join(", ", list2.ToArray()) + "]"; } CompetitiveUI.QueueNotification(text5, new Color(1f, 0.85f, 0.3f), 4f); } if (num2 > lastKnownLevel && lastKnownLevel >= 0) { CompetitiveUI.QueueNotification($"LEVEL UP! Level {num2}", new Color(1f, 0.85f, 0.3f), 4f); } CompetitiveUI.LastKnownLevel = num2; FetchPlayerStats(MatchTracker.LocalSteamId); FetchMatchHistory(MatchTracker.LocalSteamId); if (isRanked) { string text6 = ExtractJsonString(response, "series_status"); string text7 = ExtractJsonString(response, "series_score"); ActiveRankedSeriesId = null; if (text6 == "active") { CompetitiveUI.QueueNotification("Series: " + text7, new Color(1f, 0.85f, 0.3f)); } else if (text6 == "completed") { CompetitiveUI.QueueNotification("SERIES COMPLETE " + text7 + "!", new Color(0.3f, 1f, 0.3f), 4f); try { string localSteamId = MatchTracker.LocalSteamId; GameStateWatcher.IncrementSessionRankedSeries((!string.IsNullOrEmpty(localSteamId) && localSteamId == p1SteamId) ? (p1RoundsWon > p2RoundsWon) : (p2RoundsWon > p1RoundsWon)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SESSION] series tally update failed: " + ex.Message)); } GameStateWatcher.pendingRegicideCheck = false; } } } else { Plugin.Log.LogError((object)("Failed to report match: " + response)); CompetitiveUI.ShowNotification("Failed to report match", Color.red); } })); } private static void AppendCards(StringBuilder sb, List cards) { for (int i = 0; i < cards.Count; i++) { if (i > 0) { sb.Append(","); } MatchTracker.CardPickData cardPickData = cards[i]; sb.Append("{"); sb.Append("\"card_name\":\"" + Escape(cardPickData.CardName) + "\","); sb.Append("\"card_rarity\":\"" + Escape(cardPickData.CardRarity ?? "Unknown") + "\","); sb.Append($"\"pick_order\":{cardPickData.PickOrder},"); sb.Append($"\"round_number\":{cardPickData.RoundNumber}"); sb.Append("}"); } } private static void AppendOffers(StringBuilder sb, List offers) { if (offers == null) { return; } for (int i = 0; i < offers.Count; i++) { if (i > 0) { sb.Append(","); } MatchTracker.CardOfferData cardOfferData = offers[i]; sb.Append("{"); sb.Append("\"card_name\":\"" + Escape(cardOfferData.CardName) + "\","); sb.Append($"\"round_number\":{cardOfferData.RoundNumber},"); sb.Append("\"was_picked\":" + (cardOfferData.WasPicked ? "true" : "false")); sb.Append("}"); } } public static void FetchLeaderboard(int limit = 100, int minMatches = 1) { IsLoading = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/leaderboard?limit={limit}&min_matches={minMatches}", delegate(bool success, string response) { IsLoading = false; if (success) { try { LeaderboardData leaderboardData = new LeaderboardData { total_players = ExtractJsonInt(response, "total_players") }; List list = new List(); string[] array = response.Split(new string[1] { "\"rank\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = array[i]; LeaderboardEntry leaderboardEntry = new LeaderboardEntry(); try { int num = text.IndexOf(':'); if (num < 0) { num = -1; } int num2 = text.IndexOf(',', num + 1); if (num >= 0 && num2 > num) { string s = text.Substring(num + 1, num2 - num - 1).Trim(); leaderboardEntry.rank = int.Parse(s); } } catch { leaderboardEntry.rank = i; } leaderboardEntry.steam_id = ExtractJsonString(text, "steam_id"); leaderboardEntry.display_name = ExtractJsonString(text, "display_name"); leaderboardEntry.rating = ExtractJsonInt(text, "rating"); leaderboardEntry.rd = ExtractJsonInt(text, "rd"); leaderboardEntry.total_matches = ExtractJsonInt(text, "total_matches"); leaderboardEntry.wins = ExtractJsonInt(text, "wins"); leaderboardEntry.losses = ExtractJsonInt(text, "losses"); try { int num3 = text.IndexOf("\"win_rate\":"); if (num3 >= 0) { for (num3 += "\"win_rate\":".Length; num3 < text.Length && text[num3] == ' '; num3++) { } int j; for (j = num3; j < text.Length && (char.IsDigit(text[j]) || text[j] == '.' || text[j] == '-'); j++) { } if (j > num3) { leaderboardEntry.win_rate = float.Parse(text.Substring(num3, j - num3), CultureInfo.InvariantCulture); } } } catch { leaderboardEntry.win_rate = 0f; } leaderboardEntry.level = ExtractJsonInt(text, "level"); leaderboardEntry.gold = ExtractJsonInt(text, "gold"); leaderboardEntry.title = ExtractJsonString(text, "title"); leaderboardEntry.title_color = ExtractJsonString(text, "title_color"); if (!string.IsNullOrEmpty(leaderboardEntry.steam_id)) { list.Add(leaderboardEntry); } } leaderboardData.entries = list.ToArray(); CachedLeaderboard = leaderboardData; ManualLogSource log = Plugin.Log; LeaderboardEntry[] entries = CachedLeaderboard.entries; log.LogInfo((object)$"Leaderboard loaded: {((entries != null) ? entries.Length : 0)} entries"); return; } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to parse leaderboard: " + ex.Message)); LastError = "Failed to parse leaderboard data"; return; } } LastError = "Failed to fetch leaderboard: " + response; Plugin.Log.LogError((object)LastError); })); } public static void FetchRecentSeries(int limit = 100) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/series/recent?minutes=10080&limit={limit}", delegate(bool success, string response) { if (success) { try { List list = new List(); string[] array = response.Split(new string[1] { "\"series_id\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { if (list.Count >= limit) { break; } RecentSeriesEntry recentSeriesEntry = new RecentSeriesEntry { winner_name = ExtractJsonString(array[i], "winner_name"), p1_name = ExtractJsonString(array[i], "p1_name"), p2_name = ExtractJsonString(array[i], "p2_name"), p1_wins = ExtractJsonInt(array[i], "p1_series_wins"), p2_wins = ExtractJsonInt(array[i], "p2_series_wins"), winner_steam_id = ExtractJsonString(array[i], "winner_steam_id"), p1_steam_id = ExtractJsonString(array[i], "p1_steam_id"), p2_steam_id = ExtractJsonString(array[i], "p2_steam_id") }; try { int num = array[i].IndexOf("\"p1_rating_change\":"); if (num >= 0) { num += "\"p1_rating_change\":".Length; int j; for (j = num; j < array[i].Length && (char.IsDigit(array[i][j]) || array[i][j] == '.' || array[i][j] == '-'); j++) { } if (j > num) { recentSeriesEntry.p1_rating_change = float.Parse(array[i].Substring(num, j - num), CultureInfo.InvariantCulture); } } } catch { } try { int num2 = array[i].IndexOf("\"p2_rating_change\":"); if (num2 >= 0) { num2 += "\"p2_rating_change\":".Length; int k; for (k = num2; k < array[i].Length && (char.IsDigit(array[i][k]) || array[i][k] == '.' || array[i][k] == '-'); k++) { } if (k > num2) { recentSeriesEntry.p2_rating_change = float.Parse(array[i].Substring(num2, k - num2), CultureInfo.InvariantCulture); } } } catch { } recentSeriesEntry.p1_rating = ExtractJsonInt(array[i], "p1_rating"); recentSeriesEntry.p2_rating = ExtractJsonInt(array[i], "p2_rating"); int num3 = array[i].IndexOf("\"bets\":"); if (num3 >= 0) { int num4 = array[i].IndexOf('[', num3); int num5 = array[i].IndexOf(']', num4); if (num4 >= 0 && num5 > num4) { string[] array2 = array[i].Substring(num4, num5 - num4 + 1).Split(new string[1] { "\"bettor_name\":" }, StringSplitOptions.None); for (int l = 1; l < array2.Length; l++) { string text = "\"bettor_name\":" + array2[l]; SeriesBetEntry seriesBetEntry = new SeriesBetEntry { bettor_name = ExtractJsonString(text, "bettor_name"), bettor_steam_id = ExtractJsonString(text, "bettor_steam_id"), bet_on_name = ExtractJsonString(text, "bet_on_name"), bet_on_steam_id = ExtractJsonString(text, "bet_on_steam_id"), amount = ExtractJsonInt(text, "amount"), payout = ExtractJsonInt(text, "payout"), odds_multiplier = ExtractJsonFloat(text, "odds_multiplier"), won = (text.Contains("\"won\":true") || text.Contains("\"won\": true")) }; if (!string.IsNullOrEmpty(seriesBetEntry.bettor_name)) { recentSeriesEntry.bets.Add(seriesBetEntry); } } } } if (!string.IsNullOrEmpty(recentSeriesEntry.p1_name)) { list.Add(recentSeriesEntry); } } CachedRecentSeries = list; Plugin.Log.LogInfo((object)$"Recent series loaded: {list.Count}"); NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Recent series parse error: " + ex.Message)); } } })); } public static void FetchPlayerStats(string steamId, bool force = false) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown" || (!force && IsLoading)) { return; } IsLoading = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/players/" + steamId, delegate(bool success, string response) { IsLoading = false; if (success) { try { CachedPlayerStats = JsonUtility.FromJson(response); ParseTopCards(CachedPlayerStats, response); Plugin.Log.LogInfo((object)("Player stats loaded for " + CachedPlayerStats.display_name)); try { TrailCosmetic.PublishLocalProps(); } catch { } try { PlayerColorCosmetic.PublishLocalProps(); } catch { } try { PlayerEffectCosmetic.PublishLocalProps(); } catch { } try { CursorColorCosmetic.ApplyFromStats(); } catch { } try { NametagStyler.PublishToPhoton(); return; } catch { return; } } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to parse player stats: " + ex.Message)); return; } } if (!response.Contains("404")) { Plugin.Log.LogError((object)("Failed to fetch player stats: " + response)); } })); } public static void FetchPlayerStatsForView(string steamId, Action callback) { if (string.IsNullOrEmpty(steamId)) { callback(null); return; } string localSteamId = MatchTracker.LocalSteamId; string text = ((!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown" && localSteamId != steamId) ? ("?viewer_steam_id=" + Escape(localSteamId)) : ""); ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/players/" + steamId + text, delegate(bool success, string response) { if (success) { try { PlayerStatsData playerStatsData = JsonUtility.FromJson(response); ParseTopCards(playerStatsData, response); callback(playerStatsData); return; } catch { callback(null); return; } } callback(null); })); } private static void ParseTopCards(PlayerStatsData data, string response) { data.top_card_names = new List(); data.top_card_picks = new List(); data.top_card_win_rates = new List(); data.recent_form = new List(); data.worst_card_names = new List(); data.worst_card_picks = new List(); data.worst_card_win_rates = new List(); data.region_names = new List(); data.region_matches = new List(); try { int num = response.IndexOf("\"top_cards\""); if (num >= 0) { int num2 = response.IndexOf("[", num); int num3 = FindMatchingBracket(response, num2); if (num2 >= 0 && num3 >= 0) { string text = response.Substring(num2, num3 - num2 + 1); if (text != "[]") { string[] array = text.Split(new string[1] { "\"card_name\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length && i <= 10; i++) { string text2 = ExtractJsonString(array[i], ""); int item = ExtractJsonInt(array[i], "times_picked"); float item2 = 0f; try { int num4 = array[i].IndexOf("\"win_rate\":"); if (num4 >= 0) { for (num4 += "\"win_rate\":".Length; num4 < array[i].Length && array[i][num4] == ' '; num4++) { } int j; for (j = num4; j < array[i].Length && (char.IsDigit(array[i][j]) || array[i][j] == '.' || array[i][j] == '-'); j++) { } if (j > num4) { item2 = float.Parse(array[i].Substring(num4, j - num4), CultureInfo.InvariantCulture); } } } catch { } if (!string.IsNullOrEmpty(text2)) { data.top_card_names.Add(text2); data.top_card_picks.Add(item); data.top_card_win_rates.Add(item2); } } } } } } catch { } try { int num5 = response.IndexOf("\"worst_cards\""); if (num5 >= 0) { int num6 = response.IndexOf("[", num5); int num7 = FindMatchingBracket(response, num6); if (num6 >= 0 && num7 >= 0) { string text3 = response.Substring(num6, num7 - num6 + 1); if (text3 != "[]") { string[] array2 = text3.Split(new string[1] { "\"card_name\"" }, StringSplitOptions.None); for (int k = 1; k < array2.Length && k <= 10; k++) { string text4 = ExtractJsonString(array2[k], ""); int item3 = ExtractJsonInt(array2[k], "times_picked"); float item4 = ExtractJsonFloat(array2[k], "win_rate"); if (!string.IsNullOrEmpty(text4)) { data.worst_card_names.Add(text4); data.worst_card_picks.Add(item3); data.worst_card_win_rates.Add(item4); } } } } } } catch { } try { int num8 = response.IndexOf("\"region_breakdown\""); if (num8 >= 0) { int num9 = response.IndexOf("[", num8); int num10 = FindMatchingBracket(response, num9); if (num9 >= 0 && num10 >= 0) { string text5 = response.Substring(num9, num10 - num9 + 1); if (text5 != "[]") { string[] array3 = text5.Split(new string[1] { "\"region\"" }, StringSplitOptions.None); for (int l = 1; l < array3.Length; l++) { string text6 = ExtractJsonString(array3[l], ""); int item5 = ExtractJsonInt(array3[l], "matches"); if (!string.IsNullOrEmpty(text6)) { data.region_names.Add(text6); data.region_matches.Add(item5); } } } } } } catch { } try { int num11 = response.IndexOf("\"recent_form\""); if (num11 >= 0) { int num12 = response.IndexOf("[", num11); int num13 = FindMatchingBracket(response, num12); if (num12 >= 0 && num13 >= 0) { string text7 = response.Substring(num12, num13 - num12 + 1); if (text7 != "[]") { string[] array4 = text7.Split(new string[1] { "\"result\"" }, StringSplitOptions.None); for (int m = 1; m < array4.Length; m++) { string text8 = ExtractJsonString(array4[m], ""); if (!string.IsNullOrEmpty(text8)) { data.recent_form.Add(text8); } } } } } } catch { } data.active_color_skus = new List(); try { int num14 = response.IndexOf("\"active_color_skus\""); if (num14 >= 0) { int num15 = response.IndexOf("[", num14); int num16 = FindMatchingBracket(response, num15); if (num15 >= 0 && num16 >= 0 && num16 > num15) { string text9 = response.Substring(num15 + 1, num16 - num15 - 1); int num17 = 0; while (num17 < text9.Length) { int num18 = text9.IndexOf('"', num17); if (num18 >= 0) { int num19 = text9.IndexOf('"', num18 + 1); if (num19 >= 0) { string text10 = text9.Substring(num18 + 1, num19 - num18 - 1); if (!string.IsNullOrEmpty(text10)) { data.active_color_skus.Add(text10); } num17 = num19 + 1; continue; } break; } break; } } } } catch { } data.active_nametag_skus = new List(); try { int num20 = response.IndexOf("\"active_nametag_skus\""); if (num20 >= 0) { int num21 = response.IndexOf("[", num20); int num22 = FindMatchingBracket(response, num21); if (num21 >= 0 && num22 >= 0 && num22 > num21) { string text11 = response.Substring(num21 + 1, num22 - num21 - 1); int num23 = 0; while (num23 < text11.Length) { int num24 = text11.IndexOf('"', num23); if (num24 >= 0) { int num25 = text11.IndexOf('"', num24 + 1); if (num25 >= 0) { string text12 = text11.Substring(num24 + 1, num25 - num24 - 1); if (!string.IsNullOrEmpty(text12)) { data.active_nametag_skus.Add(text12); } num23 = num25 + 1; continue; } break; } break; } } } } catch { } data.rating_history = new List(); try { int num26 = response.IndexOf("\"recent_rating_history\""); if (num26 >= 0) { int num27 = response.IndexOf("[", num26); int num28 = FindMatchingBracket(response, num27); if (num27 >= 0 && num28 >= 0) { string text13 = response.Substring(num27, num28 - num27 + 1); if (text13 != "[]") { string[] array5 = text13.Split(new string[1] { "\"rating\"" }, StringSplitOptions.None); for (int n = 1; n < array5.Length; n++) { int num29 = array5[n].IndexOf(':'); if (num29 >= 0) { int num30; for (num30 = num29 + 1; num30 < array5[n].Length && array5[n][num30] == ' '; num30++) { } int num31; for (num31 = num30; num31 < array5[n].Length && (char.IsDigit(array5[n][num31]) || array5[n][num31] == '.' || array5[n][num31] == '-'); num31++) { } if (num31 > num30) { float item6 = float.Parse(array5[n].Substring(num30, num31 - num30), CultureInfo.InvariantCulture); data.rating_history.Add(item6); } } } } } } } catch { } if (data.rating_history.Count > 0 && data.rating_history[0] != 1500f) { data.rating_history.Insert(0, 1500f); } Plugin.Log.LogInfo((object)$"[STATS] Parsed {data.rating_history.Count} rating history points for {data.display_name} (oldest→newest, 1500 baseline prepended)"); } public static void FetchAchievementsForView(string steamId) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown" || (steamId == selectedAchSteamId && SelectedPlayerAchievements != null)) { return; } selectedAchSteamId = steamId; SelectedPlayerAchievements = null; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/achievements/" + steamId, delegate(bool success, string response) { if (success) { try { Dictionary dictionary = new Dictionary(); string[] array = response.Split(new string[1] { "\"achievement_key\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = ExtractJsonString(array[i], ""); if (!string.IsNullOrEmpty(text)) { bool unlocked = array[i].Contains("\"unlocked\":true") || array[i].Contains("\"unlocked\": true"); dictionary[text] = new AchievementData { achievement_key = text, unlocked = unlocked }; } } SelectedPlayerAchievements = dictionary; NativeUI.MarkDirty(); } catch { } } })); } private static int FindMatchingBracket(string s, int openPos) { if (openPos < 0 || openPos >= s.Length) { return -1; } int num = 0; for (int i = openPos; i < s.Length; i++) { if (s[i] == '[') { num++; } else if (s[i] == ']') { num--; if (num == 0) { return i; } } } return -1; } private static int FindMatchingBrace(string s, int openPos) { if (openPos < 0 || openPos >= s.Length) { return -1; } int num = 0; for (int i = openPos; i < s.Length; i++) { if (s[i] == '{') { num++; } else if (s[i] == '}') { num--; if (num == 0) { return i; } } } return -1; } public static void FetchCardTiers(string steamId, string filter, Action> onLoaded) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { onLoaded?.Invoke(new Dictionary()); return; } string url = baseUrl + "/api/v1/players/" + Escape(steamId) + "/card-tiers?filter=" + Escape(filter); ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool success, string response) { Dictionary dictionary = new Dictionary(); if (!success || string.IsNullOrEmpty(response)) { onLoaded?.Invoke(dictionary); } else { try { int num = response.IndexOf("\"tiers\""); if (num < 0) { onLoaded?.Invoke(dictionary); return; } int num2 = response.IndexOf('{', num); int num3 = FindMatchingBrace(response, num2); if (num2 < 0 || num3 < 0) { onLoaded?.Invoke(dictionary); return; } string text = response.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('"', num4); if (num5 < 0) { break; } int num6 = text.IndexOf('"', num5 + 1); if (num6 < 0) { break; } string text2 = text.Substring(num5 + 1, num6 - num5 - 1); int num7 = text.IndexOf(':', num6); if (num7 < 0) { break; } int num8 = text.IndexOf('"', num7); if (num8 < 0) { break; } int num9 = text.IndexOf('"', num8 + 1); if (num9 < 0) { break; } string value = text.Substring(num8 + 1, num9 - num8 - 1); dictionary[text2.ToLower()] = value; num4 = num9 + 1; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARD-TIER] parse: " + ex.Message)); } onLoaded?.Invoke(dictionary); } })); } public static void SetCardTier(string steamId, string cardName, string filter, string tier) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } string text = ComputeHmacHex("card-tier:" + steamId + ":" + cardName + ":" + filter + ":" + tier); string url = baseUrl + "/api/v1/players/" + Escape(steamId) + "/card-tiers?card_name=" + Escape(cardName) + "&filter=" + Escape(filter) + "&tier=" + Escape(tier) + "&sig=" + text; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (!ok) { Plugin.Log.LogWarning((object)("[CARD-TIER] set failed: " + resp)); } })); } public static void FetchCardStats(int limit = 30, string steamId = null, string sortBy = "times_picked", string isRanked = null) { IsLoading = true; string text = $"{baseUrl}/api/v1/cards?limit={limit}&sort_by={sortBy}&min_picks=1"; if (!string.IsNullOrEmpty(steamId) && steamId != "unknown") { text = text + "&steam_id=" + steamId; } if (!string.IsNullOrEmpty(isRanked)) { text = text + "&is_ranked=" + isRanked; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(text, delegate(bool success, string response) { IsLoading = false; if (success) { try { if (string.IsNullOrEmpty(response) || response.Trim() == "[]") { CachedCardStats = new List(); Plugin.Log.LogInfo((object)"Card stats: no data yet"); } else { List list = new List(); string[] array = response.Split(new string[1] { "\"card_name\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text2 = array[i]; CardStatData cardStatData = new CardStatData { card_name = ExtractJsonString(text2, ""), card_rarity = ExtractJsonString(text2, "card_rarity"), times_picked = ExtractJsonInt(text2, "times_picked"), wins_with_card = ExtractJsonInt(text2, "wins_with_card"), times_offered = ExtractJsonInt(text2, "times_offered"), pass_rate = ExtractJsonFloat(text2, "pass_rate") }; try { string text3 = text2; int num = text3.IndexOf("\"win_rate\":"); if (num >= 0) { for (num += "\"win_rate\":".Length; num < text3.Length && text3[num] == ' '; num++) { } int j; for (j = num; j < text3.Length && (char.IsDigit(text3[j]) || text3[j] == '.' || text3[j] == '-'); j++) { } if (j > num) { cardStatData.win_rate = float.Parse(text3.Substring(num, j - num), CultureInfo.InvariantCulture); } } } catch { cardStatData.win_rate = 0f; } if (!string.IsNullOrEmpty(cardStatData.card_name)) { list.Add(cardStatData); } } CachedCardStats = list; Plugin.Log.LogInfo((object)$"Card stats loaded: {CachedCardStats.Count} cards"); } return; } catch (Exception ex) { CachedCardStats = new List(); Plugin.Log.LogError((object)("Failed to parse card stats: " + ex.Message)); return; } } Plugin.Log.LogError((object)("Failed to fetch card stats: " + response)); })); } public static void FetchMatchHistory(string steamId, int limit = 2000) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/players/{steamId}/matches?limit={limit}", delegate(bool success, string response) { if (success) { try { if (string.IsNullOrEmpty(response) || response.Trim() == "[]") { CachedMatchHistory = new List(); } else { List list = new List(); string[] array = response.Split(new string[1] { "\"match_id\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { MatchHistoryEntry matchHistoryEntry = new MatchHistoryEntry(); string text = array[i]; matchHistoryEntry.match_id = ExtractJsonString(text, ""); matchHistoryEntry.opponent_name = ExtractJsonString(text, "opponent_name"); matchHistoryEntry.opponent_steam_id = ExtractJsonString(text, "opponent_steam_id"); matchHistoryEntry.opponent_title = ExtractJsonString(text, "opponent_title"); matchHistoryEntry.opponent_title_color = ExtractJsonString(text, "opponent_title_color"); matchHistoryEntry.player_rounds_won = ExtractJsonInt(text, "player_rounds_won"); matchHistoryEntry.opponent_rounds_won = ExtractJsonInt(text, "opponent_rounds_won"); matchHistoryEntry.player_points = ExtractJsonInt(text, "player_points"); matchHistoryEntry.opponent_points = ExtractJsonInt(text, "opponent_points"); matchHistoryEntry.won = text.Contains("\"won\":true") || text.Contains("\"won\": true"); matchHistoryEntry.is_ranked = text.Contains("\"is_ranked\":true") || text.Contains("\"is_ranked\": true"); matchHistoryEntry.ended_at = ExtractJsonString(text, "ended_at"); matchHistoryEntry.cards_display = ExtractCardNames(text); matchHistoryEntry.opp_cards_display = ExtractCardNames(text, "opponent_cards_picked"); matchHistoryEntry.series_id = ExtractJsonString(text, "series_id"); matchHistoryEntry.series_score = ExtractJsonString(text, "series_score"); matchHistoryEntry.series_rating_change = ExtractJsonFloat(text, "series_rating_change"); matchHistoryEntry.xp_gained = ExtractJsonInt(text, "xp_gained"); matchHistoryEntry.gold_gained = ExtractJsonInt(text, "gold_gained"); matchHistoryEntry.series_gold_gained = ExtractJsonInt(text, "series_gold_gained"); matchHistoryEntry.player_fps_avg = ExtractJsonInt(text, "player_fps_avg"); matchHistoryEntry.opponent_fps_avg = ExtractJsonInt(text, "opponent_fps_avg"); list.Add(matchHistoryEntry); } CachedMatchHistory = list; Plugin.Log.LogInfo((object)$"Match history loaded: {CachedMatchHistory.Count} matches"); } } catch (Exception ex) { CachedMatchHistory = new List(); Plugin.Log.LogError((object)("Failed to parse match history: " + ex.Message)); } } })); } private static List ParseMatchHistoryJson(string response) { List list = new List(); if (string.IsNullOrEmpty(response) || response.Trim() == "[]") { return list; } string[] array = response.Split(new string[1] { "\"match_id\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { MatchHistoryEntry matchHistoryEntry = new MatchHistoryEntry(); string text = array[i]; matchHistoryEntry.match_id = ExtractJsonString(text, ""); matchHistoryEntry.opponent_name = ExtractJsonString(text, "opponent_name"); matchHistoryEntry.opponent_steam_id = ExtractJsonString(text, "opponent_steam_id"); matchHistoryEntry.opponent_title = ExtractJsonString(text, "opponent_title"); matchHistoryEntry.opponent_title_color = ExtractJsonString(text, "opponent_title_color"); matchHistoryEntry.player_rounds_won = ExtractJsonInt(text, "player_rounds_won"); matchHistoryEntry.opponent_rounds_won = ExtractJsonInt(text, "opponent_rounds_won"); matchHistoryEntry.player_points = ExtractJsonInt(text, "player_points"); matchHistoryEntry.opponent_points = ExtractJsonInt(text, "opponent_points"); matchHistoryEntry.won = text.Contains("\"won\":true") || text.Contains("\"won\": true"); matchHistoryEntry.is_ranked = text.Contains("\"is_ranked\":true") || text.Contains("\"is_ranked\": true"); matchHistoryEntry.ended_at = ExtractJsonString(text, "ended_at"); matchHistoryEntry.cards_display = ExtractCardNames(text); matchHistoryEntry.opp_cards_display = ExtractCardNames(text, "opponent_cards_picked"); matchHistoryEntry.series_id = ExtractJsonString(text, "series_id"); matchHistoryEntry.series_score = ExtractJsonString(text, "series_score"); matchHistoryEntry.series_rating_change = ExtractJsonFloat(text, "series_rating_change"); matchHistoryEntry.xp_gained = ExtractJsonInt(text, "xp_gained"); matchHistoryEntry.gold_gained = ExtractJsonInt(text, "gold_gained"); matchHistoryEntry.series_gold_gained = ExtractJsonInt(text, "series_gold_gained"); matchHistoryEntry.player_fps_avg = ExtractJsonInt(text, "player_fps_avg"); matchHistoryEntry.opponent_fps_avg = ExtractJsonInt(text, "opponent_fps_avg"); list.Add(matchHistoryEntry); } return list; } public static void FetchMatchHistoryForView(string steamId, Action> callback, int limit = 400) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { callback?.Invoke(new List()); return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/players/{steamId}/matches?limit={limit}", delegate(bool success, string response) { List obj; try { obj = (success ? ParseMatchHistoryJson(response) : new List()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[LBVIEW] match parse failed: " + ex.Message)); obj = new List(); } try { callback?.Invoke(obj); } catch { } })); } private static string ExtractJsonString(string json, string key) { try { string text = (string.IsNullOrEmpty(key) ? ":\"" : ("\"" + key + "\":\"")); int num = json.IndexOf(text); if (num < 0) { return ""; } num += text.Length; int num2 = num; StringBuilder stringBuilder = new StringBuilder(); while (num2 < json.Length) { char c = json[num2]; if (c == '\\' && num2 + 1 < json.Length) { char c2 = json[num2 + 1]; switch (c2) { case '"': stringBuilder.Append('"'); num2 += 2; break; case '\\': stringBuilder.Append('\\'); num2 += 2; break; case '/': stringBuilder.Append('/'); num2 += 2; break; case 'n': stringBuilder.Append('\n'); num2 += 2; break; case 'r': stringBuilder.Append('\r'); num2 += 2; break; case 't': stringBuilder.Append('\t'); num2 += 2; break; case 'b': stringBuilder.Append('\b'); num2 += 2; break; case 'f': stringBuilder.Append('\f'); num2 += 2; break; case 'u': { if (num2 + 5 < json.Length && int.TryParse(json.Substring(num2 + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { stringBuilder.Append((char)result); num2 += 6; } else { stringBuilder.Append(c2); num2 += 2; } break; } default: stringBuilder.Append(c2); num2 += 2; break; } } else { if (c == '"') { break; } stringBuilder.Append(c); num2++; } } return stringBuilder.ToString(); } catch { return ""; } } public static int ExtractJsonIntPublic(string json, string key) { return ExtractJsonInt(json, key); } private static int ExtractJsonInt(string json, string key) { try { string text = "\"" + key + "\":"; int num = json.IndexOf(text); if (num < 0) { return 0; } for (num += text.Length; num < json.Length && (json[num] == ' ' || json[num] == '\t'); num++) { } int i; for (i = num; i < json.Length && (char.IsDigit(json[i]) || json[i] == '-'); i++) { } if (i == num) { return 0; } return int.Parse(json.Substring(num, i - num)); } catch { return 0; } } private static float ExtractJsonFloat(string json, string key) { try { string text = "\"" + key + "\":"; int num = json.IndexOf(text); if (num < 0) { return 0f; } for (num += text.Length; num < json.Length && (json[num] == ' ' || json[num] == '\t'); num++) { } if (num < json.Length && json[num] == 'n') { return 0f; } int i; for (i = num; i < json.Length && (char.IsDigit(json[i]) || json[i] == '.' || json[i] == '-'); i++) { } if (i == num) { return 0f; } return float.Parse(json.Substring(num, i - num), CultureInfo.InvariantCulture); } catch { return 0f; } } private static bool ExtractJsonBool(string json, string key) { try { string text = "\"" + key + "\":"; int num = json.IndexOf(text); if (num < 0) { return false; } for (num += text.Length; num < json.Length && (json[num] == ' ' || json[num] == '\t'); num++) { } return num < json.Length && json[num] == 't'; } catch { return false; } } private static string ExtractCardNames(string chunk, string key = "cards_picked") { try { int num = chunk.IndexOf("\"" + key + "\""); if (num < 0) { return ""; } int num2 = chunk.IndexOf("[", num); int num3 = chunk.IndexOf("]", num2); if (num2 < 0 || num3 < 0) { return ""; } string text = chunk.Substring(num2, num3 - num2 + 1); if (text == "[]") { return ""; } List list = new List(); string[] array = text.Split(new string[1] { "\"card_name\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text2 = ExtractJsonString(array[i], ""); if (!string.IsNullOrEmpty(text2) && text2 != "Unknown") { list.Add(text2); } } return (list.Count > 0) ? string.Join(", ", list.ToArray()) : ""; } catch { return ""; } } public static void TriggerGlickoRecalc() { string text = (Plugin.ApiBaseUrl.Value.Contains("192.168") ? "dev" : "dev"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/glicko/recalculate?api_key=" + text, "", delegate(bool success, string response) { if (success) { Plugin.Log.LogInfo((object)("Glicko-2 recalculation triggered: " + response)); FetchPlayerStats(MatchTracker.LocalSteamId); } else { Plugin.Log.LogWarning((object)("Glicko recalc failed: " + response)); } })); } public static void SendSeriesPreflight(string mySteamId, string oppSteamId) { if (string.IsNullOrEmpty(mySteamId) || string.IsNullOrEmpty(oppSteamId)) { return; } string text = ((string.Compare(mySteamId, oppSteamId, StringComparison.Ordinal) <= 0) ? mySteamId : oppSteamId); string text2 = ((text == mySteamId) ? oppSteamId : mySteamId); string text3 = ComputeHmacHex("preflight:" + text + ":" + text2); string s = MatchTracker.LocalDisplayName ?? mySteamId; string s2 = GameStateWatcher.OpponentDisplayName ?? oppSteamId; string url = baseUrl + "/api/v1/series/preflight?p1_steam_id=" + Escape(mySteamId) + "&p2_steam_id=" + Escape(oppSteamId) + "&p1_name=" + Escape(s) + "&p2_name=" + Escape(s2) + "&sig=" + text3; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (ok) { string text4 = ExtractJsonString(resp, "series_id"); if (!string.IsNullOrEmpty(text4)) { ActiveRankedSeriesId = text4; Plugin.Log.LogInfo((object)("[PREFLIGHT] series_id=" + text4 + " (private room)")); } else { Plugin.Log.LogInfo((object)("[PREFLIGHT] response: " + resp)); } } else { Plugin.Log.LogWarning((object)("[PREFLIGHT] failed: " + resp)); } })); } public static void ToggleRanked(string steamId, bool enabled) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/mod/toggle-ranked/" + steamId + "?enabled=" + enabled.ToString().ToLower() + "&sig=" + ComputeHmacHex("toggle-ranked:" + steamId + ":" + enabled.ToString().ToLower()), "", delegate(bool success, string response) { //IL_0045: 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) if (success) { Plugin.Log.LogInfo((object)$"Ranked mode set to {enabled}"); CompetitiveUI.ShowNotification(enabled ? "Ranked mode ON" : "Ranked mode OFF", enabled ? Color.green : Color.yellow); } else { Plugin.Log.LogError((object)("Failed to toggle ranked: " + response)); } })); } public static void JoinQueue(string steamId, string displayName, string region, bool rankedOnly) { if (string.IsNullOrEmpty(region)) { try { region = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { region = ""; } } string text = Escape(displayName ?? steamId); string json = "{\"steam_id\":\"" + Escape(steamId) + "\",\"display_name\":\"" + text + "\",\"region\":\"" + Escape(region ?? "") + "\",\"ranked_only\":" + (rankedOnly ? "true" : "false") + "}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/queue/join", json, delegate(bool success, string response) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (success) { CurrentQueueState = QueueState.Searching; IsQueuePolling = true; queuePollTimer = 0f; Plugin.Log.LogInfo((object)"[QUEUE] Joined ranked queue"); CompetitiveUI.ShowNotification("Searching for ranked match...", new Color(0.4f, 0.8f, 1f)); NativeUI.MarkDirty(); } else { Plugin.Log.LogWarning((object)("[QUEUE] Failed to join queue: " + response)); CompetitiveUI.ShowNotification("Failed to join queue", new Color(1f, 0.4f, 0.4f)); } })); } public static void LeaveQueue(string steamId) { if (CurrentQueueState != QueueState.Idle || IsQueuePolling) { CurrentQueueState = QueueState.Idle; IsQueuePolling = false; LastPollData = null; NativeUI.MarkDirty(); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/queue/leave?steam_id=" + Escape(steamId), "", delegate { Plugin.Log.LogInfo((object)"[QUEUE] Left ranked queue"); })); } } public static void DeclineMatch(string steamId) { string oppSteamId = LastPollData?.opponent_steam_id ?? ""; CurrentQueueState = QueueState.Searching; LastPollData = null; Plugin.ClearPendingRoom(); NativeUI.MarkDirty(); if (string.IsNullOrEmpty(oppSteamId)) { CurrentQueueState = QueueState.Idle; IsQueuePolling = false; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/queue/leave?steam_id=" + Escape(steamId), "", delegate { Plugin.Log.LogInfo((object)"[QUEUE] Left ranked queue (decline fallback)"); })); NativeUI.MarkDirty(); return; } string json = "{\"steam_id\":\"" + Escape(steamId) + "\",\"opponent_steam_id\":\"" + Escape(oppSteamId) + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/queue/decline", json, delegate(bool success, string response) { if (success) { Plugin.Log.LogInfo((object)("[QUEUE] Declined match vs " + oppSteamId + ", searching for new opponent")); } else { Plugin.Log.LogWarning((object)("[QUEUE] Decline failed: " + response)); } })); } public static void ReadyUp(string steamId) { if (CurrentQueueState != QueueState.Matched) { return; } CurrentQueueState = QueueState.ReadySent; NativeUI.MarkDirty(); Plugin.Log.LogInfo((object)"[QUEUE] Ready Up sent"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/queue/ready?steam_id=" + Escape(steamId), "", delegate(bool success, string response) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (success) { if (ExtractJsonString(response, "status") == "both_ready") { string text = ExtractJsonString(response, "room_name"); string text2 = ExtractJsonString(response, "photon_region"); ActiveRankedSeriesId = ExtractJsonString(response, "series_id"); if (!string.IsNullOrEmpty(text)) { IsQueuePolling = false; CurrentQueueState = QueueState.Idle; LastPollData = null; Plugin.SetPendingRoom(text, text2); Plugin.Log.LogInfo((object)("[QUEUE] Both ready! Joining room: " + text + " (region: " + (text2 ?? "auto") + ") series=" + ActiveRankedSeriesId)); CompetitiveUI.ShowNotification("Both ready! Joining match...", Color.green, 5f); FetchActiveSeries(); NativeUI.MarkDirty(); } } else { string text3 = ExtractJsonString(response, "status") ?? "(no status)"; string text4 = ExtractJsonString(response, "message") ?? ""; Plugin.Log.LogInfo((object)("[QUEUE] Waiting for opponent to ready up (server: " + text3 + " — " + text4 + ")")); } } else { Plugin.Log.LogWarning((object)("[QUEUE] Ready failed after retries: " + response)); CompetitiveUI.ShowNotification("Ready-up failed — retrying search", new Color(1f, 0.6f, 0.2f), 5f); CurrentQueueState = QueueState.Searching; NativeUI.MarkDirty(); } })); } public static void UpdateQueuePoll(string steamId) { if (!IsQueuePolling) { return; } queuePollTimer += Time.deltaTime; if (queuePollTimer < queuePollInterval) { return; } queuePollTimer = 0f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/queue/poll/" + steamId, delegate(bool success, string response) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) if (!success || !IsQueuePolling) { return; } try { switch (ExtractJsonString(response, "status")) { case "ready_join": { string text = ExtractJsonString(response, "room_name"); string text2 = ExtractJsonString(response, "photon_region"); IsQueuePolling = false; CurrentQueueState = QueueState.Idle; LastPollData = null; Plugin.SetPendingRoom(text, text2); Plugin.Log.LogInfo((object)("[QUEUE] Both ready! Joining room: " + text + " (region: " + (text2 ?? "auto") + ")")); CompetitiveUI.ShowNotification("Both ready! Joining match...", Color.green, 5f); NativeUI.MarkDirty(); break; } case "matched": { bool opponent_ready = ExtractJsonBool(response, "opponent_ready"); if (CurrentQueueState == QueueState.Searching) { CurrentQueueState = QueueState.Matched; Plugin.Log.LogInfo((object)string.Format("[QUEUE] MATCHED! vs {0} ({1:F0})", ExtractJsonString(response, "opponent_name"), ExtractJsonFloat(response, "opponent_rating"))); CompetitiveUI.ShowNotification(string.Format("MATCH FOUND! vs {0} ({1:F0})", ExtractJsonString(response, "opponent_name"), ExtractJsonFloat(response, "opponent_rating")), Color.green, 8f); CompetitiveUI.PlayMatchFoundSound(); TaskbarFlash.Flash(); } LastPollData = new QueuePollData { status = "matched", wait_time = ExtractJsonInt(response, "wait_time"), opponent_steam_id = ExtractJsonString(response, "opponent_steam_id"), opponent_name = ExtractJsonString(response, "opponent_name"), opponent_rating = ExtractJsonFloat(response, "opponent_rating"), opponent_ready = opponent_ready }; NativeUI.MarkDirty(); break; } case "searching": if (CurrentQueueState == QueueState.Matched || CurrentQueueState == QueueState.ReadySent) { Plugin.Log.LogInfo((object)"[QUEUE] Match canceled — back to searching"); CompetitiveUI.ShowNotification("Match canceled — searching...", Color.yellow, 5f); } CurrentQueueState = QueueState.Searching; LastPollData = new QueuePollData { status = "searching", wait_time = ExtractJsonInt(response, "wait_time"), queue_size = ExtractJsonInt(response, "queue_size"), elo_range = ExtractJsonInt(response, "elo_range") }; NativeUI.MarkDirty(); break; case "expired": case "not_in_queue": CurrentQueueState = QueueState.Idle; IsQueuePolling = false; LastPollData = null; CompetitiveUI.ShowNotification("Queue search expired", Color.yellow); NativeUI.MarkDirty(); break; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[QUEUE] Poll parse error: " + ex.Message)); } })); } public static void ResetQueueState() { CurrentQueueState = QueueState.Idle; IsQueuePolling = false; LastPollData = null; } public static void UpdateQueueCount() { queueCountTimer += Time.deltaTime; if (queueCountTimer < queueCountInterval) { return; } queueCountTimer = 0f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/queue/count", delegate(bool success, string response) { if (success) { int num = ExtractJsonInt(response, "searching"); int num2 = ExtractJsonInt(response, "total"); if (num != CachedQueueSearching || num2 != CachedQueueTotal) { CachedQueueSearching = num; CachedQueueTotal = num2; NativeUI.MarkDirty(); } } })); } public static void ResetQueueCountTimer() { queueCountTimer = queueCountInterval; } public static void JoinTeamQueue(string steamId, string displayName, string region, string queueType = "auto") { if (string.IsNullOrEmpty(region)) { try { region = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { region = ""; } } string qt = ((queueType == "manual") ? "manual" : "auto"); string text = Escape(displayName ?? steamId); string json = "{\"steam_id\":\"" + Escape(steamId) + "\",\"display_name\":\"" + text + "\",\"region\":\"" + Escape(region ?? "") + "\",\"queue_type\":\"" + qt + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/team/queue/join", json, delegate(bool success, string response) { //IL_00b1: 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) if (success) { CurrentTeamQueueState = TeamQueueState.Searching; CurrentTeamQueueType = qt; IsTeamQueuePolling = true; teamQueuePollTimer = 0f; Plugin.Log.LogInfo((object)("[TEAM-QUEUE] Joined 2v2 " + qt + " queue")); CompetitiveUI.ShowNotification((qt == "manual") ? "Searching for custom 2v2 lobby..." : "Searching for 2v2 match...", new Color(0.4f, 0.8f, 1f)); NativeUI.MarkDirty(); } else { Plugin.Log.LogWarning((object)("[TEAM-QUEUE] Join failed: " + response)); CompetitiveUI.ShowNotification("Failed to join 2v2 queue", new Color(1f, 0.4f, 0.4f)); } })); } public static void LeaveTeamQueue(string steamId) { if (CurrentTeamQueueState != TeamQueueState.Idle || IsTeamQueuePolling) { CurrentTeamQueueState = TeamQueueState.Idle; IsTeamQueuePolling = false; LastTeamPollData = null; ActiveTeamSeriesId = null; Plugin.ClearPending2v2Slot(); NativeUI.MarkDirty(); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/team/queue/leave?steam_id=" + Escape(steamId), "", delegate { Plugin.Log.LogInfo((object)"[TEAM-QUEUE] Left 2v2 queue"); })); } } public static void ReadyUpTeam(string steamId) { if (CurrentTeamQueueState != TeamQueueState.Matched) { return; } CurrentTeamQueueState = TeamQueueState.ReadySent; NativeUI.MarkDirty(); Plugin.Log.LogInfo((object)"[TEAM-QUEUE] Ready Up sent"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/team/queue/ready?steam_id=" + Escape(steamId), "", delegate(bool success, string response) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!success) { Plugin.Log.LogWarning((object)("[TEAM-QUEUE] Ready failed after retries: " + response)); CompetitiveUI.ShowNotification("Ready-up failed — retrying search", new Color(1f, 0.6f, 0.2f), 5f); CurrentTeamQueueState = TeamQueueState.Matched; NativeUI.MarkDirty(); } })); } public static void UpdateTeamQueuePoll(string steamId) { if (!IsTeamQueuePolling) { return; } teamQueuePollTimer += Time.deltaTime; if (teamQueuePollTimer < 3f) { return; } teamQueuePollTimer = 0f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/team/queue/poll/" + steamId, delegate(bool success, string response) { if (!success || !IsTeamQueuePolling) { return; } try { ParseTeamQueuePoll(response); } catch (Exception ex) { Plugin.Log.LogError((object)("[TEAM-QUEUE] poll parse: " + ex.Message)); } })); } public static void UpdateTeamQueueList(bool force = false) { teamQueueListTimer += Time.deltaTime; if (!force && teamQueueListTimer < 2f) { return; } teamQueueListTimer = 0f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/team/queue/list", delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { ParseTeamQueueList(response); NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TEAM-QUEUE-LIST] parse: " + ex.Message)); } })); } private static void ParseTeamQueueList(string response) { List list = new List(); int num = response.IndexOf("\"queuers\""); if (num < 0) { CachedTeamQueueList = list; return; } int num2 = response.IndexOf('[', num); int num3 = FindMatchingBracket(response, num2); if (num2 < 0 || num3 < 0) { CachedTeamQueueList = list; return; } string text = response.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = 1; int i; for (i = num5 + 1; i < text.Length; i++) { if (num6 <= 0) { break; } if (text[i] == '{') { num6++; } else if (text[i] == '}') { num6--; } } if (num6 != 0) { break; } string json = text.Substring(num5, i - num5); string text2 = ExtractJsonString(json, "queue_type"); if (string.IsNullOrEmpty(text2)) { text2 = "auto"; } list.Add(new TeamQueueListEntry { steam_id = ExtractJsonString(json, "steam_id"), display_name = ExtractJsonString(json, "display_name"), rating = ExtractJsonInt(json, "rating"), balance_rating = ExtractJsonInt(json, "balance_rating"), using_fallback_rating = ExtractJsonBool(json, "using_fallback_rating"), completed_series = ExtractJsonInt(json, "completed_series"), region = ExtractJsonString(json, "region"), status = ExtractJsonString(json, "status"), team_assigned = ExtractJsonInt(json, "team_assigned"), series_id = ExtractJsonString(json, "series_id"), wait_seconds = ExtractJsonInt(json, "wait_seconds"), manual_pick_enabled = ExtractJsonBool(json, "manual_pick_enabled"), preferred_team = ExtractJsonInt(json, "preferred_team"), queue_type = text2 }); num4 = i; } CachedTeamQueueList = list; List list2 = new List(); List list3 = new List(); foreach (TeamQueueListEntry item in list) { if (item.queue_type == "manual") { list3.Add(item); } else { list2.Add(item); } } CachedTeamQueueAuto = list2; CachedTeamQueueManual = list3; } public static void ToggleTeamManualPick(string steamId, bool enabled) { if (string.IsNullOrEmpty(steamId)) { return; } string url = baseUrl + "/api/v1/team/queue/manual-pick-toggle?steam_id=" + UnityWebRequest.EscapeURL(steamId) + "&enabled=" + (enabled ? "true" : "false"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (ok) { Plugin.Log.LogInfo((object)$"[2v2-MANUAL] toggle={enabled} ok: {resp}"); } else { Plugin.Log.LogWarning((object)("[2v2-MANUAL] toggle failed: " + resp)); } UpdateTeamQueueList(force: true); })); } public static void SetTeamPreferredTeam(string steamId, int team) { if (string.IsNullOrEmpty(steamId)) { return; } string url = $"{baseUrl}/api/v1/team/queue/preferred-team?steam_id={UnityWebRequest.EscapeURL(steamId)}&team={team}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (ok) { Plugin.Log.LogInfo((object)$"[2v2-MANUAL] team={team} ok: {resp}"); } else { Plugin.Log.LogWarning((object)("[2v2-MANUAL] team set failed: " + resp)); } UpdateTeamQueueList(force: true); })); } private static void ParseTeamQueuePoll(string response) { //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) string text = ExtractJsonString(response, "status"); TeamQueuePollData teamQueuePollData = new TeamQueuePollData { status = text, queue_count = ExtractJsonInt(response, "queue_count"), elo_range = ExtractJsonInt(response, "elo_range"), series_id = ExtractJsonString(response, "series_id"), team_assigned = ExtractJsonInt(response, "team_assigned"), room_name = ExtractJsonString(response, "room_name"), room_region = ExtractJsonString(response, "room_region"), match_age_seconds = ExtractJsonInt(response, "match_age_seconds"), my_ready = ExtractJsonBool(response, "my_ready") }; teamQueuePollData.teammates = ExtractTeamMemberList(response, "teammates"); teamQueuePollData.opponents = ExtractTeamMemberList(response, "opponents"); LastTeamPollData = teamQueuePollData; switch (text) { case "ready_join": { if (string.IsNullOrEmpty(teamQueuePollData.room_name)) { break; } IsTeamQueuePolling = false; CurrentTeamQueueState = TeamQueueState.Idle; ActiveTeamSeriesId = teamQueuePollData.series_id; int num = ComputeMy2v2Slot(MatchTracker.LocalSteamId, teamQueuePollData.team_assigned, teamQueuePollData.teammates); Plugin.SetPending2v2Slot(num); try { Hashtable val = new Hashtable(); val[(object)"p_id"] = num; val[(object)"t_id"] = num / 2; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { val[(object)"u_id"] = localSteamId; } if (PhotonNetwork.LocalPlayer != null) { PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] pre-join SetCustomProperties: " + ex.Message)); } try { NametagStyler.PublishToPhoton(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[2v2] pre-join nametag publish: " + ex2.Message)); } try { PlayerColorCosmetic.PublishLocalProps(); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[2v2] pre-join pcolor publish: " + ex3.Message)); } try { TrailCosmetic.PublishLocalProps(); } catch (Exception ex4) { Plugin.Log.LogWarning((object)("[2v2] pre-join trail publish: " + ex4.Message)); } Plugin.SetPendingRoom(teamQueuePollData.room_name, teamQueuePollData.room_region); Plugin.Log.LogInfo((object)string.Format("[TEAM-QUEUE] All ready! Room: {0} (region: {1}) series={2} my_slot={3}", teamQueuePollData.room_name, teamQueuePollData.room_region ?? "auto", teamQueuePollData.series_id, num)); CompetitiveUI.ShowNotification("4/4 ready! Joining 2v2...", Color.green, 5f); try { if (NativeUI.IsOpen) { NativeUI.Close(); } } catch { } NativeUI.MarkDirty(); break; } case "matched": if (CurrentTeamQueueState != TeamQueueState.ReadySent) { CurrentTeamQueueState = TeamQueueState.Matched; } ActiveTeamSeriesId = teamQueuePollData.series_id; NativeUI.MarkDirty(); break; case "searching": if (CurrentTeamQueueState != TeamQueueState.Searching) { CurrentTeamQueueState = TeamQueueState.Searching; ActiveTeamSeriesId = null; Plugin.ClearPending2v2Slot(); CompetitiveUI.ShowNotification("Match canceled — re-searching", new Color(1f, 0.6f, 0.2f), 5f); } NativeUI.MarkDirty(); break; case "expired": case "not_in_queue": IsTeamQueuePolling = false; CurrentTeamQueueState = TeamQueueState.Idle; LastTeamPollData = null; ActiveTeamSeriesId = null; Plugin.ClearPending2v2Slot(); NativeUI.MarkDirty(); break; } } public static int ComputeMy2v2Slot(string mySteamId, int teamAssigned, List teammates) { int num = ((teamAssigned == 2) ? 2 : 0); string text = null; if (teammates != null) { foreach (TeamQueueMember teammate in teammates) { if (teammate != null && teammate.team_assigned == teamAssigned && teammate.steam_id != mySteamId) { text = teammate.steam_id; break; } } } if (string.IsNullOrEmpty(text)) { return num; } int num2 = ((string.Compare(mySteamId, text, StringComparison.Ordinal) > 0) ? 1 : 0); return num + num2; } private static List ExtractTeamMemberList(string json, string key) { List list = new List(); try { int num = json.IndexOf("\"" + key + "\":["); if (num < 0) { return list; } int num2 = num + key.Length + 4; int num3 = 1; int i; for (i = num2; i < json.Length; i++) { if (num3 <= 0) { break; } if (json[i] == '[') { num3++; } else if (json[i] == ']') { num3--; } } if (num3 != 0) { return list; } string text = json.Substring(num2, i - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = 1; int j; for (j = num5 + 1; j < text.Length; j++) { if (num6 <= 0) { break; } if (text[j] == '{') { num6++; } else if (text[j] == '}') { num6--; } } if (num6 == 0) { string json2 = text.Substring(num5, j - num5); list.Add(new TeamQueueMember { steam_id = ExtractJsonString(json2, "steam_id"), display_name = ExtractJsonString(json2, "display_name"), rating = ExtractJsonInt(json2, "rating"), region = ExtractJsonString(json2, "region"), team_assigned = ExtractJsonInt(json2, "team_assigned"), using_fallback_rating = ExtractJsonBool(json2, "using_fallback_rating"), balance_rating = ExtractJsonInt(json2, "balance_rating"), completed_series = ExtractJsonInt(json2, "completed_series"), ready = ExtractJsonBool(json2, "ready") }); num4 = j; continue; } break; } } catch { } return list; } public static void UpdateTeamQueueCount() { teamQueueCountTimer += Time.deltaTime; if (teamQueueCountTimer < 10f) { return; } teamQueueCountTimer = 0f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/team/queue/count", delegate(bool success, string response) { if (success) { int num = ExtractJsonInt(response, "searching"); if (num != CachedTeamQueueSearching) { CachedTeamQueueSearching = num; NativeUI.MarkDirty(); } } })); } public static void UpdateTeamSeriesStatePoll(bool force) { string activeTeamSeriesId = ActiveTeamSeriesId; if (!string.IsNullOrEmpty(activeTeamSeriesId)) { teamSeriesStateTimer += Time.deltaTime; if (force || !(teamSeriesStateTimer < 2f)) { teamSeriesStateTimer = 0f; PollTeamSeriesState(activeTeamSeriesId, delegate { }); } } } public static void ReportTeamSeriesDc(string seriesId, string reporterSteamId, string dcPlayerSteamId, int t1PointsTotal, int t2PointsTotal) { if (string.IsNullOrEmpty(seriesId) || string.IsNullOrEmpty(reporterSteamId) || string.IsNullOrEmpty(dcPlayerSteamId)) { return; } string text = ComputeHmacHex(reporterSteamId + ":" + seriesId + ":" + dcPlayerSteamId + ":dc"); string url = baseUrl + "/api/v1/team/series/" + seriesId + "/report-dc?reporter_steam_id=" + UnityWebRequest.EscapeURL(reporterSteamId) + "&dc_player_steam_id=" + UnityWebRequest.EscapeURL(dcPlayerSteamId) + $"&t1_points_total={t1PointsTotal}" + $"&t2_points_total={t2PointsTotal}" + "&hmac_sig=" + UnityWebRequest.EscapeURL(text); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (ok) { Plugin.Log.LogInfo((object)("[2v2-DC] report accepted: " + resp)); } else { Plugin.Log.LogWarning((object)("[2v2-DC] report failed: " + resp)); } })); } public static void SendTeamSpawnConfirm(string seriesId, string steamId) { if (string.IsNullOrEmpty(seriesId) || string.IsNullOrEmpty(steamId)) { return; } string text = ComputeHmacHex(steamId + ":" + seriesId + ":spawn"); string url = baseUrl + "/api/v1/team/series/" + seriesId + "/spawn-confirm?steam_id=" + UnityWebRequest.EscapeURL(steamId) + "&hmac_sig=" + UnityWebRequest.EscapeURL(text); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(url, "", delegate(bool ok, string resp) { if (ok) { Plugin.Log.LogInfo((object)("[2v2] spawn-confirm OK: " + resp)); } else { Plugin.Log.LogWarning((object)("[2v2] spawn-confirm failed: " + resp)); } })); } public static void PollTeamSeriesState(string seriesId, Action onResponse) { if (string.IsNullOrEmpty(seriesId)) { return; } string url = baseUrl + "/api/v1/team/series/" + seriesId + "/state"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(url, delegate(bool ok, string resp) { if (ok && !string.IsNullOrEmpty(resp)) { string text = ExtractJsonString(resp, "status") ?? ""; string text2 = ExtractJsonString(resp, "reason") ?? ""; int num = ExtractJsonInt(resp, "confirmations"); LastSeriesStateStatus = text; LastSeriesStateReason = text2; LastSeriesStateConfirmations = num; LastSeriesDcGraceSeconds = ExtractJsonInt(resp, "dc_grace_seconds_remaining"); LastSeriesDcTeamRemaining = ExtractJsonInt(resp, "dc_team_remaining"); LastSeriesT1Wins = ExtractJsonInt(resp, "t1_series_wins"); LastSeriesT2Wins = ExtractJsonInt(resp, "t2_series_wins"); onResponse?.Invoke(text, text2, num); } })); } public static void ReportTeamMatch(string seriesId, string t1aSteam, string t1aName, List t1aCards, string t1bSteam, string t1bName, List t1bCards, string t2aSteam, string t2aName, List t2aCards, string t2bSteam, string t2bName, List t2bCards, int t1Rounds, int t2Rounds, int t1Points, int t2Points, string photonRoomId, string region, int durationSeconds, DateTime startedAt, string reporterSteamId, bool isRanked, int winnerTeam, int t1aFps, int t1bFps, int t2aFps, int t2bFps) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append("\"series_id\":\"" + Escape(seriesId) + "\","); appendPlayer("t1a", t1aSteam, t1aName, t1aCards); appendPlayer("t1b", t1bSteam, t1bName, t1bCards); appendPlayer("t2a", t2aSteam, t2aName, t2aCards); appendPlayer("t2b", t2bSteam, t2bName, t2bCards); sb.Append($"\"t1_rounds_won\":{t1Rounds},"); sb.Append($"\"t2_rounds_won\":{t2Rounds},"); sb.Append($"\"t1_points_total\":{t1Points},"); sb.Append($"\"t2_points_total\":{t2Points},"); sb.Append($"\"winner_team\":{winnerTeam},"); sb.Append("\"photon_room_id\":\"" + Escape(photonRoomId) + "\","); sb.Append("\"game_version\":\"v" + Application.version + "\","); sb.Append("\"region\":\"" + Escape(region) + "\","); sb.Append($"\"match_duration\":{durationSeconds},"); sb.Append($"\"started_at\":\"{startedAt:yyyy-MM-ddTHH:mm:ssZ}\","); sb.Append("\"is_ranked\":" + (isRanked ? "true" : "false") + ","); sb.Append("\"reported_by_steam_id\":\"" + Escape(reporterSteamId) + "\","); sb.Append($"\"t1a_fps\":{t1aFps},\"t1b_fps\":{t1bFps},\"t2a_fps\":{t2aFps},\"t2b_fps\":{t2bFps},"); string text = ComputeHmacHex(t1aSteam + ":" + t1bSteam + ":" + t2aSteam + ":" + t2bSteam + ":" + $"{t1Rounds}:{t2Rounds}:" + (isRanked ? "true" : "false") + ":" + reporterSteamId + ":" + string.Format("{0}:{1}:{2}", photonRoomId ?? "", winnerTeam, seriesId)); sb.Append("\"hmac_signature\":\"" + text + "\""); sb.Append("}"); string json = sb.ToString(); Plugin.Log.LogInfo((object)$"Reporting 2v2 match (series={seriesId}, winner=T{winnerTeam}, {t1Rounds}-{t2Rounds})..."); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/team/matches", json, delegate(bool success, string response) { //IL_004c: 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) //IL_0182: Unknown result type (might be due to invalid IL or missing references) if (success) { Plugin.Log.LogInfo((object)("2v2 match reported: " + response)); string text2 = ExtractJsonString(response, "series_status"); string text3 = ExtractJsonString(response, "series_score"); if (text2 == "completed") { CompetitiveUI.ShowNotification("Series complete: " + text3, Color.green, 6f); try { bool won = false; if (!string.IsNullOrEmpty(text3)) { string[] array = text3.Split('-'); if (array.Length == 2 && int.TryParse(array[0], out var result) && int.TryParse(array[1], out var result2)) { won = result > result2; } } GameStateWatcher.RecordSessionTeamSeries(won); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] session tally failed: " + ex.Message)); } ActiveTeamSeriesId = null; Plugin.ClearPending2v2Slot(); } else if (!string.IsNullOrEmpty(text3)) { CompetitiveUI.ShowNotification("Series: " + text3, new Color(0.6f, 0.8f, 1f), 4f); } try { int num = response.IndexOf("\"rebalance_assignments\":"); if (num >= 0) { int num2 = response.IndexOf('{', num); int num3 = ((num2 >= 0) ? FindMatchingBrace(response, num2) : (-1)); if (num2 > 0 && num3 > num2) { string text4 = response.Substring(num2 + 1, num3 - num2 - 1); if (!string.IsNullOrEmpty(text4.Trim())) { Plugin.Log.LogInfo((object)("[2v2-REBALANCE] server says swap teams next match: " + text4)); CompetitiveUI.ShowNotification("Teams will rebalance next match!", new Color(1f, 0.8f, 0.4f), 5f); } } } return; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[2v2-REBALANCE] parse: " + ex2.Message)); return; } } Plugin.Log.LogWarning((object)("2v2 match report failed: " + response)); })); void appendPlayer(string field, string sid, string name, List cards) { sb.Append("\"" + field + "\":{\"steam_id\":\"" + Escape(sid) + "\",\"display_name\":\"" + Escape(name) + "\",\"cards\":["); AppendCards(sb, cards); sb.Append("],\"card_offers\":[]},"); } } public static void ResetTeamQueue() { CurrentTeamQueueState = TeamQueueState.Idle; IsTeamQueuePolling = false; LastTeamPollData = null; } public static void FetchAllSeriesPaged(int page = 0, int pageSize = 3) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/team/all-series-paged?page={page}&page_size={pageSize}", delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { ParseAllSeriesPaged(response, page, pageSize); NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TEAM-SERIES-PAGED] parse: " + ex.Message)); } })); } private static void ParseAllSeriesPaged(string response, int reqPage, int reqPageSize) { List list = new List(); int num = response.IndexOf("\"series\""); if (num < 0) { CachedTeamSeriesPaged = list; return; } int num2 = response.IndexOf('[', num); int num3 = FindMatchingBracket(response, num2); if (num2 < 0 || num3 < 0) { CachedTeamSeriesPaged = list; return; } string text = response.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = FindMatchingBrace(text, num5); if (num6 < 0) { break; } string text2 = text.Substring(num5, num6 - num5 + 1); TeamSeriesPagedEntry item = new TeamSeriesPagedEntry { series_id = ExtractJsonString(text2, "series_id"), completed_at = ExtractJsonString(text2, "completed_at"), winner_team = ExtractJsonInt(text2, "winner_team"), t1_series_wins = ExtractJsonInt(text2, "t1_series_wins"), t2_series_wins = ExtractJsonInt(text2, "t2_series_wins"), t1a = ParseSeriesSlot(text2, "t1a"), t1b = ParseSeriesSlot(text2, "t1b"), t2a = ParseSeriesSlot(text2, "t2a"), t2b = ParseSeriesSlot(text2, "t2b"), matches = ParseSeriesMatches(text2) }; list.Add(item); num4 = num6 + 1; } CachedTeamSeriesPaged = list; CachedTeamSeriesTotal = ExtractJsonInt(response, "total"); CachedTeamSeriesPage = reqPage; CachedTeamSeriesPageSize = reqPageSize; CachedTeamSeriesTotalPages = ExtractJsonInt(response, "total_pages"); } private static TeamSeriesSlot ParseSeriesSlot(string seriesObj, string slotKey) { int num = seriesObj.IndexOf("\"" + slotKey + "\":"); if (num < 0) { return new TeamSeriesSlot(); } int num2 = seriesObj.IndexOf('{', num); int num3 = FindMatchingBrace(seriesObj, num2); if (num2 < 0 || num3 < 0) { return new TeamSeriesSlot(); } string json = seriesObj.Substring(num2, num3 - num2 + 1); return new TeamSeriesSlot { steam_id = ExtractJsonString(json, "steam_id"), name = ExtractJsonString(json, "name"), title = ExtractJsonString(json, "title"), title_color = ExtractJsonString(json, "title_color"), rating = (int)ExtractJsonFloat(json, "rating"), rating_change = ExtractJsonFloat(json, "rating_change"), gold_earned = ExtractJsonInt(json, "gold_earned"), xp_earned = ExtractJsonInt(json, "xp_earned") }; } private static List ParseSeriesMatches(string seriesObj) { List list = new List(); int num = seriesObj.IndexOf("\"matches\":"); if (num < 0) { return list; } int num2 = seriesObj.IndexOf('[', num); int num3 = FindMatchingBracket(seriesObj, num2); if (num2 < 0 || num3 < 0) { return list; } string text = seriesObj.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('{', num4); if (num5 < 0) { break; } int num6 = FindMatchingBrace(text, num5); if (num6 < 0) { break; } string text2 = text.Substring(num5, num6 - num5 + 1); TeamSeriesMatch teamSeriesMatch = new TeamSeriesMatch { match_id = ExtractJsonString(text2, "match_id"), ended_at = ExtractJsonString(text2, "ended_at"), t1_rounds_won = ExtractJsonInt(text2, "t1_rounds_won"), t2_rounds_won = ExtractJsonInt(text2, "t2_rounds_won"), t1_points_total = ExtractJsonInt(text2, "t1_points_total"), t2_points_total = ExtractJsonInt(text2, "t2_points_total") }; int num7 = text2.IndexOf("\"cards_by_player\":"); if (num7 >= 0) { int num8 = text2.IndexOf('{', num7); int num9 = FindMatchingBrace(text2, num8); if (num8 >= 0 && num9 > num8) { string text3 = text2.Substring(num8 + 1, num9 - num8 - 1); int num10 = 0; while (num10 < text3.Length) { int num11 = text3.IndexOf('"', num10); if (num11 < 0) { break; } int num12 = text3.IndexOf('"', num11 + 1); if (num12 < 0) { break; } string key = text3.Substring(num11 + 1, num12 - num11 - 1); int num13 = text3.IndexOf('[', num12); int num14 = FindMatchingBracket(text3, num13); if (num13 < 0 || num14 < 0) { break; } string text4 = text3.Substring(num13 + 1, num14 - num13 - 1); List list2 = new List(); int num15 = 0; while (num15 < text4.Length) { int num16 = text4.IndexOf('"', num15); if (num16 < 0) { break; } int num17 = text4.IndexOf('"', num16 + 1); if (num17 < 0) { break; } list2.Add(text4.Substring(num16 + 1, num17 - num16 - 1)); num15 = num17 + 1; } teamSeriesMatch.cards_by_player[key] = list2; num10 = num14 + 1; } } } list.Add(teamSeriesMatch); num4 = num6 + 1; } return list; } public static void FetchTeamStats(string steamId) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/team/players/" + steamId + "/team-stats", delegate(bool success, string response) { if (!success) { return; } try { CachedTeamStats = new TeamStatsData { steam_id = ExtractJsonString(response, "steam_id"), display_name = ExtractJsonString(response, "display_name"), rating = ExtractJsonFloat(response, "rating"), rating_deviation = ExtractJsonFloat(response, "rating_deviation"), peak_rating = ExtractJsonFloat(response, "peak_rating"), completed_series = ExtractJsonInt(response, "completed_series"), series_wins = ExtractJsonInt(response, "series_wins"), series_losses = ExtractJsonInt(response, "series_losses"), series_win_rate = ExtractJsonFloat(response, "series_win_rate"), match_wins = ExtractJsonInt(response, "match_wins"), match_losses = ExtractJsonInt(response, "match_losses"), current_streak = ExtractJsonInt(response, "current_streak") }; NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogError((object)("[TEAM-STATS] parse: " + ex.Message)); } })); } public static void FetchTeamMatchHistory(string steamId, int limit = 50) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/team/players/{steamId}/team-matches?limit={limit}", delegate(bool success, string response) { if (!success) { return; } try { List list = new List(); if (string.IsNullOrEmpty(response) || response.Trim() == "[]") { CachedTeamMatchHistory = list; NativeUI.MarkDirty(); } else { string[] array = response.Split(new string[1] { "\"match_id\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = array[i]; TeamMatchHistoryEntry teamMatchHistoryEntry = new TeamMatchHistoryEntry { match_id = ExtractJsonString(text, ""), series_id = ExtractJsonString(text, "series_id"), ended_at = ExtractJsonString(text, "ended_at"), won = text.Contains("\"won\":true"), my_team = ExtractJsonInt(text, "my_team"), t1a_steam_id = ExtractJsonString(text, "t1a_steam_id"), t1a_name = ExtractJsonString(text, "t1a_name"), t1b_steam_id = ExtractJsonString(text, "t1b_steam_id"), t1b_name = ExtractJsonString(text, "t1b_name"), t2a_steam_id = ExtractJsonString(text, "t2a_steam_id"), t2a_name = ExtractJsonString(text, "t2a_name"), t2b_steam_id = ExtractJsonString(text, "t2b_steam_id"), t2b_name = ExtractJsonString(text, "t2b_name"), t1_rounds_won = ExtractJsonInt(text, "t1_rounds_won"), t2_rounds_won = ExtractJsonInt(text, "t2_rounds_won"), t1_points_total = ExtractJsonInt(text, "t1_points_total"), t2_points_total = ExtractJsonInt(text, "t2_points_total"), series_score = ExtractJsonString(text, "series_score"), series_rating_change = ExtractJsonFloat(text, "series_rating_change") }; try { int num = text.IndexOf("\"cards_by_player\""); if (num >= 0) { int num2 = text.IndexOf('{', num); int num3 = FindMatchingBrace(text, num2); if (num2 >= 0 && num3 > num2) { string text2 = text.Substring(num2 + 1, num3 - num2 - 1); int num4 = 0; while (num4 < text2.Length) { int num5 = text2.IndexOf('"', num4); if (num5 < 0) { break; } int num6 = text2.IndexOf('"', num5 + 1); if (num6 < 0) { break; } string key = text2.Substring(num5 + 1, num6 - num5 - 1); int num7 = text2.IndexOf('[', num6); int num8 = FindMatchingBracket(text2, num7); if (num7 < 0 || num8 < 0) { break; } string text3 = text2.Substring(num7 + 1, num8 - num7 - 1); List list2 = new List(); int num9 = 0; while (num9 < text3.Length) { int num10 = text3.IndexOf('{', num9); if (num10 < 0) { break; } int num11 = 1; int j; for (j = num10 + 1; j < text3.Length; j++) { if (num11 <= 0) { break; } if (text3[j] == '{') { num11++; } else if (text3[j] == '}') { num11--; } } string text4 = ExtractJsonString(text3.Substring(num10, j - num10), "card_name"); if (!string.IsNullOrEmpty(text4)) { list2.Add(text4); } num9 = j; } teamMatchHistoryEntry.cards_by_player[key] = list2; num4 = num8 + 1; } } } } catch { } list.Add(teamMatchHistoryEntry); } CachedTeamMatchHistory = list; Plugin.Log.LogInfo((object)$"[TEAM-HIST] loaded {list.Count} 2v2 matches"); NativeUI.MarkDirty(); } } catch (Exception ex) { Plugin.Log.LogError((object)("[TEAM-HIST] parse: " + ex.Message)); } })); } public static void FetchTeamLeaderboard(int limit = 200, string sortBy = "rating") { CachedTeamLeaderboardSort = sortBy; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest($"{baseUrl}/api/v1/team/leaderboard?limit={limit}&sort_by={sortBy}", delegate(bool success, string response) { if (!success) { return; } try { List list = new List(); string[] array = response.Split(new string[1] { "\"rank\":" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = array[i]; int rank = 0; try { rank = int.Parse(text[..text.IndexOf(',')]); } catch { } list.Add(new TeamLeaderboardEntry { rank = rank, steam_id = ExtractJsonString(text, "steam_id"), display_name = ExtractJsonString(text, "display_name"), rating = ExtractJsonInt(text, "rating"), rd = ExtractJsonInt(text, "rd"), completed_series = ExtractJsonInt(text, "completed_series"), series_wins = ExtractJsonInt(text, "series_wins"), series_losses = ExtractJsonInt(text, "series_losses"), win_rate = ExtractJsonFloat(text, "win_rate"), level = ExtractJsonInt(text, "level"), title = ExtractJsonString(text, "title"), title_color = ExtractJsonString(text, "title_color"), avg_teammate_elo = ExtractJsonInt(text, "avg_teammate_elo"), team_gold_earned = ExtractJsonInt(text, "team_gold_earned"), team_xp_earned = ExtractJsonInt(text, "team_xp_earned") }); } CachedTeamLeaderboard = list; CachedTeamLeaderboardTotal = ExtractJsonInt(response, "total_players"); NativeUI.MarkDirty(); Plugin.Log.LogInfo((object)$"[TEAM-LB] Loaded {list.Count} 2v2 ranked players"); } catch (Exception ex) { Plugin.Log.LogError((object)("[TEAM-LB] parse error: " + ex.Message)); } })); } public static void FetchBlockedPlayers(string steamId) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/players/blocks/" + steamId, delegate(bool success, string response) { if (success) { BlockedSteamIds.Clear(); int num = response.IndexOf("["); int num2 = response.IndexOf("]"); if (num >= 0 && num2 > num) { string text = response.Substring(num + 1, num2 - num - 1); if (!string.IsNullOrEmpty(text)) { string[] array = text.Split(','); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim().Trim('"'); if (!string.IsNullOrEmpty(text2)) { BlockedSteamIds.Add(text2); } } } } blocksLoaded = true; NativeUI.MarkDirty(); Plugin.Log.LogInfo((object)$"[BLOCKS] Loaded {BlockedSteamIds.Count} blocked players"); } })); } public static bool IsPlayerBlocked(string steamId) { return BlockedSteamIds.Contains(steamId); } public static void ReportDisconnect(string reporterSteamId, string disconnectedSteamId) { if (string.IsNullOrEmpty(reporterSteamId) || string.IsNullOrEmpty(disconnectedSteamId)) { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/report-disconnect?reporter_steam_id=" + Escape(reporterSteamId) + "&disconnected_steam_id=" + Escape(disconnectedSteamId), "", delegate(bool success, string response) { if (success) { Plugin.Log.LogInfo((object)("[DC] Reported disconnect by " + disconnectedSteamId + ": " + response)); } else { Plugin.Log.LogWarning((object)("[DC] Failed to report disconnect: " + response)); } })); } public static void BlockPlayer(string mySteamId, string targetSteamId, Action callback = null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/players/block?steam_id=" + Escape(mySteamId) + "&target_steam_id=" + Escape(targetSteamId) + "&sig=" + ComputeHmacHex("block:" + mySteamId + ":" + targetSteamId), "", delegate(bool success, string response) { if (success) { BlockedSteamIds.Add(targetSteamId); Plugin.Log.LogInfo((object)("[BLOCKS] Blocked " + targetSteamId)); NativeUI.MarkDirty(); } callback?.Invoke(success); })); } public static void UnblockPlayer(string mySteamId, string targetSteamId, Action callback = null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/players/unblock?steam_id=" + Escape(mySteamId) + "&target_steam_id=" + Escape(targetSteamId) + "&sig=" + ComputeHmacHex("unblock:" + mySteamId + ":" + targetSteamId), "", delegate(bool success, string response) { if (success) { BlockedSteamIds.Remove(targetSteamId); Plugin.Log.LogInfo((object)("[BLOCKS] Unblocked " + targetSteamId)); NativeUI.MarkDirty(); } callback?.Invoke(success); })); } private static void StampVersionHeader(UnityWebRequest req) { try { req.SetRequestHeader("X-Mod-Version", "1.28.2"); } catch { } } private static bool IsConsentBypassed(string url) { if (string.IsNullOrEmpty(url)) { return false; } return url.Contains("/api/v1/mod-version"); } private static bool ConsentBlocksRequest(string url) { if (Plugin.DataConsentGranted) { return false; } if (IsConsentBypassed(url)) { return false; } return true; } public static void OnConsentChanged() { if (Plugin.DataConsentGranted) { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { FetchPlayerStats(localSteamId); FetchMatchHistory(localSteamId); FetchAchievements(localSteamId); } FetchLeaderboard(); FetchRecentSeries(); ChatClient.Connect(); } else { CachedLeaderboard = null; CachedPlayerStats = null; CachedCardStats = null; CachedMatchHistory = null; CachedRecentSeries = null; CachedAchievements = null; CachedShopItems = null; CachedInventory = null; CachedActiveSeries = null; ChatClient.Disconnect(); if (Plugin.RankedEnabled != null && Plugin.RankedEnabled.Value) { Plugin.RankedEnabled.Value = false; Plugin.Log.LogInfo((object)"[CONSENT] Ranked mode disabled due to revoke"); } } NativeUI.MarkDirty(); } private static bool HandleVersionGate(UnityWebRequest req) { if (req.responseCode == 426) { if (!ForceUpdateRequired) { Plugin.Log.LogWarning((object)"[VERSION] Server returned 426 — mod is below required version, gating UI"); } ForceUpdateRequired = true; return true; } return false; } private static void NoteAttempt() { LastApiAttemptAt = Time.unscaledTime; } private static void NoteResult(bool success, long httpCode) { if (success) { LastApiSuccessAt = Time.unscaledTime; LastResponseWasMaintenance = false; } else if (httpCode == 503) { LastResponseWasMaintenance = true; } } private static IEnumerator GetRequest(string url, Action callback) { if (ConsentBlocksRequest(url)) { callback(arg1: false, "no-consent"); yield break; } NoteAttempt(); UnityWebRequest request = UnityWebRequest.Get(url); try { StampVersionHeader(request); request.timeout = 20; yield return request.SendWebRequest(); if (HandleVersionGate(request)) { callback(arg1: false, "outdated"); yield break; } bool flag = (int)request.result == 1; NoteResult(flag, request.responseCode); callback(flag, flag ? request.downloadHandler.text : request.error); } finally { ((IDisposable)request)?.Dispose(); } } private static IEnumerator PostRequest(string url, string json, Action callback) { if (ConsentBlocksRequest(url)) { callback(arg1: false, "no-consent"); yield break; } NoteAttempt(); UnityWebRequest request = new UnityWebRequest(url, "POST"); try { if (!string.IsNullOrEmpty(json)) { byte[] bytes = Encoding.UTF8.GetBytes(json); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); } request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); StampVersionHeader(request); request.timeout = 20; yield return request.SendWebRequest(); if (HandleVersionGate(request)) { callback(arg1: false, "outdated"); yield break; } bool flag = (int)request.result == 1; NoteResult(flag, request.responseCode); callback(flag, flag ? request.downloadHandler.text : request.error); } finally { ((IDisposable)request)?.Dispose(); } } private static IEnumerator PostRequestWithRetry(string url, string json, Action callback, int maxRetries = 3, float retryDelay = 2f) { if (ConsentBlocksRequest(url)) { callback(arg1: false, "no-consent"); yield break; } for (int attempt = 1; attempt <= maxRetries; attempt++) { NoteAttempt(); UnityWebRequest request = new UnityWebRequest(url, "POST"); try { if (!string.IsNullOrEmpty(json)) { byte[] bytes = Encoding.UTF8.GetBytes(json); request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); } request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); StampVersionHeader(request); request.timeout = 10; yield return request.SendWebRequest(); if (HandleVersionGate(request)) { callback(arg1: false, "outdated"); break; } bool num = (int)request.result == 1; NoteResult(num, request.responseCode); if (num) { callback(arg1: true, request.downloadHandler.text); break; } Plugin.Log.LogWarning((object)$"[HTTP] POST attempt {attempt}/{maxRetries} failed: {request.error}"); if (attempt < maxRetries) { yield return (object)new WaitForSeconds(retryDelay); } else { callback(arg1: false, request.error); } } finally { ((IDisposable)request)?.Dispose(); } } } public static void GenerateLinkCode(string steamId) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/players/link-code?steam_id=" + Escape(steamId), "", delegate(bool success, string response) { //IL_0076: 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) if (success) { string text = ExtractJsonString(response, "code"); if (!string.IsNullOrEmpty(text)) { Plugin.Log.LogInfo((object)("[LINK] Generated link code: " + text)); CompetitiveUI.ShowNotification("Link code: " + text, Color.cyan, 15f); NativeUI.SetLinkCode(text); } } else { Plugin.Log.LogWarning((object)("[LINK] Failed to generate code: " + response)); CompetitiveUI.ShowNotification("Failed to get link code", new Color(1f, 0.4f, 0.4f)); } })); } public static void FetchAchievements(string steamId) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/achievements/" + steamId, delegate(bool success, string response) { if (success) { try { Dictionary dictionary = new Dictionary(); string[] array = response.Split(new string[1] { "\"achievement_key\"" }, StringSplitOptions.None); for (int i = 1; i < array.Length; i++) { string text = ExtractJsonString(array[i], ""); if (!string.IsNullOrEmpty(text)) { bool unlocked = array[i].Contains("\"unlocked\":true") || array[i].Contains("\"unlocked\": true"); string unlocked_at = ExtractJsonString(array[i], "unlocked_at"); dictionary[text] = new AchievementData { achievement_key = text, unlocked = unlocked, unlocked_at = unlocked_at }; } } CachedAchievements = dictionary; NativeUI.MarkDirty(); Plugin.Log.LogInfo((object)$"[ACH] Loaded {dictionary.Count} achievements"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ACH] Parse error: " + ex.Message)); } } })); } public static void UnlockAchievement(string steamId, string achievementKey, string matchId = null) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } string s = ComputeHmacHex("achievement:" + steamId + ":" + achievementKey); string text = "{\"steam_id\":\"" + Escape(steamId) + "\",\"achievement_key\":\"" + Escape(achievementKey) + "\",\"hmac_signature\":\"" + Escape(s) + "\""; if (!string.IsNullOrEmpty(matchId)) { text = text + ",\"match_id\":\"" + Escape(matchId) + "\""; } text += "}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequestWithRetry(baseUrl + "/api/v1/achievements/unlock", text, delegate(bool success, string response) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (success) { string text2 = ExtractJsonString(response, "status"); string text3 = ExtractJsonString(response, "name"); if (text2 == "unlocked" && !string.IsNullOrEmpty(text3)) { CompetitiveUI.ShowNotification("Achievement Unlocked: " + text3 + "!", new Color(1f, 0.85f, 0.3f), 6f); Plugin.Log.LogInfo((object)("[ACH] Unlocked: " + achievementKey + " (" + text3 + ")")); } else { Plugin.Log.LogInfo((object)("[ACH] " + achievementKey + ": " + text2)); } FetchAchievements(steamId); } else { Plugin.Log.LogWarning((object)("[ACH] Unlock failed for " + achievementKey + ": " + response)); } })); } private static string Escape(string s) { if (string.IsNullOrEmpty(s)) { return ""; } return s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") .Replace("\r", "\\r"); } public static void SubmitBugReport(string steamId, string displayName, string description, string reproSteps, string severity, string category, string logText, Action done) { if (string.IsNullOrEmpty(steamId)) { done?.Invoke(arg1: false, "steam_id missing"); return; } if (logText != null && logText.Length > 3500000) { logText = logText.Substring(logText.Length - 3500000); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{"); stringBuilder.Append("\"steam_id\":\"" + Escape(steamId) + "\""); stringBuilder.Append(",\"display_name\":\"" + Escape(displayName ?? "") + "\""); stringBuilder.Append(",\"mod_version\":\"" + Escape("1.28.2") + "\""); stringBuilder.Append(",\"game_version\":\"" + Escape(Application.version ?? "") + "\""); stringBuilder.Append(",\"severity\":\"" + Escape(severity ?? "medium") + "\""); stringBuilder.Append(",\"category\":\"" + Escape(category ?? "other") + "\""); stringBuilder.Append(",\"description\":\"" + Escape(description ?? "") + "\""); if (!string.IsNullOrEmpty(reproSteps)) { stringBuilder.Append(",\"repro_steps\":\"" + Escape(reproSteps) + "\""); } if (!string.IsNullOrEmpty(logText)) { stringBuilder.Append(",\"log_text\":\"" + Escape(logText) + "\""); } stringBuilder.Append("}"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/bug-reports", stringBuilder.ToString(), delegate(bool ok, string response) { if (ok) { Plugin.Log.LogInfo((object)("[BUG-REPORT] submitted ok: " + response)); } else { Plugin.Log.LogWarning((object)("[BUG-REPORT] submit failed: " + response)); } done?.Invoke(ok, response); })); } public static string ReadLogTail(string path, int maxChars = 3500000) { try { if (string.IsNullOrEmpty(path) || !File.Exists(path)) { return ""; } using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using StreamReader streamReader = new StreamReader(stream); string text = streamReader.ReadToEnd(); if (text.Length <= maxChars) { return text; } return text.Substring(text.Length - maxChars); } catch (Exception ex) { return "[log read error: " + ex.Message + "]"; } } public static void FetchTournamentCurrent(string steamId, bool force = false) { if (!force && Time.unscaledTime < _tournamentRefreshAt) { return; } _tournamentRefreshAt = Time.unscaledTime + 5f; string text = (string.IsNullOrEmpty(TournamentKind) ? "sync" : TournamentKind); string text2 = ((string.IsNullOrEmpty(steamId) || steamId == "unknown") ? ("?kind=" + text) : ("?steam_id=" + Escape(steamId) + "&kind=" + text)); ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/tournaments/current" + text2, delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { CachedTournamentJson = response; CachedTournament = ParseTournament(response); NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TOURNAMENT] parse failed: " + ex.Message)); } })); } private static TournamentSnapshot ParseTournament(string json) { return new TournamentSnapshot { tournament_id = ExtractString(json, "tournament_id"), status = ExtractString(json, "status"), kind = ExtractString(json, "kind"), default_start_ts = ExtractString(json, "default_start_ts"), scheduled_start_ts = ExtractString(json, "scheduled_start_ts"), lock_at = ExtractString(json, "lock_at"), started_at = ExtractString(json, "started_at"), ended_at = ExtractString(json, "ended_at"), min_players = ExtractInt(json, "min_players", 8), max_players = ExtractInt(json, "max_players", 16), my_signup_id = ExtractString(json, "my_signup_id"), my_ready = ExtractBool(json, "my_ready"), my_penalty_pct = ExtractFloat(json, "my_penalty_pct"), my_discord_linked = ExtractBool(json, "my_discord_linked"), force_vote_count = ExtractInt(json, "force_vote_count", 0), photon_region = ExtractString(json, "photon_region"), my_votes = ExtractStringArray(json, "my_votes"), time_slot_options = ExtractStringArray(json, "time_slot_options"), time_slot_tallies = ExtractObjectArray(json, "time_slot_tallies", (string raw) => new TimeVoteTally { slot_ts = ExtractString(raw, "slot_ts"), votes = ExtractInt(raw, "votes", 0) }), signups = ExtractObjectArray(json, "signups", (string raw) => new TournamentSignupRow { signup_id = ExtractString(raw, "signup_id"), steam_id = ExtractString(raw, "steam_id"), display_name = ExtractString(raw, "display_name"), is_speculative = ExtractBool(raw, "is_speculative"), seed = ExtractInt(raw, "seed", 0), penalty_at_signup = ExtractFloat(raw, "penalty_at_signup"), ready = ExtractBool(raw, "ready"), forfeited = ExtractBool(raw, "forfeited"), placed_rank = ExtractInt(raw, "placed_rank", 0), progress_label = ExtractString(raw, "progress_label") }), matches = ExtractObjectArray(json, "matches", (string raw) => new TournamentMatchRow { match_id = ExtractString(raw, "match_id"), round = ExtractInt(raw, "round", 0), bracket_side = ExtractString(raw, "bracket_side"), slot_idx = ExtractInt(raw, "slot_idx", 0), p1_signup_id = ExtractString(raw, "p1_signup_id"), p2_signup_id = ExtractString(raw, "p2_signup_id"), p1_display_name = ExtractString(raw, "p1_display_name"), p2_display_name = ExtractString(raw, "p2_display_name"), is_bye = ExtractBool(raw, "is_bye"), status = ExtractString(raw, "status"), series_id = ExtractString(raw, "series_id"), winner_signup_id = ExtractString(raw, "winner_signup_id"), p1_series_wins = ExtractInt(raw, "p1_series_wins", 0), p2_series_wins = ExtractInt(raw, "p2_series_wins", 0), deadline_at = ExtractString(raw, "deadline_at"), prereq_match_ids = ExtractStringArray(raw, "prereq_match_ids"), photon_room_name = ExtractString(raw, "photon_room_name") }) }; } private static string ExtractString(string json, string key) { if (string.IsNullOrEmpty(json)) { return null; } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return null; } int num2 = json.IndexOf(':', num); if (num2 < 0) { return null; } int i; for (i = num2 + 1; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length) { return null; } if (json[i] == 'n' && json.Length >= i + 4 && json.Substring(i, 4) == "null") { return null; } if (json[i] != '"') { return null; } int num3 = i + 1; StringBuilder stringBuilder = new StringBuilder(); for (int j = num3; j < json.Length; j++) { char c = json[j]; if (c == '\\' && j + 1 < json.Length) { stringBuilder.Append(json[j + 1]); j++; continue; } if (c == '"') { break; } stringBuilder.Append(c); } return stringBuilder.ToString(); } private static int ExtractInt(string json, string key, int def) { if (string.IsNullOrEmpty(json)) { return def; } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return def; } int num2 = json.IndexOf(':', num); if (num2 < 0) { return def; } int i; for (i = num2 + 1; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length) { return def; } int j; for (j = i; j < json.Length && (char.IsDigit(json[j]) || json[j] == '-'); j++) { } if (j == i) { return def; } if (!int.TryParse(json.Substring(i, j - i), out var result)) { return def; } return result; } private static float ExtractFloat(string json, string key) { if (string.IsNullOrEmpty(json)) { return 0f; } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return 0f; } int num2 = json.IndexOf(':', num); if (num2 < 0) { return 0f; } int i; for (i = num2 + 1; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length) { return 0f; } int j; for (j = i; j < json.Length && (char.IsDigit(json[j]) || json[j] == '-' || json[j] == '.' || json[j] == 'e' || json[j] == 'E' || json[j] == '+'); j++) { } if (j == i) { return 0f; } if (!float.TryParse(json.Substring(i, j - i), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 0f; } return result; } private static bool ExtractBool(string json, string key) { if (string.IsNullOrEmpty(json)) { return false; } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return false; } int num2 = json.IndexOf(':', num); if (num2 < 0) { return false; } int i; for (i = num2 + 1; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i + 4 <= json.Length) { return json.Substring(i, 4) == "true"; } return false; } private static string[] ExtractStringArray(string json, string key) { if (string.IsNullOrEmpty(json)) { return Array.Empty(); } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return Array.Empty(); } int num2 = json.IndexOf('[', num); if (num2 < 0) { return Array.Empty(); } int num3 = json.IndexOf(']', num2); if (num3 < 0) { return Array.Empty(); } string text = json.Substring(num2 + 1, num3 - num2 - 1); List list = new List(); int num4 = 0; while (num4 < text.Length) { int num5 = text.IndexOf('"', num4); if (num5 < 0) { break; } int num6 = text.IndexOf('"', num5 + 1); if (num6 < 0) { break; } list.Add(text.Substring(num5 + 1, num6 - num5 - 1)); num4 = num6 + 1; } return list.ToArray(); } private static T[] ExtractObjectArray(string json, string key, Func parse) { if (string.IsNullOrEmpty(json)) { return Array.Empty(); } int num = json.IndexOf("\"" + key + "\""); if (num < 0) { return Array.Empty(); } int num2 = json.IndexOf('[', num); if (num2 < 0) { return Array.Empty(); } List list = new List(); int num3 = 0; int num4 = -1; for (int i = num2; i < json.Length; i++) { switch (json[i]) { case '[': num3++; continue; case ']': num3--; if (num3 != 0) { continue; } break; case '{': if (num4 < 0) { num4 = i; } num3++; continue; case '}': num3--; if (num3 == 1 && num4 >= 0) { list.Add(parse(json.Substring(num4, i - num4 + 1))); num4 = -1; } continue; default: continue; } break; } return list.ToArray(); } public static void TournamentSignup(string tournamentId, string steamId, string displayName) { string text = ""; try { text = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { text = ""; } string json = "{\"steam_id\":\"" + Escape(steamId) + "\",\"display_name\":\"" + Escape(displayName ?? steamId) + "\",\"region\":\"" + Escape(text) + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/tournaments/" + tournamentId + "/signup", json, delegate(bool s, string r) { //IL_0023: 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) if (s) { FetchTournamentCurrent(steamId, force: true); CompetitiveUI.ShowNotification("Signed up for tournament", new Color(0.4f, 1f, 0.5f)); } else { CompetitiveUI.ShowNotification(ExtractErrorDetail(r) ?? "Signup failed", new Color(1f, 0.4f, 0.4f)); } })); } public static void TournamentUnsignup(string tournamentId, string steamId) { string json = "{\"steam_id\":\"" + Escape(steamId) + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/tournaments/" + tournamentId + "/unsignup", json, delegate(bool s, string r) { //IL_0023: 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) if (s) { FetchTournamentCurrent(steamId, force: true); CompetitiveUI.ShowNotification("Left tournament signup", new Color(0.9f, 0.9f, 0.4f)); } else { CompetitiveUI.ShowNotification(ExtractErrorDetail(r) ?? "Failed", new Color(1f, 0.4f, 0.4f)); } })); } public static void TournamentTimeVote(string tournamentId, string steamId, string[] slotIsos) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{\"steam_id\":\"").Append(Escape(steamId)).Append("\",\"slot_ts\":["); for (int i = 0; i < slotIsos.Length; i++) { if (i > 0) { stringBuilder.Append(','); } stringBuilder.Append('"').Append(Escape(slotIsos[i])).Append('"'); } stringBuilder.Append("]}"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/tournaments/" + tournamentId + "/time-vote", stringBuilder.ToString(), delegate(bool s, string r) { if (s) { FetchTournamentCurrent(steamId, force: true); } })); } public static void TournamentForceStartVote(string tournamentId, string steamId) { string json = "{\"steam_id\":\"" + Escape(steamId) + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/tournaments/" + tournamentId + "/force-start-vote", json, delegate(bool s, string r) { if (s) { FetchTournamentCurrent(steamId, force: true); } })); } public static void TournamentReady(string tournamentId, string steamId) { string json = "{\"steam_id\":\"" + Escape(steamId) + "\"}"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(PostRequest(baseUrl + "/api/v1/tournaments/" + tournamentId + "/ready", json, delegate(bool s, string r) { if (s) { FetchTournamentCurrent(steamId, force: true); } })); } private static string ExtractErrorDetail(string response) { if (string.IsNullOrEmpty(response)) { return null; } try { return ExtractString(response, "detail"); } catch { return null; } } public static void FetchPlayerTournaments(string steamId, Action onDone = null) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown") { return; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/tournaments/players/" + Escape(steamId) + "/tournaments?limit=8", delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { PlayerTournamentHistory value = new PlayerTournamentHistory { steam_id = (ExtractString(response, "steam_id") ?? steamId), winner_count = ExtractInt(response, "winner_count", 0), runner_up_count = ExtractInt(response, "runner_up_count", 0), third_place_count = ExtractInt(response, "third_place_count", 0), participant_count = ExtractInt(response, "participant_count", 0), recent = ExtractObjectArray(response, "recent", (string raw) => new PlayerTournamentEntry { tournament_id = ExtractString(raw, "tournament_id"), ended_at = ExtractString(raw, "ended_at"), placed_rank = ExtractInt(raw, "placed_rank", 0), kind = ExtractString(raw, "kind"), signup_count = ExtractInt(raw, "signup_count", 0), winner_display_name = ExtractString(raw, "winner_display_name") }) }; CachedPlayerTournaments[steamId] = value; NativeUI.MarkDirty(); onDone?.Invoke(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TOURNAMENT-HIST] parse: " + ex.Message)); } })); } public static void FetchMyActiveTournamentMatches(string steamId) { if (string.IsNullOrEmpty(steamId) || steamId == "unknown" || Time.unscaledTime < _myActiveMatchesRefreshAt) { return; } _myActiveMatchesRefreshAt = Time.unscaledTime + 20f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/tournaments/my-active-matches?steam_id=" + Escape(steamId), delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { List list = new List(); string[] array = ExtractObjectArray(response, "matches", (string r) => r); foreach (string json in array) { list.Add(new ActiveTournamentMatch { tournament_id = ExtractString(json, "tournament_id"), kind = ExtractString(json, "kind"), match_id = ExtractString(json, "match_id"), status = ExtractString(json, "status"), bracket_side = ExtractString(json, "bracket_side"), round = ExtractInt(json, "round", 0), opponent_steam_id = ExtractString(json, "opponent_steam_id"), opponent_display_name = ExtractString(json, "opponent_display_name"), photon_room_name = ExtractString(json, "photon_room_name"), photon_region = ExtractString(json, "photon_region"), my_ready = ExtractBool(json, "my_ready"), opp_ready = ExtractBool(json, "opp_ready") }); } CachedMyActiveTournamentMatches = list; NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TOURNAMENT-ACTIVE] parse: " + ex.Message)); } })); } public static void FetchSiteTournamentHistory() { ((MonoBehaviour)Plugin.Instance).StartCoroutine(GetRequest(baseUrl + "/api/v1/tournaments/history?limit=12", delegate(bool success, string response) { if (!success || string.IsNullOrEmpty(response)) { return; } try { CachedSiteTournamentHistory = ExtractObjectArray("{\"_hist\":" + response + "}", "_hist", (string raw) => new PlayerTournamentEntry { tournament_id = ExtractString(raw, "tournament_id"), ended_at = ExtractString(raw, "ended_at"), placed_rank = 0, kind = ExtractString(raw, "kind"), signup_count = ExtractInt(raw, "signup_count", 0), winner_display_name = ExtractString(raw, "winner_display_name") }); NativeUI.MarkDirty(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TOURNAMENT-SITEHIST] parse: " + ex.Message)); } })); } } public static class CardImageLoader { private const int EXPECTED_CARD_COUNT = 67; private static volatile Dictionary _filesByKey; private static readonly Dictionary _spriteCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static bool _scanAttempted; private static string _cardsDir; public static bool IsAvailable { get { if (_filesByKey != null) { return _filesByKey.Count > 0; } return false; } } public static int Count => _filesByKey?.Count ?? 0; public static void Initialize() { if (_scanAttempted) { return; } _scanAttempted = true; try { _cardsDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "cards"); _filesByKey = ScanCardsDir(); int count = _filesByKey.Count; if (count >= 67) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[CARD-ART] indexed {count} card images from {_cardsDir}"); } } else { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)$"[CARD-ART] only {count}/{67} card images present at {_cardsDir}. Reinstall via the mod manager if popups / tier list export look broken."); } } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[CARD-ART] init failed: " + ex.Message)); } _filesByKey = _filesByKey ?? new Dictionary(); } } private static Dictionary ScanCardsDir() { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); if (string.IsNullOrEmpty(_cardsDir) || !Directory.Exists(_cardsDir)) { return dictionary; } string[] array = new string[3] { "*.jpg", "*.jpeg", "*.png" }; foreach (string searchPattern in array) { string[] files = Directory.GetFiles(_cardsDir, searchPattern); foreach (string text in files) { string key = NormalizeKey(Path.GetFileNameWithoutExtension(text)); if (!dictionary.ContainsKey(key)) { dictionary[key] = text; } } } return dictionary; } public static Sprite GetSprite(string cardName) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(cardName)) { return null; } if (!_scanAttempted) { Initialize(); } Dictionary filesByKey = _filesByKey; if (filesByKey == null) { return null; } string text = null; try { text = CardRarityLookup.GetCanonicalName(cardName); } catch { } string text2 = NormalizeKey(text ?? cardName); string text3 = NormalizeKey(cardName); if (_spriteCache.TryGetValue(text2, out var value) && (Object)(object)value != (Object)null) { return value; } if (text2 != text3 && _spriteCache.TryGetValue(text3, out var value2) && (Object)(object)value2 != (Object)null) { return value2; } string value3 = null; string text4 = null; if (filesByKey.TryGetValue(text2, out value3)) { text4 = text2; } else if (filesByKey.TryGetValue(text3, out value3)) { text4 = text3; } if (value3 == null) { return null; } try { byte[] array = File.ReadAllBytes(value3); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; if (!ImageConversion.LoadImage(val, array)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[CARD-ART] LoadImage failed for " + value3)); } return null; } ((Texture)val).filterMode = (FilterMode)1; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val2).name = "CardArt_" + text4; ((Object)val2).hideFlags = (HideFlags)61; _spriteCache[text4] = val2; return val2; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[CARD-ART] failed to load " + value3 + ": " + ex.Message)); } return null; } } private static string NormalizeKey(string s) { if (string.IsNullOrEmpty(s)) { return ""; } StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { if (c != ' ' && c != '-' && c != '\'' && c != '.' && c != '_') { stringBuilder.Append(char.ToLowerInvariant(c)); } } return stringBuilder.ToString(); } } public static class ChatClient { private static ClientWebSocket socket; private static CancellationTokenSource cts; private static Task loopTask; private static volatile bool running; private static readonly ConcurrentQueue sendQueue = new ConcurrentQueue(); private static SemaphoreSlim sendSignal; public static Action OnMessage; public static bool IsConnected { get { if (socket != null) { return socket.State == WebSocketState.Open; } return false; } } public static void Connect() { if (running) { return; } if (!Plugin.DataConsentGranted) { Plugin.Log.LogInfo((object)"[CHAT] Connect skipped — no data consent"); return; } running = true; cts = new CancellationTokenSource(); sendSignal = new SemaphoreSlim(0); loopTask = Task.Run(() => RunLoop(cts.Token)); } public static void Disconnect() { running = false; try { cts?.Cancel(); } catch { } try { sendSignal?.Release(); } catch { } try { if (socket != null && socket.State == WebSocketState.Open) { socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None).Wait(1000); } } catch { } socket = null; } public static void Send(string steamId, string displayName, string message) { if (string.IsNullOrEmpty(message)) { return; } string item = "{\"steam_id\":\"" + JsonEscape(steamId ?? "") + "\",\"display_name\":\"" + JsonEscape(displayName ?? "") + "\",\"message\":\"" + JsonEscape(message) + "\"}"; sendQueue.Enqueue(item); try { sendSignal?.Release(); } catch { } Plugin.Log.LogInfo((object)("[CHAT] queued: " + message)); ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; int num = ((cachedPlayerStats != null) ? ((int)Math.Round(cachedPlayerStats.rating)) : 0); string s = cachedPlayerStats?.active_title ?? ""; string s2 = cachedPlayerStats?.active_title_color ?? ""; string obj2 = "{\"source\":\"ingame\",\"steam_id\":\"" + JsonEscape(steamId ?? "") + "\",\"display_name\":\"" + JsonEscape(displayName ?? "") + "\",\"rating\":" + num + ",\"title\":\"" + JsonEscape(s) + "\",\"title_color\":\"" + JsonEscape(s2) + "\",\"message\":\"" + JsonEscape(message) + "\"}"; try { OnMessage?.Invoke(obj2); } catch { } } private static async Task RunLoop(CancellationToken token) { int backoffSec = 2; string text = Plugin.ApiBaseUrl?.Value ?? "http://competitive-rounds.duckdns.org:8443"; string wsUrl = text.Replace("https://", "wss://").Replace("http://", "ws://") + "/api/v1/ws/chat"; while (running && !token.IsCancellationRequested) { Task senderTask = null; try { _ = 2; try { socket = new ClientWebSocket(); socket.Options.SetRequestHeader("X-Mod-Version", "1.28.2"); await socket.ConnectAsync(new Uri(wsUrl), token); Plugin.Log.LogInfo((object)("[CHAT] WS connected: " + wsUrl)); backoffSec = 2; try { ApiClient.FetchRecentChat(); } catch { } senderTask = Task.Run(() => SendLoop(socket, token)); Task.Run(() => KeepAliveLoop(socket, token)); byte[] buffer = new byte[8192]; StringBuilder msg = new StringBuilder(); while (socket.State == WebSocketState.Open && !token.IsCancellationRequested) { ArraySegment buffer2 = new ArraySegment(buffer); WebSocketReceiveResult webSocketReceiveResult; try { webSocketReceiveResult = await socket.ReceiveAsync(buffer2, token); } catch (WebSocketException ex) { Plugin.Log.LogWarning((object)("[CHAT] recv error: " + ex.Message)); break; } if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close) { Plugin.Log.LogWarning((object)$"[CHAT] WS close from server: {webSocketReceiveResult.CloseStatus} {webSocketReceiveResult.CloseStatusDescription}"); try { await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "closing", CancellationToken.None); } catch { } break; } msg.Append(Encoding.UTF8.GetString(buffer, 0, webSocketReceiveResult.Count)); if (webSocketReceiveResult.EndOfMessage) { string text2 = msg.ToString(); msg.Clear(); try { OnMessage?.Invoke(text2); } catch { } Plugin.Log.LogInfo((object)("[CHAT] <- " + text2)); } } } catch (Exception ex2) when (!token.IsCancellationRequested) { Plugin.Log.LogWarning((object)$"[CHAT] WS error: {ex2.Message} (reconnect in {backoffSec}s)"); } } finally { try { sendSignal?.Release(); } catch { } if (senderTask != null) { try { await senderTask; } catch { } } try { socket?.Dispose(); } catch { } socket = null; } if (!running || token.IsCancellationRequested) { break; } try { await Task.Delay(backoffSec * 1000, token); } catch { } backoffSec = Math.Min(backoffSec * 2, 60); } Plugin.Log.LogInfo((object)"[CHAT] WS loop exited"); } private static async Task SendLoop(ClientWebSocket ws, CancellationToken token) { while (!token.IsCancellationRequested && ws.State == WebSocketState.Open) { try { await sendSignal.WaitAsync(token); } catch { break; } string json; while (sendQueue.TryDequeue(out json)) { if (ws.State != WebSocketState.Open) { sendQueue.Enqueue(json); return; } byte[] bytes = Encoding.UTF8.GetBytes(json); try { await ws.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, endOfMessage: true, token); Plugin.Log.LogInfo((object)$"[CHAT] -> sent ({bytes.Length}B)"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CHAT] send failed: " + ex.Message + " — requeueing")); sendQueue.Enqueue(json); return; } } } } private static async Task KeepAliveLoop(ClientWebSocket ws, CancellationToken token) { while (!token.IsCancellationRequested && ws.State == WebSocketState.Open) { try { await Task.Delay(25000, token); } catch { break; } if (ws.State != WebSocketState.Open) { break; } sendQueue.Enqueue("{\"type\":\"ping\"}"); try { sendSignal?.Release(); } catch { } } } private static string JsonEscape(string s) { if (string.IsNullOrEmpty(s)) { return ""; } StringBuilder stringBuilder = new StringBuilder(s.Length); foreach (char c in s) { switch (c) { case '\\': stringBuilder.Append("\\\\"); continue; case '"': stringBuilder.Append("\\\""); continue; case '\n': stringBuilder.Append("\\n"); continue; case '\r': stringBuilder.Append("\\r"); continue; case '\t': stringBuilder.Append("\\t"); continue; } if (c < ' ') { stringBuilder.Append($"\\u{(int)c:x4}"); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } } public static class CompetitiveUI { private struct QueuedNotif { public string text; public Color color; public float dur; } public struct CardHoverRegion { public Rect screenRect; public string fullCardLine; public bool isOpponent; public string titleOverride; public string bodyOverride; } public static int LastKnownLevel = -1; private static float fpsTimer = 0f; private static int fpsCnt = 0; private static float fpsVal = 0f; private static GUIStyle fpsStyle; private static string notifText = ""; private static Color notifColor = Color.white; private static float notifTimer = 0f; private static List notifQueue = new List(); private static GUIStyle notifStyle; private static GUIStyle statusStyle; private static AudioClip matchFoundClip; private static GameObject soundObj; private static GUIStyle mapToastStyle; private static GUIStyle compareSearchStyle; private static GUIStyle compareSearchHintStyle; private static bool compareSearchFocused = false; private const string CMP_SEARCH_CTRL = "CmpSearchField"; private static readonly List _cardHoverRegions = new List(40); private static GUIStyle _cardTipTitleStyle; private static GUIStyle _cardTipBodyStyle; private static GUIStyle stuckTitleStyle; private static GUIStyle stuckTextStyle; private static GUIStyle stuckButtonStyle; private static readonly string[] BUG_STATUSES = new string[5] { "open", "triaged", "resolved", "wontfix", "dupe" }; private static bool bugAdminOpen = false; private static string bugAdminSelectedId = null; private static Vector2 bugAdminListScroll; private static Vector2 bugAdminDetailScroll; private static bool bugAdminLoading = false; private static GUIStyle bugAdminRowStyle; private static GUIStyle bugAdminDetailStyle; private static GUIStyle bugAdminTabStyle; private static GUIStyle bugAdminTabActiveStyle; private static string bugAdminCommentDraft = ""; private static int bugAdminStatusIdx = 0; private static string bugAdminActionStatus = ""; private static string bugAdminLookup = ""; private static GUIStyle inputKeyStyle; private static GUIStyle inputKeySmallStyle; private static GUIStyle blockDbgStyle; private static GUIStyle blockDbgSmallStyle; private static GUIStyle ingameChatStyle; private static bool adminPromptOpen = false; private static string adminPromptMode = ""; private static string adminInputA = ""; private static string adminInputB = ""; private static GUIStyle adminFieldStyle; private static GUIStyle adminLabelStyle; private static readonly string[] ADMIN_ACHIEVEMENT_KEYS = new string[13] { "untouchable", "silent_assassin", "total_mayhem", "fragile_perfection", "no_escape", "rise_from_the_ashes", "the_comeback_kid", "stacked_deck", "regicide", "pacifist", "immovable_object", "master_rank", "team_sweep" }; private static readonly string[] BUG_SEVERITIES = new string[4] { "low", "medium", "high", "crash" }; private static readonly string[] BUG_CATEGORIES = new string[4] { "ui", "gameplay", "network", "other" }; private static bool bugModalOpen = false; private static string bugDescription = ""; private static string bugRepro = ""; private static int bugSeverityIdx = 1; private static int bugCategoryIdx = 3; private static bool bugSendLogs = true; private static string bugSubmitStatus = ""; private static bool bugSubmitting = false; private static Vector2 bugDescScroll; private static Vector2 bugReproScroll; private static GUIStyle bugTitleStyle; private static GUIStyle bugLabelStyle; private static GUIStyle bugFieldStyle; private static GUIStyle bugAreaStyle; private static GUIStyle bugButtonStyle; private static GUIStyle bugBtnPickedStyle; private const int BUNDLE_CAP_BEP_CURRENT = 1500000; private const int BUNDLE_CAP_BEP_PREV = 1000000; private const int BUNDLE_CAP_UNITY = 1000000; private static bool logViewerOpen = false; private static int logViewerTab = 0; private static Vector2 logViewerScroll; private static string logViewerBepCache; private static string logViewerBepPrevCache; private static string logViewerUniCache; private static GUIStyle logViewerStyle; private static GUIStyle logViewerTabStyle; private static GUIStyle logViewerTabActiveStyle; private static Type s_eventSystemType; private static PropertyInfo s_eventSystemCurrentProp; private static PropertyInfo s_eventSystemSelectedProp; private static bool chatInputOpen = false; private static bool chatJustOpened = false; private static string chatInputText = ""; private static GUIStyle chatStyle; private static GUIStyle consentTitleStyle; private static GUIStyle consentBodyStyle; private static GameObject consentBlockerGO; private static GUIStyle scoreStyle; public static bool IsCompareSearchFocused => compareSearchFocused; public static bool IsChatInputOpen => chatInputOpen; public static void ToggleOverlay() { NativeUI.Toggle(); } public static void ShowNotification(string text, Color color, float duration = 3f) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (Plugin.ShowNotifications.Value) { notifText = text; notifColor = color; notifTimer = duration; } } public static void QueueNotification(string text, Color color, float duration = 3f) { //IL_0024: 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) if (Plugin.ShowNotifications.Value) { notifQueue.Add(new QueuedNotif { text = text, color = color, dur = duration }); } } public static void PlayMatchFoundSound() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown try { if ((Object)(object)matchFoundClip == (Object)null) { int num = 44100; float num2 = 0.45f; int num3 = (int)((float)num * num2); matchFoundClip = AudioClip.Create("MatchFound", num3, 1, num, false); float[] array = new float[num3]; int num4 = num3 / 2; for (int i = 0; i < num3; i++) { float num5 = (float)i / (float)num; float num6 = ((i < num4) ? 660f : 880f); array[i] = Mathf.Sin(MathF.PI * 2f * num6 * num5) * 0.35f; float num7 = ((i < num4) ? ((float)i / (float)num4) : ((float)(i - num4) / (float)(num3 - num4))); float num8 = Mathf.Clamp01(num7 * 10f) * Mathf.Clamp01((1f - num7) * 5f); array[i] *= num8; } matchFoundClip.SetData(array, 0); } if ((Object)(object)soundObj == (Object)null) { soundObj = new GameObject("CR_Sound"); ((Object)soundObj).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)soundObj); } AudioSource val = soundObj.GetComponent(); if ((Object)(object)val == (Object)null) { val = soundObj.AddComponent(); } val.clip = matchFoundClip; val.volume = 0.7f; val.Play(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SOUND] Match found sound failed: " + ex.Message)); } } public static void ResetStyles() { } public static void CacheRaycasters() { } public static void MarkDirty() { NativeUI.MarkDirty(); } public static void Tick() { NativeUI.Tick(); } public static void DrawUI() { DrawFPS(); DrawNotification(); DrawMatchStatus(); DrawInGameChat(); DrawChatInput(); DrawAdminPrompt(); DrawBugReportModal(); DrawBugReportAdminViewer(); DrawLogViewerModal(); DrawBlockDebug(); DrawInputOverlay(); DrawCardHoverTooltip(); DrawCompareSearch(); DrawMapColorToast(); NativeUI.SetClickBlocker(bugModalOpen || logViewerOpen || bugAdminOpen); DrawConsentModal(); } private static void DrawMapColorToast() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_005c: Expected O, but got Unknown try { if (Time.unscaledTime >= MapColorState.ToastUntil) { return; } string toastText = MapColorState.ToastText; if (!string.IsNullOrEmpty(toastText)) { if (mapToastStyle == null) { mapToastStyle = new GUIStyle(GUI.skin.label) { fontSize = 22, alignment = (TextAnchor)4, fontStyle = (FontStyle)1, richText = true }; } float num = 460f; float num2 = 40f; float num3 = ((float)Screen.width - num) / 2f; float num4 = (float)Screen.height - 120f; float num5 = Mathf.Clamp01((MapColorState.ToastUntil - Time.unscaledTime) / 0.6f); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.55f * num5); GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(1f, 1f, 1f, num5); GUI.Label(new Rect(num3, num4, num, num2), "Map skin: " + toastText + "", mapToastStyle); GUI.color = color; } } catch { } } private static void DrawCompareSearch() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_007d: 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_008a: 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_009d: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) compareSearchFocused = false; try { if (!NativeUI.IsOpen || NativeUI.CurrentTab != 9) { return; } Rect compareSearchScreenRect = NativeUI.GetCompareSearchScreenRect(); if (!(((Rect)(ref compareSearchScreenRect)).width < 1f) && !(((Rect)(ref compareSearchScreenRect)).height < 1f)) { if (compareSearchStyle == null) { compareSearchStyle = new GUIStyle(GUI.skin.textField) { fontSize = 13, alignment = (TextAnchor)3 }; } if (compareSearchHintStyle == null) { compareSearchHintStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, alignment = (TextAnchor)3, richText = true }; } float num = Mathf.Max(((Rect)(ref compareSearchScreenRect)).height, 22f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref compareSearchScreenRect)).x, ((Rect)(ref compareSearchScreenRect)).y, Mathf.Max(((Rect)(ref compareSearchScreenRect)).width, 200f), num); string text = NativeUI.CompareSearch ?? ""; GUI.SetNextControlName("CmpSearchField"); string text2 = GUI.TextField(val, text, compareSearchStyle); compareSearchFocused = GUI.GetNameOfFocusedControl() == "CmpSearchField"; if (string.IsNullOrEmpty(text2)) { GUI.Label(new Rect(((Rect)(ref val)).x + 6f, ((Rect)(ref val)).y, ((Rect)(ref val)).width - 8f, num), "search players...", compareSearchHintStyle); } if (text2 != text) { NativeUI.CompareSearch = text2; NativeUI.MarkDirty(); } } } catch { } } public static void ClearCardHoverRegions() { _cardHoverRegions.Clear(); } public static void RegisterCardHoverRegion(Rect screenRect, string fullCardLine, bool isOpponent) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) RegisterCardHoverRegion(screenRect, fullCardLine, isOpponent, null, null); } public static void RegisterCardHoverRegion(Rect screenRect, string fullCardLine, bool isOpponent, string titleOverride, string bodyOverride) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(fullCardLine) || !string.IsNullOrEmpty(bodyOverride)) { _cardHoverRegions.Add(new CardHoverRegion { screenRect = screenRect, fullCardLine = fullCardLine, isOpponent = isOpponent, titleOverride = titleOverride, bodyOverride = bodyOverride }); } } private static void DrawCardHoverTooltip() { //IL_0025: 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_002f: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) if (!NativeUI.IsOpen || (NativeUI.CurrentTab != 0 && NativeUI.CurrentTab != 8) || _cardHoverRegions.Count == 0) { return; } Vector2 val = Vector2.op_Implicit(Input.mousePosition); CardHoverRegion? cardHoverRegion = null; for (int num = _cardHoverRegions.Count - 1; num >= 0; num--) { CardHoverRegion cardHoverRegion2 = _cardHoverRegions[num]; if (((Rect)(ref cardHoverRegion2.screenRect)).Contains(val)) { cardHoverRegion = _cardHoverRegions[num]; break; } } if (!cardHoverRegion.HasValue) { return; } if (_cardTipTitleStyle == null) { _cardTipTitleStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; _cardTipBodyStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, wordWrap = true, alignment = (TextAnchor)0 }; } string text; int num2; if (cardHoverRegion.Value.bodyOverride != null) { text = cardHoverRegion.Value.bodyOverride; num2 = 1; for (int i = 0; i < text.Length; i++) { if (text[i] == '\n') { num2++; } } } else { string fullCardLine = cardHoverRegion.Value.fullCardLine; string[] array; try { array = fullCardLine.Split(','); } catch { array = new string[1] { fullCardLine }; } num2 = 0; StringBuilder stringBuilder = new StringBuilder(); string[] array2 = array; for (int j = 0; j < array2.Length; j++) { string value = array2[j].Trim(); if (!string.IsNullOrEmpty(value)) { num2++; stringBuilder.Append("• ").Append(value).Append('\n'); } } text = stringBuilder.ToString().TrimEnd(); } string text2 = ((cardHoverRegion.Value.titleOverride != null) ? cardHoverRegion.Value.titleOverride : (cardHoverRegion.Value.isOpponent ? "Opponent's picks" : "Your picks")); bool num3 = !string.IsNullOrEmpty(text2); float num4 = 260f; float num5 = 16f; float num6 = (num3 ? 22f : 6f); float num7 = num6 + (float)num2 * num5 + 8f; float num8 = Input.mousePosition.x + 14f; float num9 = (float)Screen.height - Input.mousePosition.y + 14f; if (num8 + num4 > (float)Screen.width) { num8 = (float)Screen.width - num4 - 4f; } if (num9 + num7 > (float)Screen.height) { num9 = (float)Screen.height - num7 - 4f; } if (num9 < 4f) { num9 = 4f; } GUI.DrawTexture(new Rect(num8, num9, num4, num7), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.06f, 0.07f, 0.1f, 0.97f), 0f, 0f); Color val2 = (cardHoverRegion.Value.isOpponent ? new Color(0.95f, 0.55f, 0.45f, 0.9f) : new Color(0.4f, 0.7f, 1f, 0.9f)); GUI.DrawTexture(new Rect(num8, num9, num4, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(num8, num9 + num7 - 1f, num4, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(num8, num9, 1f, num7), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(num8 + num4 - 1f, num9, 1f, num7), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); if (num3) { GUI.Label(new Rect(num8 + 8f, num9 + 6f, num4 - 16f, 18f), "" + text2 + "", _cardTipTitleStyle); } GUI.Label(new Rect(num8 + 8f, num9 + num6, num4 - 16f, num7 - num6 - 4f), "" + text + "", _cardTipBodyStyle); } private static void DrawMatchFoundStuckOverlay() { //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (!GameStateWatcher.ShouldShowMatchFoundStuckOverlay || NativeUI.IsOpen) { return; } if (stuckTitleStyle == null) { stuckTitleStyle = new GUIStyle(GUI.skin.label) { fontSize = 17, richText = true, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; stuckTextStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true, wordWrap = true, alignment = (TextAnchor)0 }; stuckButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 14 }; } float num = 560f; float num2 = 132f; float num3 = ((float)Screen.width - num) / 2f; float num4 = 60f; GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.1f, 0.06f, 0.06f, 0.94f), 0f, 0f); Color val = default(Color); ((Color)(ref val))..ctor(0.95f, 0.65f, 0.2f, 0.9f); GUI.DrawTexture(new Rect(num3, num4, num, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); GUI.DrawTexture(new Rect(num3, num4 + num2 - 1f, num, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); GUI.DrawTexture(new Rect(num3, num4, 1f, num2), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); GUI.DrawTexture(new Rect(num3 + num - 1f, num4, 1f, num2), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); int secondsInUnstartedRoom = GameStateWatcher.SecondsInUnstartedRoom; GUI.Label(new Rect(num3 + 14f, num4 + 8f, num - 28f, 22f), "Match-found screen might be stuck", stuckTitleStyle); GUI.Label(new Rect(num3 + 14f, num4 + 32f, num - 28f, 50f), $"In this Photon room for {secondsInUnstartedRoom}s with no match started. " + "Vanilla matchmaking sometimes hangs here when one player has ROUNDS unfocused. Click into the ROUNDS window first and try space again, or use the escape hatch below.", stuckTextStyle); if (GUI.Button(new Rect(num3 + 14f, num4 + num2 - 38f, 220f, 28f), "Force exit room", stuckButtonStyle)) { try { PhotonNetwork.LeaveRoom(true); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[STUCK] LeaveRoom failed: " + ex.Message)); } GameStateWatcher.DismissMatchFoundStuckOverlay(); } if (GUI.Button(new Rect(num3 + num - 174f, num4 + num2 - 38f, 160f, 28f), "Dismiss (1 min)", stuckButtonStyle)) { GameStateWatcher.DismissMatchFoundStuckOverlay(); } } public static void OpenBugReportAdminViewer() { bugAdminOpen = true; bugAdminSelectedId = null; ApiClient.CachedBugReportDetail = null; bugAdminLoading = true; bugAdminCommentDraft = ""; bugAdminActionStatus = ""; ApiClient.FetchBugReports(MatchTracker.LocalSteamId, delegate { bugAdminLoading = false; }); } private static void DrawBugReportAdminViewer() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_0a0f: Unknown result type (might be due to invalid IL or missing references) //IL_0a34: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_0a84: Unknown result type (might be due to invalid IL or missing references) //IL_09e4: Unknown result type (might be due to invalid IL or missing references) //IL_0b01: Unknown result type (might be due to invalid IL or missing references) //IL_0b46: Unknown result type (might be due to invalid IL or missing references) //IL_0bb3: Unknown result type (might be due to invalid IL or missing references) //IL_0c4c: Unknown result type (might be due to invalid IL or missing references) //IL_0859: Unknown result type (might be due to invalid IL or missing references) //IL_089c: Unknown result type (might be due to invalid IL or missing references) //IL_0922: Unknown result type (might be due to invalid IL or missing references) //IL_0942: Unknown result type (might be due to invalid IL or missing references) //IL_1146: Unknown result type (might be due to invalid IL or missing references) //IL_114b: Unknown result type (might be due to invalid IL or missing references) //IL_1164: Unknown result type (might be due to invalid IL or missing references) //IL_1169: Unknown result type (might be due to invalid IL or missing references) //IL_116e: Unknown result type (might be due to invalid IL or missing references) //IL_118d: Unknown result type (might be due to invalid IL or missing references) //IL_11c1: Unknown result type (might be due to invalid IL or missing references) //IL_11f5: Unknown result type (might be due to invalid IL or missing references) //IL_1257: Unknown result type (might be due to invalid IL or missing references) if (!bugAdminOpen) { return; } if (!NativeUI.IsOpen) { bugAdminOpen = false; return; } Event current = Event.current; if (current != null && (int)current.type == 4 && (int)current.keyCode == 27) { bugAdminOpen = false; current.Use(); return; } if (bugAdminRowStyle == null) { bugAdminRowStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, wordWrap = false }; bugAdminDetailStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, wordWrap = true, alignment = (TextAnchor)0 }; bugAdminTabStyle = new GUIStyle(GUI.skin.button) { fontSize = 12 }; GUIStyle val = new GUIStyle(GUI.skin.button) { fontSize = 12, fontStyle = (FontStyle)1 }; val.normal.background = Texture2D.whiteTexture; val.normal.textColor = Color.black; val.hover.background = Texture2D.whiteTexture; val.hover.textColor = Color.black; bugAdminTabActiveStyle = val; } float num = Mathf.Min(Screen.width - 40, 1280); float num2 = Mathf.Min(Screen.height - 60, 760); float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.55f), 0f, 0f); GUI.DrawTexture(new Rect(num3 - 10f, num4 - 10f, num + 20f, num2 + 20f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.05f, 0.06f, 0.08f, 0.98f), 0f, 0f); GUI.Label(new Rect(num3, num4, num, 24f), "Bug Reports", bugTitleStyle ?? GUI.skin.label); if (GUI.Button(new Rect(num3 + num - 100f, num4, 100f, 26f), "Close")) { bugAdminOpen = false; return; } if (GUI.Button(new Rect(num3 + num - 210f, num4, 100f, 26f), "Refresh")) { bugAdminLoading = true; string localSteamId = MatchTracker.LocalSteamId; ApiClient.FetchBugReports(localSteamId, delegate { bugAdminLoading = false; }); if (!string.IsNullOrEmpty(bugAdminSelectedId)) { ApiClient.FetchBugReportDetail(localSteamId, bugAdminSelectedId); } } if (bugAdminLoading) { GUI.Label(new Rect(num3 + 200f, num4, 200f, 24f), "loading...", bugAdminRowStyle); } float num5 = num * 0.4f; float num6 = num4 + 36f; float num7 = num2 - 46f; GUI.DrawTexture(new Rect(num3, num6, num5 - 6f, num7), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.08f, 0.1f, 0.13f, 0.95f), 0f, 0f); float num8 = num6 + 4f; GUI.Label(new Rect(num3 + 6f, num8 + 2f, 48f, 22f), "Find:", bugAdminRowStyle); bugAdminLookup = GUI.TextField(new Rect(num3 + 56f, num8, num5 - 70f, 22f), bugAdminLookup ?? ""); List list = ApiClient.CachedBugReports ?? new List(); List list2 = list; string text = (bugAdminLookup ?? "").Trim(); if (!string.IsNullOrEmpty(text)) { list2 = new List(); int result; bool flag = int.TryParse(text, out result); string value = text.ToLowerInvariant(); foreach (ApiClient.BugReportSummary item in list) { if (flag && item.bug_number == result) { list2.Add(item); } else if ((item.description ?? "").ToLowerInvariant().Contains(value)) { list2.Add(item); } else if ((item.display_name ?? "").ToLowerInvariant().Contains(value)) { list2.Add(item); } else if ((item.steam_id ?? "").Contains(text)) { list2.Add(item); } } } float num9 = num8 + 28f; float num10 = num7 - 28f - 4f; float num11 = num5 - 18f; float num12 = num11 - 16f; float num13 = Mathf.Max(num10 - 8f, (float)list2.Count * 88f + 8f); bugAdminListScroll = GUI.BeginScrollView(new Rect(num3 + 4f, num9, num11, num10), bugAdminListScroll, new Rect(0f, 0f, num12, num13)); Rect val2 = default(Rect); for (int num14 = 0; num14 < list2.Count; num14++) { ApiClient.BugReportSummary bugReportSummary = list2[num14]; ((Rect)(ref val2))..ctor(2f, (float)num14 * 88f + 2f, num12 - 6f, 84f); Color val3 = ((bugReportSummary.id == bugAdminSelectedId) ? new Color(0.2f, 0.3f, 0.45f, 0.95f) : new Color(0.13f, 0.15f, 0.19f, 0.95f)); GUI.DrawTexture(val2, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val3, 0f, 0f); string text2 = ((bugReportSummary.severity == "crash") ? "#FF5555" : ((bugReportSummary.severity == "high") ? "#FF9966" : ((bugReportSummary.severity == "medium") ? "#FFCC66" : "#88AABB"))); string text3 = ((bugReportSummary.status == "resolved") ? "#88FF88" : ((bugReportSummary.status == "wontfix") ? "#888888" : ((bugReportSummary.status == "dupe") ? "#888888" : ((bugReportSummary.status == "triaged") ? "#FFCC66" : "#FF6688")))); string text4 = ((bugReportSummary.bug_number > 0) ? $"#{bugReportSummary.bug_number} " : ""); string text5 = text4 + "[" + (bugReportSummary.severity ?? "?").ToUpper() + "/" + (bugReportSummary.category ?? "?").ToUpper() + "] " + (bugReportSummary.status ?? "?").ToUpper() + ""; string text6 = (bugReportSummary.display_name ?? bugReportSummary.steam_id ?? "?") + " (" + (bugReportSummary.mod_version ?? "?") + ")"; string text7 = ShortDate(bugReportSummary.created_at); string text8 = (bugReportSummary.description ?? "").Replace("\n", " "); if (text8.Length > 70) { text8 = text8.Substring(0, 70) + "..."; } GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 6f, ((Rect)(ref val2)).width - 16f, 20f), text5, bugAdminRowStyle); GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 6f + 20f, ((Rect)(ref val2)).width - 16f, 20f), "" + text6 + " " + text7 + "" + (bugReportSummary.has_log ? " [log]" : ""), bugAdminRowStyle); GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 6f + 40f, ((Rect)(ref val2)).width - 16f, 20f), "" + text8 + "", bugAdminRowStyle); if (GUI.Button(val2, GUIContent.none, GUIStyle.none)) { bugAdminSelectedId = bugReportSummary.id; ApiClient.CachedBugReportDetail = null; bugAdminCommentDraft = ""; bugAdminActionStatus = ""; ApiClient.FetchBugReportDetail(MatchTracker.LocalSteamId, bugReportSummary.id); } } if (list2.Count == 0) { string text9 = (string.IsNullOrEmpty(text) ? "(no reports yet)" : ("(no reports match '" + text + "')")); GUI.Label(new Rect(8f, 8f, num5 - 40f, 30f), text9, bugAdminRowStyle); } GUI.EndScrollView(); float num15 = num3 + num5; float num16 = num - num5; GUI.DrawTexture(new Rect(num15, num6, num16, num7), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.05f, 0.07f, 0.1f, 0.95f), 0f, 0f); ApiClient.BugReportDetail d = ApiClient.CachedBugReportDetail; if (d == null || string.IsNullOrEmpty(bugAdminSelectedId)) { GUI.Label(new Rect(num15 + 12f, num6 + 12f, num16 - 24f, 30f), "Click a report on the left to view full detail + log.", bugAdminRowStyle); return; } int num17 = Array.IndexOf(BUG_STATUSES, (d.status ?? "open").ToLower()); if (num17 < 0) { num17 = 0; } if (bugAdminStatusIdx < 0 || bugAdminStatusIdx >= BUG_STATUSES.Length) { bugAdminStatusIdx = num17; } float num18 = num6 + 8f; GUI.Label(new Rect(num15 + 8f, num18, 80f, 22f), "Status:", bugAdminRowStyle); for (int num19 = 0; num19 < BUG_STATUSES.Length; num19++) { bool flag2 = num19 == bugAdminStatusIdx; if (GUI.Button(new Rect(num15 + 80f + (float)(num19 * 76), num18 - 2f, 72f, 24f), BUG_STATUSES[num19].ToUpper(), flag2 ? bugAdminTabActiveStyle : bugAdminTabStyle)) { bugAdminStatusIdx = num19; } } if (GUI.Button(new Rect(num15 + 80f + (float)(BUG_STATUSES.Length * 76) + 8f, num18 - 2f, 96f, 24f), "Apply Status")) { string sid = MatchTracker.LocalSteamId; string newStatus = BUG_STATUSES[bugAdminStatusIdx]; bugAdminActionStatus = "updating..."; ApiClient.AdminBugReportStatus(sid, d.id, newStatus, null, delegate(bool ok, string resp) { bugAdminActionStatus = (ok ? "status updated" : ("fail: " + (resp ?? "").Replace("\n", " ") + "")); if (ok) { ApiClient.FetchBugReportDetail(sid, d.id); ApiClient.FetchBugReports(sid); } }); } if (!string.IsNullOrEmpty(bugAdminActionStatus)) { GUI.Label(new Rect(num15 + 8f, num18 + 24f, num16 - 16f, 18f), bugAdminActionStatus, bugAdminRowStyle); } StringBuilder stringBuilder = new StringBuilder(); string text10 = ((d.bug_number > 0) ? $"#{d.bug_number} " : ""); stringBuilder.AppendLine(text10 + "" + (d.display_name ?? d.steam_id) + " " + d.steam_id + ""); stringBuilder.AppendLine("" + ShortDate(d.created_at) + " | mod=" + d.mod_version + " | game=" + d.game_version + ""); stringBuilder.AppendLine("severity: " + d.severity + " category: " + d.category + " status: " + d.status); stringBuilder.AppendLine(); stringBuilder.AppendLine("Description:"); stringBuilder.AppendLine(d.description ?? "(empty)"); if (!string.IsNullOrEmpty(d.repro_steps)) { stringBuilder.AppendLine(); stringBuilder.AppendLine("Repro:"); stringBuilder.AppendLine(d.repro_steps); } if (d.events != null && d.events.Count > 0) { stringBuilder.AppendLine(); stringBuilder.AppendLine($"Activity ({d.events.Count}):"); foreach (ApiClient.BugReportEventEntry @event in d.events) { string text11 = ShortDate(@event.created_at); string text12 = @event.actor_name ?? "?"; if (@event.event_type == "status_change") { stringBuilder.AppendLine(" " + text11 + " " + text12 + " " + (@event.old_status ?? "?") + " -> " + (@event.new_status ?? "?") + "" + (string.IsNullOrEmpty(@event.comment) ? "" : (" -- " + @event.comment))); } else if (@event.event_type == "created") { stringBuilder.AppendLine(" " + text11 + " " + text12 + " filed report"); } else { stringBuilder.AppendLine(" " + text11 + " " + text12 + ": " + @event.comment); } } } if (!string.IsNullOrEmpty(d.log_text)) { stringBuilder.AppendLine(); int length = d.log_text.Length; string text13 = d.log_text; string arg = ""; if (text13.Length > 400000) { text13 = "[... earlier content trimmed for display - see ssh bug-log:" + d.bug_number + " for full ...]\n" + text13.Substring(text13.Length - 400000); arg = $" — showing last {400000:N0} of {length:N0} chars"; } stringBuilder.AppendLine($"Attached log ({d.log_bytes:N0} bytes gzipped on disk, {length:N0} chars decoded){arg}:"); stringBuilder.AppendLine(text13); } string text14 = stringBuilder.ToString(); float num20 = num18 + 48f; float num21 = 96f; float num22 = num7 - (num20 - num6) - num21 - 8f; float num23 = num16 - 24f; float num24 = Mathf.Max(num22, (float)text14.Length / 90f * 14f + 80f); bugAdminDetailScroll = GUI.BeginScrollView(new Rect(num15 + 8f, num20, num16 - 12f, num22), bugAdminDetailScroll, new Rect(0f, 0f, num23 - 12f, num24)); GUI.Label(new Rect(4f, 4f, num23 - 12f, num24 - 8f), text14, bugAdminDetailStyle); GUI.EndScrollView(); float num25 = num6 + num7 - num21; GUI.Label(new Rect(num15 + 8f, num25, 200f, 18f), "Add comment:", bugAdminRowStyle); bugAdminCommentDraft = GUI.TextArea(new Rect(num15 + 8f, num25 + 20f, num16 - 130f, num21 - 26f), bugAdminCommentDraft ?? "", 2000); GUI.enabled = !string.IsNullOrEmpty((bugAdminCommentDraft ?? "").Trim()); if (GUI.Button(new Rect(num15 + num16 - 116f, num25 + 20f, 108f, num21 - 26f), "Post Comment")) { string sid2 = MatchTracker.LocalSteamId; string comment = (bugAdminCommentDraft ?? "").Trim(); bugAdminActionStatus = "posting..."; ApiClient.AdminBugReportComment(sid2, d.id, comment, delegate(bool ok, string resp) { bugAdminActionStatus = (ok ? "comment posted" : ("fail: " + (resp ?? "").Replace("\n", " ") + "")); if (ok) { bugAdminCommentDraft = ""; ApiClient.FetchBugReportDetail(sid2, d.id); } }); } GUI.enabled = true; } private static string ShortDate(string isoStr) { if (string.IsNullOrEmpty(isoStr)) { return "?"; } try { return DateTime.Parse(isoStr, null, DateTimeStyles.RoundtripKind).ToLocalTime().ToString("M/d HH:mm", CultureInfo.InvariantCulture); } catch { return isoStr; } } private static void DrawInputOverlay() { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01df: 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_0032: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown if (Plugin.ShowInputOverlay != null && Plugin.ShowInputOverlay.Value && GameStateWatcher.IsInMatch) { if (inputKeyStyle == null) { inputKeyStyle = new GUIStyle(GUI.skin.label) { fontSize = 18, richText = true, alignment = (TextAnchor)4, fontStyle = (FontStyle)1 }; inputKeySmallStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, alignment = (TextAnchor)4, fontStyle = (FontStyle)1 }; } bool key = Input.GetKey((KeyCode)119); bool key2 = Input.GetKey((KeyCode)97); bool key3 = Input.GetKey((KeyCode)115); bool key4 = Input.GetKey((KeyCode)100); bool key5 = Input.GetKey((KeyCode)32); bool mouseButton = Input.GetMouseButton(0); bool mouseButton2 = Input.GetMouseButton(1); float num = 38f; float num2 = 38f; float num3 = 4f; float num4 = (float)(Screen.height - 14) - num2; float num5 = num * 1.6f; DrawKeyBox(new Rect(14f, num4, num5, num2), "LMB", mouseButton, small: true); DrawKeyBox(new Rect(14f + num5 + num3, num4, num5, num2), "RMB", mouseButton2, small: true); float num6 = num4 - 10f - num2; DrawKeyBox(new Rect(14f, num6, num, num2), "A", key2, small: false); DrawKeyBox(new Rect(14f + num + num3, num6, num, num2), "S", key3, small: false); DrawKeyBox(new Rect(14f + (num + num3) * 2f, num6, num, num2), "D", key4, small: false); float num7 = num6 - num2 - num3; DrawKeyBox(new Rect(14f + num + num3, num7, num, num2), "W", key, small: false); float num8 = (num + num3) * 3f - num3; DrawKeyBox(new Rect(14f + (num + num3) * 3f + 8f, num6, num8, num2), "SPACE", key5, small: true); } } private static void DrawKeyBox(Rect r, string label, bool pressed, bool small) { //IL_0032: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) Color val = (pressed ? new Color(0.85f, 0.18f, 0.18f, 0.92f) : new Color(0.1f, 0.1f, 0.13f, 0.78f)); Color val2 = (pressed ? new Color(1f, 0.5f, 0.5f, 0.9f) : new Color(1f, 1f, 1f, 0.35f)); GUI.DrawTexture(r, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + ((Rect)(ref r)).height - 1f, ((Rect)(ref r)).width, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width - 1f, ((Rect)(ref r)).y, 1f, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); Color contentColor = GUI.contentColor; GUI.contentColor = Color.white; GUI.Label(r, label, small ? inputKeySmallStyle : inputKeyStyle); GUI.contentColor = contentColor; } private static void DrawBlockDebug() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_007e: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0363: 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_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) if (Plugin.ShowBlockDebug == null || !Plugin.ShowBlockDebug.Value || !GameStateWatcher.IsInMatch) { return; } if (blockDbgStyle == null) { blockDbgStyle = new GUIStyle(GUI.skin.label) { fontSize = 15, richText = true, alignment = (TextAnchor)0, fontStyle = (FontStyle)1 }; blockDbgSmallStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = true, alignment = (TextAnchor)0 }; } int localBlocksActivatedThisMatch = GameStateWatcher.LocalBlocksActivatedThisMatch; int localBlocksSuccessfulThisMatch = GameStateWatcher.LocalBlocksSuccessfulThisMatch; int localBlockRawAbsorbs = GameStateWatcher.LocalBlockRawAbsorbs; int localBlockDedupeDrops = GameStateWatcher.LocalBlockDedupeDrops; float time = Time.time; float num = time - GameStateWatcher.LastBlockActivatedTime; float num2 = time - GameStateWatcher.LastBlockSuccessfulTime; float num3 = time - GameStateWatcher.LastBlockAbsorbTime; float num4 = time - GameStateWatcher.LastBlockMissTime; string text = GameStateWatcher.LastBlockEventLabel ?? ""; float num5 = 270f; float num6 = 110f; float num7 = 6f; float num8 = (float)Screen.width - num5 - 12f; float num9 = 12f; Color val = default(Color); ((Color)(ref val))..ctor(0f, 0f, 0f, 0.72f); float num10 = Mathf.Min(num, Mathf.Min(num2, Mathf.Min(num3, num4))); if (num10 >= 0f && num10 < 0.35f) { float num11 = 1f - num10 / 0.35f; Color val2 = default(Color); if (num4 <= num10 + 0.001f) { ((Color)(ref val2))..ctor(0.95f, 0.25f, 0.25f, 0.9f); } else if (num2 <= num10 + 0.001f) { ((Color)(ref val2))..ctor(0.2f, 0.9f, 0.2f, 0.85f); } else if (num <= num10 + 0.001f) { ((Color)(ref val2))..ctor(0.3f, 0.55f, 1f, 0.85f); } else { ((Color)(ref val2))..ctor(0.95f, 0.7f, 0.1f, 0.85f); } val = Color.Lerp(val, val2, num11); } GUI.DrawTexture(new Rect(num8, num9, num5, num6), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val, 0f, 0f); GUI.DrawTexture(new Rect(num8, num9, num5, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(1f, 1f, 1f, 0.5f), 0f, 0f); Color contentColor = GUI.contentColor; GUI.contentColor = Color.white; GUI.Label(new Rect(num8 + num7, num9 + num7, num5 - num7 * 2f, 20f), "BLOCK DEBUG", blockDbgStyle); string text2 = $"Act: {localBlocksActivatedThisMatch} " + $"Succ: {localBlocksSuccessfulThisMatch} " + $"Raw: {localBlockRawAbsorbs}"; GUI.Label(new Rect(num8 + num7, num9 + num7 + 22f, num5 - num7 * 2f, 20f), text2, blockDbgStyle); string text3 = string.Format(arg1: (localBlocksActivatedThisMatch > 0) ? $"{(float)localBlocksSuccessfulThisMatch * 100f / (float)localBlocksActivatedThisMatch:F0}%" : "-", format: "Drops: {0} Rate: {1}", arg0: localBlockDedupeDrops); GUI.Label(new Rect(num8 + num7, num9 + num7 + 44f, num5 - num7 * 2f, 18f), text3, blockDbgSmallStyle); string text4 = ""; if (!string.IsNullOrEmpty(text) && num10 < 5f && num10 >= 0f) { text4 = $"{text} (+{num10:F1}s)"; } GUI.Label(new Rect(num8 + num7, num9 + num7 + 64f, num5 - num7 * 2f, 18f), text4, blockDbgSmallStyle); GUI.Label(new Rect(num8 + num7, num9 + num7 + 82f, num5 - num7 * 2f, 14f), "debug overlay — CompetitiveUI.BlockDebugEnabled", blockDbgSmallStyle); GUI.contentColor = contentColor; } private static void DrawInGameChat() { //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_0051: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0175: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) if ((Plugin.ShowIngameChat != null && !Plugin.ShowIngameChat.Value) || !Plugin.DataConsentGranted || NativeUI.IsOpen) { return; } NativeUI.ChatEntry[] array = NativeUI.SnapshotChat(8); if (array == null || array.Length == 0) { return; } if (ingameChatStyle == null) { ingameChatStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, wordWrap = true, richText = true, alignment = (TextAnchor)0 }; } DateTime utcNow = DateTime.UtcNow; float[] array2 = new float[array.Length]; float num = 0f; int num2 = 0; for (int i = 0; i < array.Length; i++) { double totalSeconds = (utcNow - array[i].AddedUtc).TotalSeconds; float num3 = (array2[i] = ((totalSeconds < 25.0) ? 1f : ((totalSeconds < 35.0) ? (1f - (float)((totalSeconds - 25.0) / 10.0)) : 0f))); if (num3 > 0.02f) { num2++; if (num3 > num) { num = num3; } } } if (num2 == 0) { return; } float num4 = 440f; float num5 = 20f; float num6 = 6f; float num7 = 12f; float num8 = (float)num2 * num5 + num6 * 2f; float num9 = Screen.height - 90; float num10 = num9 - num8; GUI.DrawTexture(new Rect(num7 - 4f, num10, num4 + 8f, num8), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.55f * num), 0f, 0f); int num11 = 0; for (int num12 = array.Length - 1; num12 >= 0; num12--) { float num13 = array2[num12]; if (!(num13 <= 0.02f)) { Color contentColor = GUI.contentColor; GUI.contentColor = new Color(1f, 1f, 1f, num13); float num14 = num9 - num6 - (float)(num11 + 1) * num5; GUI.Label(new Rect(num7, num14, num4, num5), array[num12].Line, ingameChatStyle); GUI.contentColor = contentColor; num11++; } } } public static void OpenAdminPrompt(string mode) { adminPromptMode = mode ?? ""; adminInputA = ""; adminInputB = ((mode == "grant") ? ADMIN_ACHIEVEMENT_KEYS[0] : ""); adminPromptOpen = true; } private static void DrawAdminPrompt() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_00d1: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_017f: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) if (!adminPromptOpen) { return; } if (!NativeUI.IsOpen) { adminPromptOpen = false; return; } Event current = Event.current; bool flag = false; bool flag2 = false; if (current != null && (int)current.type == 4 && (int)current.keyCode == 27) { flag2 = true; current.Use(); } if (adminFieldStyle == null) { adminFieldStyle = new GUIStyle(GUI.skin.textField) { fontSize = 15 }; } if (adminLabelStyle == null) { adminLabelStyle = new GUIStyle(GUI.skin.label) { fontSize = 14 }; } float num = 560f; float num2 = 220f; float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; GUI.DrawTexture(new Rect(num3 - 8f, num4 - 8f, num + 16f, num2 + 16f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.92f), 0f, 0f); string text = adminPromptMode switch { "ban" => "Ban a player", "grant" => "Grant an achievement", "reverse" => "Reverse a ranked series", _ => "Admin action", }; GUI.Label(new Rect(num3 + 10f, num4 + 8f, num - 20f, 24f), text, new GUIStyle(adminLabelStyle) { fontSize = 17, fontStyle = (FontStyle)1 }); string text2; string text3; switch (adminPromptMode) { case "ban": text2 = "Target Steam ID"; text3 = "Reason"; break; case "grant": text2 = "Target Steam ID"; text3 = "Achievement key"; break; case "reverse": text2 = "Series ID (UUID)"; text3 = "Reason"; break; default: text2 = "ID"; text3 = "Detail"; break; } GUI.Label(new Rect(num3 + 10f, num4 + 38f, 200f, 20f), text2, adminLabelStyle); adminInputA = GUI.TextField(new Rect(num3 + 10f, num4 + 60f, num - 20f, 26f), adminInputA ?? "", adminFieldStyle); GUI.Label(new Rect(num3 + 10f, num4 + 96f, 200f, 20f), text3, adminLabelStyle); if (adminPromptMode == "grant") { if (GUI.Button(new Rect(num3 + 10f, num4 + 118f, 30f, 26f), "<")) { int num5 = Math.Max(0, Array.IndexOf(ADMIN_ACHIEVEMENT_KEYS, adminInputB)); num5 = (num5 - 1 + ADMIN_ACHIEVEMENT_KEYS.Length) % ADMIN_ACHIEVEMENT_KEYS.Length; adminInputB = ADMIN_ACHIEVEMENT_KEYS[num5]; } GUI.Label(new Rect(num3 + 50f, num4 + 122f, num - 100f, 22f), adminInputB, adminLabelStyle); if (GUI.Button(new Rect(num3 + num - 40f, num4 + 118f, 30f, 26f), ">")) { int num6 = Math.Max(0, Array.IndexOf(ADMIN_ACHIEVEMENT_KEYS, adminInputB)); num6 = (num6 + 1) % ADMIN_ACHIEVEMENT_KEYS.Length; adminInputB = ADMIN_ACHIEVEMENT_KEYS[num6]; } } else { adminInputB = GUI.TextField(new Rect(num3 + 10f, num4 + 118f, num - 20f, 26f), adminInputB ?? "", adminFieldStyle); } if (GUI.Button(new Rect(num3 + 10f, num4 + num2 - 36f, 100f, 28f), "Cancel")) { flag2 = true; } if (GUI.Button(new Rect(num3 + num - 110f, num4 + num2 - 36f, 100f, 28f), "Submit")) { flag = true; } if (flag2) { adminPromptOpen = false; } else { if (!flag) { return; } string sid = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(sid)) { Plugin.Log.LogWarning((object)"[ADMIN] No local Steam ID"); adminPromptOpen = false; return; } string text4 = (adminInputA ?? "").Trim(); string text5 = (adminInputB ?? "").Trim(); if (string.IsNullOrEmpty(text4)) { return; } Action callback = delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)("[ADMIN] " + adminPromptMode + " -> " + (ok ? "OK" : "FAIL") + " " + resp)); if (ok) { ApiClient.FetchFlaggedMatches(sid); ApiClient.FetchBannedUsers(sid); } }; switch (adminPromptMode) { case "ban": ApiClient.AdminBan(sid, text4, string.IsNullOrEmpty(text5) ? "violation" : text5, callback); break; case "grant": ApiClient.AdminGrantAchievement(sid, text4, text5, callback); break; case "reverse": ApiClient.AdminReverseSeries(sid, text4, string.IsNullOrEmpty(text5) ? "admin_reverse" : text5, callback); break; } adminPromptOpen = false; } } public static void OpenBugReportModal() { bugModalOpen = true; bugSubmitStatus = ""; bugSubmitting = false; } private static void EnsureBugStyles() { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown if (bugTitleStyle == null) { bugTitleStyle = new GUIStyle(GUI.skin.label) { fontSize = 19, fontStyle = (FontStyle)1, richText = true, alignment = (TextAnchor)3 }; bugLabelStyle = new GUIStyle(GUI.skin.label) { fontSize = 13, richText = true }; bugFieldStyle = new GUIStyle(GUI.skin.textField) { fontSize = 14 }; bugAreaStyle = new GUIStyle(GUI.skin.textArea) { fontSize = 13, wordWrap = true }; bugButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 13 }; GUIStyle val = new GUIStyle(GUI.skin.button) { fontSize = 13, fontStyle = (FontStyle)1 }; val.normal.background = Texture2D.whiteTexture; val.normal.textColor = Color.black; val.hover.background = Texture2D.whiteTexture; val.hover.textColor = Color.black; val.active.background = Texture2D.whiteTexture; val.active.textColor = Color.black; bugBtnPickedStyle = val; } } private static void DrawBugReportModal() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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) //IL_002b: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0253: 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_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: 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_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_041f: 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_0497: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_06a3: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Expected O, but got Unknown //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_076a: Unknown result type (might be due to invalid IL or missing references) //IL_07b4: Unknown result type (might be due to invalid IL or missing references) if (!bugModalOpen) { return; } if (!NativeUI.IsOpen) { bugModalOpen = false; return; } EnsureBugStyles(); Event current = Event.current; if (current != null && (int)current.type == 4 && (int)current.keyCode == 27) { bugModalOpen = false; current.Use(); return; } float num = 680f; float num2 = 580f; float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.45f), 0f, 0f); GUI.DrawTexture(new Rect(num3 - 10f, num4 - 10f, num + 20f, num2 + 20f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.07f, 0.08f, 0.11f, 0.97f), 0f, 0f); GUI.DrawTexture(new Rect(num3 - 10f, num4 - 10f, num + 20f, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(1f, 1f, 1f, 0.4f), 0f, 0f); GUI.Label(new Rect(num3, num4, num, 28f), "Report a Bug", bugTitleStyle); GUI.Label(new Rect(num3, num4 + 30f, num, 18f), "Reports go to the mod team. Be specific — what happened, when, what you were doing.", bugLabelStyle); GUI.Label(new Rect(num3, num4 + 56f, 120f, 22f), "Severity:", bugLabelStyle); for (int i = 0; i < BUG_SEVERITIES.Length; i++) { bool flag = i == bugSeverityIdx; if (GUI.Button(new Rect(num3 + 100f + (float)(i * 88), num4 + 54f, 84f, 26f), BUG_SEVERITIES[i].ToUpper(), flag ? bugBtnPickedStyle : bugButtonStyle)) { bugSeverityIdx = i; } } GUI.Label(new Rect(num3, num4 + 92f, 120f, 22f), "Category:", bugLabelStyle); for (int j = 0; j < BUG_CATEGORIES.Length; j++) { bool flag2 = j == bugCategoryIdx; if (GUI.Button(new Rect(num3 + 100f + (float)(j * 88), num4 + 90f, 84f, 26f), BUG_CATEGORIES[j].ToUpper(), flag2 ? bugBtnPickedStyle : bugButtonStyle)) { bugCategoryIdx = j; } } GUI.Label(new Rect(num3, num4 + 126f, num, 18f), "What happened? (required)", bugLabelStyle); bugDescScroll = GUI.BeginScrollView(new Rect(num3, num4 + 146f, num, 140f), bugDescScroll, new Rect(0f, 0f, num - 20f, (float)Mathf.Max(140, (bugDescription?.Length ?? 0) / 4))); bugDescription = GUI.TextArea(new Rect(0f, 0f, num - 20f, (float)Mathf.Max(140, (bugDescription?.Length ?? 0) / 4)), bugDescription ?? "", 4000, bugAreaStyle); GUI.EndScrollView(); GUI.Label(new Rect(num3, num4 + 296f, num, 18f), "How to reproduce? (optional)", bugLabelStyle); bugReproScroll = GUI.BeginScrollView(new Rect(num3, num4 + 316f, num, 100f), bugReproScroll, new Rect(0f, 0f, num - 20f, (float)Mathf.Max(100, (bugRepro?.Length ?? 0) / 4))); bugRepro = GUI.TextArea(new Rect(0f, 0f, num - 20f, (float)Mathf.Max(100, (bugRepro?.Length ?? 0) / 4)), bugRepro ?? "", 4000, bugAreaStyle); GUI.EndScrollView(); float num5 = num3; float num6 = 280f; if (GUI.Button(new Rect(num5, num4 + 428f, num6, 26f), GUIContent.none, GUIStyle.none)) { bugSendLogs = !bugSendLogs; } Rect val = default(Rect); ((Rect)(ref val))..ctor(num5 + 2f, num4 + 430f, 20f, 20f); Color val2 = (bugSendLogs ? new Color(0.25f, 0.7f, 0.3f, 0.95f) : new Color(0.18f, 0.18f, 0.22f, 0.95f)); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, val2, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, Color.white, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + ((Rect)(ref val)).height - 1f, ((Rect)(ref val)).width, 1f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, Color.white, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, 1f, ((Rect)(ref val)).height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, Color.white, 0f, 0f); GUI.DrawTexture(new Rect(((Rect)(ref val)).x + ((Rect)(ref val)).width - 1f, ((Rect)(ref val)).y, 1f, ((Rect)(ref val)).height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, Color.white, 0f, 0f); if (bugSendLogs) { GUIStyle val3 = new GUIStyle(bugLabelStyle) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; GUI.Label(val, "X", val3); } GUI.Label(new Rect(num5 + 28f, num4 + 428f, num6 - 32f, 26f), "Attach game logs (recommended)", bugLabelStyle); if (GUI.Button(new Rect(num5 + num6 + 16f, num4 + 428f, 140f, 24f), "Preview logs", bugButtonStyle)) { OpenLogViewer(); } if (!string.IsNullOrEmpty(bugSubmitStatus)) { GUI.Label(new Rect(num3, num4 + 460f, num, 20f), bugSubmitStatus, bugLabelStyle); } bool flag3 = bugSubmitting || string.IsNullOrEmpty(bugDescription) || bugDescription.Trim().Length < 4; GUI.enabled = !bugSubmitting; if (GUI.Button(new Rect(num3, num4 + num2 - 44f, 120f, 30f), "Cancel", bugButtonStyle)) { bugModalOpen = false; GUI.enabled = true; return; } GUI.enabled = !flag3; if (GUI.Button(new Rect(num3 + num - 160f, num4 + num2 - 44f, 160f, 30f), bugSubmitting ? "Submitting..." : "Submit Report", bugButtonStyle)) { SubmitBugReportNow(); } GUI.enabled = true; } private static void SubmitBugReportNow() { bugSubmitting = true; bugSubmitStatus = "Submitting..."; string localSteamId = MatchTracker.LocalSteamId; string displayName = MatchTracker.LocalDisplayName ?? ""; string description = (bugDescription ?? "").Trim(); string reproSteps = (bugRepro ?? "").Trim(); string severity = BUG_SEVERITIES[Mathf.Clamp(bugSeverityIdx, 0, BUG_SEVERITIES.Length - 1)]; string category = BUG_CATEGORIES[Mathf.Clamp(bugCategoryIdx, 0, BUG_CATEGORIES.Length - 1)]; string logText = (bugSendLogs ? BuildLogBundle() : null); ApiClient.SubmitBugReport(localSteamId, displayName, description, reproSteps, severity, category, logText, delegate(bool ok, string resp) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) bugSubmitting = false; if (ok) { int num = ApiClient.ExtractJsonIntPublic(resp ?? "", "bug_number"); string text = ((num > 0) ? $" Filed as #{num}." : ""); bugSubmitStatus = "Sent! Thank you." + text + ""; bugDescription = ""; bugRepro = ""; ShowNotification((num > 0) ? $"Bug report sent. Thanks! (#{num})" : "Bug report sent. Thanks!", new Color(0.5f, 1f, 0.5f), 5f); bugModalOpen = false; } else { bugSubmitStatus = "Failed: " + (resp ?? "").Replace("\n", " ") + ""; } }); } private static string BuildLogBundle() { string text = ApiClient.ReadLogTail(BepInExLogPath(), 1500000); string text2 = ApiClient.ReadLogTail(BepInExLogPreviousPath(), 1000000); string text3 = ApiClient.ReadLogTail(UnityLogPath(), 1000000); StringBuilder stringBuilder = new StringBuilder(); if (!string.IsNullOrEmpty(text2)) { stringBuilder.AppendLine($"===== BepInEx LogOutput-prev.log [{BepInExLogPreviousPath()}] ({text2.Length:N0} chars, cap {1000000:N0}) ====="); stringBuilder.AppendLine(text2); stringBuilder.AppendLine(); } stringBuilder.AppendLine(string.Format("===== BepInEx LogOutput.log [{0}] ({1:N0} chars, cap {2:N0}) =====", BepInExLogPath() ?? "(path unknown)", text?.Length ?? 0, 1500000)); stringBuilder.AppendLine(string.IsNullOrEmpty(text) ? "(not found)" : text); stringBuilder.AppendLine(); stringBuilder.AppendLine(string.Format("===== Unity Player.log [{0}] ({1:N0} chars, cap {2:N0}) =====", UnityLogPath() ?? "(path unknown)", text3?.Length ?? 0, 1000000)); stringBuilder.AppendLine(string.IsNullOrEmpty(text3) ? "(not found)" : text3); return stringBuilder.ToString(); } private static string BepInExDir() { try { string location = typeof(Plugin).Assembly.Location; if (string.IsNullOrEmpty(location)) { return null; } string directoryName = Path.GetDirectoryName(Path.GetDirectoryName(location)); if (string.IsNullOrEmpty(directoryName)) { return null; } return Path.GetDirectoryName(directoryName); } catch { return null; } } private static string GameRoot() { try { string text = BepInExDir(); return string.IsNullOrEmpty(text) ? null : Path.GetDirectoryName(text); } catch { return null; } } private static string BepInExLogPath() { string text = BepInExDir(); if (string.IsNullOrEmpty(text)) { return null; } return Path.Combine(text, "LogOutput.log"); } public static string BepInExLogPathPublic() { return BepInExLogPath(); } public static string BepInExLogPreviousPath() { string text = BepInExDir(); if (!string.IsNullOrEmpty(text)) { return Path.Combine(text, "LogOutput-prev.log"); } return null; } private static string UnityLogPath() { try { string text = GameRoot(); if (!string.IsNullOrEmpty(text)) { string text2 = Path.Combine(text, "output_log.txt"); if (File.Exists(text2)) { return text2; } } string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); if (!string.IsNullOrEmpty(folderPath)) { string[] array = new string[2] { "Landfall Games", "Landfall" }; foreach (string text3 in array) { string fullPath = Path.GetFullPath(Path.Combine(folderPath, "..", "LocalLow", text3, "ROUNDS", "Player.log")); if (File.Exists(fullPath)) { return fullPath; } } } } catch { } return null; } private static void OpenLogViewer() { logViewerOpen = true; logViewerBepCache = ApiClient.ReadLogTail(BepInExLogPath(), 400000); logViewerBepPrevCache = ApiClient.ReadLogTail(BepInExLogPreviousPath(), 400000); logViewerUniCache = ApiClient.ReadLogTail(UnityLogPath(), 400000); Plugin.Log.LogInfo((object)($"[BUG-REPORT-VIEWER] bep_path={BepInExLogPath()} bep_chars={logViewerBepCache?.Length ?? 0}; " + $"prev_path={BepInExLogPreviousPath()} prev_chars={logViewerBepPrevCache?.Length ?? 0}; " + $"uni_path={UnityLogPath()} uni_chars={logViewerUniCache?.Length ?? 0}")); } private static void DrawLogViewerModal() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005b: 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) //IL_006d: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Invalid comparison between Unknown and I4 //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Invalid comparison between Unknown and I4 //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) if (!logViewerOpen) { return; } if (!NativeUI.IsOpen) { logViewerOpen = false; return; } if (logViewerStyle == null) { logViewerStyle = new GUIStyle(GUI.skin.label) { fontSize = 12, richText = false, alignment = (TextAnchor)0, wordWrap = false }; logViewerTabStyle = new GUIStyle(GUI.skin.button) { fontSize = 13 }; GUIStyle val = new GUIStyle(GUI.skin.button) { fontSize = 13, fontStyle = (FontStyle)1 }; val.normal.background = Texture2D.whiteTexture; val.normal.textColor = Color.black; val.hover.background = Texture2D.whiteTexture; val.hover.textColor = Color.black; logViewerTabActiveStyle = val; } Event current = Event.current; if (current != null && (int)current.type == 4 && (int)current.keyCode == 27) { logViewerOpen = false; current.Use(); return; } float num = Mathf.Min(Screen.width - 60, 1100); float num2 = Mathf.Min(Screen.height - 80, 720); float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.55f), 0f, 0f); GUI.DrawTexture(new Rect(num3 - 10f, num4 - 10f, num + 20f, num2 + 20f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0.05f, 0.06f, 0.08f, 0.98f), 0f, 0f); GUI.Label(new Rect(num3, num4, num, 24f), "Game logs (tail) — included with your report when the box is checked.", bugLabelStyle ?? GUI.skin.label); if (GUI.Button(new Rect(num3, num4 + 28f, 160f, 26f), "BepInEx (current)", (logViewerTab == 0) ? logViewerTabActiveStyle : logViewerTabStyle)) { logViewerTab = 0; } if (GUI.Button(new Rect(num3 + 168f, num4 + 28f, 180f, 26f), "BepInEx (prev session)", (logViewerTab == 1) ? logViewerTabActiveStyle : logViewerTabStyle)) { logViewerTab = 1; } if (GUI.Button(new Rect(num3 + 356f, num4 + 28f, 140f, 26f), "Unity / Game", (logViewerTab == 2) ? logViewerTabActiveStyle : logViewerTabStyle)) { logViewerTab = 2; } if (GUI.Button(new Rect(num3 + num - 200f, num4 + 28f, 90f, 26f), "Refresh", logViewerTabStyle)) { logViewerBepCache = ApiClient.ReadLogTail(BepInExLogPath(), 400000); logViewerBepPrevCache = ApiClient.ReadLogTail(BepInExLogPreviousPath(), 400000); logViewerUniCache = ApiClient.ReadLogTail(UnityLogPath(), 400000); } if (GUI.Button(new Rect(num3 + num - 100f, num4 + 28f, 100f, 26f), "Close", logViewerTabStyle)) { logViewerOpen = false; return; } string text; string text2; switch (logViewerTab) { case 0: text = logViewerBepCache; text2 = BepInExLogPath(); break; case 1: text = logViewerBepPrevCache; text2 = BepInExLogPreviousPath(); break; default: text = logViewerUniCache; text2 = UnityLogPath(); break; } if (string.IsNullOrEmpty(text)) { text = ((logViewerTab != 1) ? ("(no log content read from: " + (text2 ?? "unknown path") + ")") : ("(no previous-session log yet — gets written by the mod when ROUNDS is closed cleanly, so on first ever launch this is empty)\n\nExpected path: " + (text2 ?? "unknown"))); } float num5 = num4 + 64f; float num6 = num2 - 70f; float num7 = num - 30f; float num8 = (float)text.Length / 110f + 4f; float num9 = Mathf.Max(num6 - 12f, num8 * 14f); logViewerScroll = GUI.BeginScrollView(new Rect(num3, num5, num, num6), logViewerScroll, new Rect(0f, 0f, num7, num9)); GUI.Label(new Rect(4f, 4f, num7 - 8f, num9 - 4f), text, logViewerStyle); GUI.EndScrollView(); } private static bool IsAnotherTextInputActive() { try { if (s_eventSystemType == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { s_eventSystemType = assemblies[i].GetType("UnityEngine.EventSystems.EventSystem"); if (s_eventSystemType != null) { break; } } if (s_eventSystemType == null) { return false; } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public; s_eventSystemCurrentProp = s_eventSystemType.GetProperty("current", bindingAttr); s_eventSystemSelectedProp = s_eventSystemType.GetProperty("currentSelectedGameObject", BindingFlags.Instance | BindingFlags.Public); } object obj = s_eventSystemCurrentProp?.GetValue(null); if (obj == null) { return false; } object? obj2 = s_eventSystemSelectedProp?.GetValue(obj); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)val == (Object)null) { return false; } if (!val.activeInHierarchy) { return false; } Component[] components = val.GetComponents(); foreach (Component val2 in components) { if ((Object)(object)val2 == (Object)null) { continue; } string name = ((object)val2).GetType().Name; if (!(name != "InputField") || !(name != "TMP_InputField") || name.EndsWith("InputField")) { PropertyInfo property = ((object)val2).GetType().GetProperty("isActiveAndEnabled", BindingFlags.Instance | BindingFlags.Public); if (property != null && (bool)property.GetValue(val2)) { return true; } } } return false; } catch { return false; } } private static void DrawChatInput() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Invalid comparison between Unknown and I4 //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Invalid comparison between Unknown and I4 //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Invalid comparison between Unknown and I4 //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Invalid comparison between Unknown and I4 if (!Plugin.DataConsentGranted) { return; } bool flag = GameStateWatcher.IsInMatch && !NativeUI.IsOpen && GameStateWatcher.LocalAliveInCombatNow; if (bugModalOpen || logViewerOpen || bugAdminOpen || compareSearchFocused) { return; } Event current = Event.current; if (!chatInputOpen) { if (!flag && !IsAnotherTextInputActive() && current != null && (int)current.type == 4 && (int)current.keyCode == 116) { chatInputOpen = true; chatJustOpened = true; chatInputText = ""; current.Use(); } return; } if (chatJustOpened) { chatJustOpened = false; if (current != null && (int)current.type == 4) { current.Use(); } return; } if (chatStyle == null) { chatStyle = new GUIStyle(GUI.skin.textField) { fontSize = 16 }; } bool flag2 = false; bool flag3 = false; if (current != null && (int)current.type == 4) { if ((int)current.keyCode == 13 || (int)current.keyCode == 271) { flag2 = true; current.Use(); } else if ((int)current.keyCode == 27) { flag3 = true; current.Use(); } } float num = 1000f; float num2 = 56f; float num3 = Screen.height - 130; GUI.DrawTexture(new Rect(20f - 6f, num3 - 24f, num + 12f, num2 + 30f), (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.82f), 0f, 0f); GUI.Label(new Rect(20f, num3 - 22f, num, 20f), "Chat — Enter to send, Esc to cancel"); GUI.SetNextControlName("CRChat"); chatInputText = GUI.TextField(new Rect(20f, num3, num, num2), chatInputText ?? "", 480, chatStyle); GUI.FocusControl("CRChat"); if (flag2) { string text = (chatInputText ?? "").Trim(); if (!string.IsNullOrEmpty(text)) { if (text.StartsWith("/mute ", StringComparison.OrdinalIgnoreCase) || text.StartsWith("/unmute ", StringComparison.OrdinalIgnoreCase) || text.Equals("/muted", StringComparison.OrdinalIgnoreCase)) { NativeUI.HandleMuteCommand(text); } else { ChatClient.Send(GameStateWatcher.LocalSteamId, GameStateWatcher.LocalDisplayName, text); Plugin.Log.LogInfo((object)("[CHAT] -> sent: " + text)); } } chatInputText = ""; chatInputOpen = false; } else if (flag3) { chatInputText = ""; chatInputOpen = false; } } private static void EnsureConsentBlocker() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0140: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)consentBlockerGO != (Object)null) { return; } try { consentBlockerGO = new GameObject("CR_ConsentBlocker"); ((Object)consentBlockerGO).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)consentBlockerGO); if (UIFactory.tCanvas != null) { Component obj = consentBlockerGO.AddComponent(UIFactory.tCanvas); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; PropertyInfo property = UIFactory.tCanvas.GetProperty("renderMode", bindingAttr); property?.SetValue(obj, Enum.ToObject(property.PropertyType, 0)); UIFactory.tCanvas.GetProperty("sortingOrder", bindingAttr)?.SetValue(obj, 29998); } if (UIFactory.tGR != null) { consentBlockerGO.AddComponent(UIFactory.tGR); } RectTransform obj2 = consentBlockerGO.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = Vector2.zero; obj2.offsetMax = Vector2.zero; if (UIFactory.tImage != null) { Component obj3 = consentBlockerGO.AddComponent(UIFactory.tImage); BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public; UIFactory.tImage.GetProperty("color", bindingAttr2)?.SetValue(obj3, (object)new Color(0f, 0f, 0f, 0.001f)); UIFactory.tImage.GetProperty("raycastTarget", bindingAttr2)?.SetValue(obj3, true); } Plugin.Log.LogInfo((object)"[CONSENT] Blocker canvas created"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CONSENT] blocker create failed: " + ex.Message)); } } private static void DestroyConsentBlocker() { if (!((Object)(object)consentBlockerGO == (Object)null)) { try { Object.Destroy((Object)(object)consentBlockerGO); } catch { } consentBlockerGO = null; } } private static void DrawConsentModal() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0135: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Invalid comparison between Unknown and I4 //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Invalid comparison between Unknown and I4 //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Invalid comparison between Unknown and I4 if (Plugin.DataConsentAsked) { DestroyConsentBlocker(); return; } EnsureConsentBlocker(); Texture2D whiteTexture = Texture2D.whiteTexture; GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, 0.78f), 0f, 0f); float num = 680f; float num2 = 420f; float num3 = ((float)Screen.width - num) / 2f; float num4 = ((float)Screen.height - num2) / 2f; GUI.DrawTexture(new Rect(num3, num4, num, num2), (Texture)(object)whiteTexture, (ScaleMode)0, true, 0f, new Color(0.1f, 0.11f, 0.16f, 0.97f), 0f, 0f); if (consentTitleStyle == null) { consentTitleStyle = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; } if (consentBodyStyle == null) { consentBodyStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, wordWrap = true, alignment = (TextAnchor)0 }; } GUI.Label(new Rect(num3, num4 + 14f, num, 30f), "Competitive ROUNDS — Data Consent", consentTitleStyle); string text = "This mod sends data to a private server run by the mod author to power the leaderboard and ranked matchmaking.\n\nWhat gets recorded if you allow:\n • Your Steam ID and in-game display name\n • Your Discord ID and username, ONLY if you link your Discord via the in-game link code\n • Each match you play: rounds won, points, duration, cards picked, cards offered, opponent\n • Your Glicko-2 rating history\n\nWhat you can do later:\n • Revoke consent anytime (F5 → Settings → Revoke). Reporting stops.\n • Delete your data (F5 → Settings → Delete my data). Steam ID, display name, and Discord link are scrubbed. Matches stay so other players' ratings and histories aren't disturbed. Deletion is IRREVERSIBLE — you cannot re-register this Steam ID later.\n\nChoose Allow to use the leaderboard. Choose Decline to run the mod fully offline."; GUI.Label(new Rect(num3 + 24f, num4 + 50f, num - 48f, num2 - 120f), text, consentBodyStyle); if (GUI.Button(new Rect(num3 + 50f, num4 + num2 - 56f, 260f, 38f), "Allow data reporting")) { Plugin.DataConsent.Value = "granted"; Plugin.Log.LogInfo((object)"[CONSENT] User granted data reporting"); ApiClient.OnConsentChanged(); } if (GUI.Button(new Rect(num3 + num - 310f, num4 + num2 - 56f, 260f, 38f), "Decline (offline mode)")) { Plugin.DataConsent.Value = "denied"; Plugin.Log.LogInfo((object)"[CONSENT] User declined data reporting"); ApiClient.OnConsentChanged(); } if (Event.current != null) { EventType type = Event.current.type; if ((int)type == 0 || (int)type == 1 || (int)type == 4 || (int)type == 5) { Event.current.Use(); } } } private static void DrawFPS() { //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) bool flag = Plugin.ShowFps == null || Plugin.ShowFps.Value; bool flag2 = Plugin.ShowRegionPing == null || Plugin.ShowRegionPing.Value; if (!flag && !flag2) { return; } fpsCnt++; fpsTimer += Time.deltaTime; if (fpsTimer >= 0.5f) { fpsVal = (float)fpsCnt / fpsTimer; fpsCnt = 0; fpsTimer = 0f; } if (fpsStyle == null) { fpsStyle = new GUIStyle(GUI.skin.label); fpsStyle.fontSize = 11; fpsStyle.normal.textColor = new Color(0.5f, 0.5f, 0.5f, 0.7f); } string text = (flag ? $"{fpsVal:F0} FPS" : ""); float num = 60f; if (flag2) { try { if (PhotonNetwork.IsConnected && PhotonNetwork.InRoom) { int ping = PhotonNetwork.GetPing(); string text2 = PhotonNetwork.CloudRegion ?? ""; if (!string.IsNullOrEmpty(text2)) { int num2 = text2.IndexOf('/'); if (num2 > 0) { text2 = text2.Substring(0, num2); } text2 = text2.ToUpper(); } string text3 = $"{ping}ms {text2}"; text = (flag ? (text + " | " + text3) : text3); num = 200f; } } catch { } } if (!string.IsNullOrEmpty(text)) { GUI.Label(new Rect(6f, 4f, num, 18f), text, fpsStyle); } } private static void DrawNotification() { //IL_003b: 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_00d3: 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) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown if (notifTimer <= 0f && notifQueue.Count > 0) { QueuedNotif queuedNotif = notifQueue[0]; notifQueue.RemoveAt(0); notifText = queuedNotif.text; notifColor = queuedNotif.color; notifTimer = queuedNotif.dur; } if (!(notifTimer <= 0f)) { notifTimer -= Time.deltaTime; float num = Mathf.Clamp01(notifTimer); if (notifStyle == null) { notifStyle = new GUIStyle(GUI.skin.label); notifStyle.fontSize = 16; notifStyle.fontStyle = (FontStyle)1; notifStyle.alignment = (TextAnchor)4; } Color contentColor = new Color(notifColor.r, notifColor.g, notifColor.b, num); Color contentColor2 = GUI.contentColor; GUI.contentColor = contentColor; float num2 = 500f; float num3 = ((float)Screen.width - num2) / 2f; float num4 = Screen.height - 80; Texture2D whiteTexture = Texture2D.whiteTexture; GUI.DrawTexture(new Rect(num3, num4 - 2f, num2, 28f), (Texture)(object)whiteTexture, (ScaleMode)0, true, 0f, new Color(0f, 0f, 0f, num * 0.5f), 0f, 0f); GUI.Label(new Rect(num3, num4, num2, 24f), notifText, notifStyle); GUI.contentColor = contentColor2; } } private static void DrawMatchStatus() { //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0087: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: 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_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) if (!MatchTracker.IsInMatch) { return; } bool matchIsRanked = GameStateWatcher.MatchIsRanked; if (statusStyle == null) { statusStyle = new GUIStyle(GUI.skin.label); statusStyle.fontSize = 11; statusStyle.fontStyle = (FontStyle)1; statusStyle.alignment = (TextAnchor)4; } if (scoreStyle == null) { scoreStyle = new GUIStyle(GUI.skin.label); scoreStyle.fontSize = 14; scoreStyle.fontStyle = (FontStyle)1; scoreStyle.alignment = (TextAnchor)4; } Color contentColor = GUI.contentColor; float num; if (matchIsRanked) { GUI.contentColor = Color.green; GUI.Label(new Rect((float)(Screen.width - 140) / 2f, 8f, 140f, 18f), "RANKED - Recording", statusStyle); num = 28f; } else { num = 8f; } float num2 = num; if (matchIsRanked) { int currentSeriesGamesWon = GameStateWatcher.CurrentSeriesGamesWon; int currentSeriesGamesLost = GameStateWatcher.CurrentSeriesGamesLost; int sessionRankedWins = GameStateWatcher.SessionRankedWins; int sessionRankedLosses = GameStateWatcher.SessionRankedLosses; int sessionRankedSeriesWins = GameStateWatcher.SessionRankedSeriesWins; int sessionRankedSeriesLosses = GameStateWatcher.SessionRankedSeriesLosses; GUI.contentColor = new Color(1f, 0.85f, 0.3f); GUI.Label(new Rect((float)(Screen.width - 260) / 2f, num, 260f, 22f), $"Series: {currentSeriesGamesWon} - {currentSeriesGamesLost}", scoreStyle); GUI.contentColor = new Color(0.75f, 0.85f, 1f); GUI.Label(new Rect((float)(Screen.width - 320) / 2f, num + 18f, 320f, 20f), $"Session: {sessionRankedWins}-{sessionRankedLosses} games ({sessionRankedSeriesWins}-{sessionRankedSeriesLosses} series)", scoreStyle); num2 = num + 36f; } try { string opponentSteamId = GameStateWatcher.OpponentSteamId; string opponentDisplayName = GameStateWatcher.OpponentDisplayName; bool flag = false; try { Room currentRoom = PhotonNetwork.CurrentRoom; flag = ((Dictionary)(object)((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null))?.ContainsKey((object)"cr_ff") ?? false; } catch { } if (!flag && !string.IsNullOrEmpty(opponentDisplayName) && opponentDisplayName != "Opponent" && (opponentSteamId == null || !opponentSteamId.StartsWith("photon_"))) { Dictionary sessionWLByOpponent = GameStateWatcher.SessionWLByOpponent; if (sessionWLByOpponent != null && sessionWLByOpponent.TryGetValue(opponentDisplayName, out var value) && value != null && value.Length >= 4) { int num3 = value[0] + value[2]; int num4 = value[1] + value[3]; if (num3 + num4 > 0) { GUI.contentColor = ((num3 > num4) ? new Color(0.6f, 1f, 0.6f) : ((num3 < num4) ? new Color(1f, 0.6f, 0.6f) : new Color(0.85f, 0.85f, 0.85f))); string arg = ((opponentDisplayName.Length > 18) ? opponentDisplayName.Substring(0, 18) : opponentDisplayName); GUI.Label(new Rect((float)(Screen.width - 360) / 2f, num2, 360f, 20f), $"vs {arg}: {num3}-{num4} this session", scoreStyle); } else { GUI.contentColor = new Color(0.7f, 0.7f, 0.7f); string text = ((opponentDisplayName.Length > 18) ? opponentDisplayName.Substring(0, 18) : opponentDisplayName); GUI.Label(new Rect((float)(Screen.width - 360) / 2f, num2, 360f, 20f), "vs " + text + ": first game this session", scoreStyle); } } else { GUI.contentColor = new Color(0.7f, 0.7f, 0.7f); string text2 = ((opponentDisplayName.Length > 18) ? opponentDisplayName.Substring(0, 18) : opponentDisplayName); GUI.Label(new Rect((float)(Screen.width - 360) / 2f, num2, 360f, 20f), "vs " + text2 + ": first game this session", scoreStyle); } } } catch { } GUI.contentColor = contentColor; } } internal static class CursorColorCosmetic { private static string _activeSku = ""; private static Color _activeColor = Color.white; private static Texture2D _activeTex; private static Vector2 _activeHotspot = new Vector2(1f, 1f); private static Coroutine _maintainLoop; private static bool _started; private static readonly Dictionary _texCache = new Dictionary(); public static readonly string[] Shapes = new string[5] { "default", "arrow", "dot", "crosshair", "circle" }; public static readonly string[] ShapeLabels = new string[5] { "ROUNDS default", "Arrow", "Dot", "Crosshair", "Circle" }; private const string SHAPE_PREF = "cr_cursor_shape"; private static string _shape; private const int SZ = 32; private static readonly Vector2[] ARROW = (Vector2[])(object)new Vector2[7] { new Vector2(0f, 0f), new Vector2(0f, 0.78f), new Vector2(0.22f, 0.6f), new Vector2(0.36f, 0.92f), new Vector2(0.5f, 0.86f), new Vector2(0.34f, 0.55f), new Vector2(0.6f, 0.55f) }; public static string CurrentShape { get { if (_shape == null) { _shape = LoadShape(); } return _shape; } } private static string LoadShape() { try { string text = PlayerPrefs.GetString("cr_cursor_shape", "default"); return (Array.IndexOf(Shapes, text) >= 0) ? text : "default"; } catch { return "default"; } } public static string CurrentShapeLabel() { int num = Array.IndexOf(Shapes, CurrentShape); if (num < 0) { return "ROUNDS default"; } return ShapeLabels[num]; } public static void CycleShape() { int num = Array.IndexOf(Shapes, CurrentShape); _shape = Shapes[(Mathf.Max(0, num) + 1) % Shapes.Length]; try { PlayerPrefs.SetString("cr_cursor_shape", _shape); PlayerPrefs.Save(); } catch { } ApplyFromStats(); } public static void Initialize() { if (_started) { return; } try { if (!((Object)(object)Plugin.Instance == (Object)null)) { _maintainLoop = ((MonoBehaviour)Plugin.Instance).StartCoroutine(MaintainLoop()); _started = true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CURSOR] init failed: " + ex.Message)); } } public static void ApplyFromStats() { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; string sku = cachedPlayerStats?.active_cursor_color_sku ?? ""; string hex = cachedPlayerStats?.active_cursor_color_hex ?? ""; Apply(sku, hex); } public static void Apply(string sku, string hex) { //IL_0030: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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) try { if (!_started) { Initialize(); } string currentShape = CurrentShape; if (currentShape == "default") { _activeSku = ""; _activeTex = null; Cursor.SetCursor((Texture2D)null, Vector2.zero, (CursorMode)0); return; } Color val = (string.IsNullOrEmpty(sku) ? Color.white : ParseHex(hex, Color.white)); _activeSku = currentShape + "|" + sku; _activeColor = val; _activeTex = GetTintedCursor(currentShape, hex, val); _activeHotspot = ((currentShape == "arrow") ? new Vector2(1f, 1f) : new Vector2(16f, 16f)); if ((Object)(object)_activeTex != (Object)null) { Cursor.SetCursor(_activeTex, _activeHotspot, (CursorMode)0); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CURSOR] Apply failed: " + ex.Message)); } } private static IEnumerator MaintainLoop() { WaitForSeconds wait = new WaitForSeconds(2.5f); while (true) { yield return wait; try { if (!string.IsNullOrEmpty(_activeSku) && (Object)(object)_activeTex != (Object)null) { Cursor.SetCursor(_activeTex, _activeHotspot, (CursorMode)0); } } catch { } } } private static Texture2D GetTintedCursor(string shape, string hex, Color c) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) string key = shape + ":" + (string.IsNullOrEmpty(hex) ? "#FFFFFF" : hex); if (_texCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = BuildFromMask(BuildShapeMask(shape), c); _texCache[key] = val; return val; } private static bool[] BuildShapeMask(string shape) { //IL_0211: Unknown result type (might be due to invalid IL or missing references) bool[] array = new bool[1024]; float num = 16f; float num2 = 16f; switch (shape) { case "dot": { float num16 = 4.5f; for (int num17 = 0; num17 < 32; num17++) { for (int num18 = 0; num18 < 32; num18++) { float num19 = (float)num18 + 0.5f - num; float num20 = (float)num17 + 0.5f - num2; if (num19 * num19 + num20 * num20 <= num16 * num16) { array[num17 * 32 + num18] = true; } } } break; } case "circle": { float num5 = 9f; float num6 = 6f; for (int k = 0; k < 32; k++) { for (int l = 0; l < 32; l++) { float num7 = (float)l + 0.5f - num; float num8 = (float)k + 0.5f - num2; float num9 = num7 * num7 + num8 * num8; if (num9 <= num5 * num5 && num9 >= num6 * num6) { array[k * 32 + l] = true; } } } break; } case "crosshair": { int num10 = 1; int num11 = 3; int num12 = 11; for (int m = 0; m < 32; m++) { for (int n = 0; n < 32; n++) { float num13 = (float)n + 0.5f - num; float num14 = (float)m + 0.5f - num2; bool num15 = Mathf.Abs(num14) <= (float)num10 && Mathf.Abs(num13) >= (float)num11 && Mathf.Abs(num13) <= (float)num12; bool flag = Mathf.Abs(num13) <= (float)num10 && Mathf.Abs(num14) >= (float)num11 && Mathf.Abs(num14) <= (float)num12; bool flag2 = num13 * num13 + num14 * num14 <= 2.5600002f; if (num15 || flag || flag2) { array[m * 32 + n] = true; } } } break; } default: { for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num3 = (float)j / 31f; float num4 = 1f - (float)i / 31f; if (PointInPoly(new Vector2(num3, num4), ARROW)) { array[i * 32 + j] = true; } } } break; } } return array; } private static Texture2D BuildFromMask(bool[] solid, Color fill) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0069: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < array.Length; i++) { array[i] = (Color)(solid[i] ? fill : new Color(0f, 0f, 0f, 0f)); } Color val2 = ((fill.r * 0.299f + fill.g * 0.587f + fill.b * 0.114f > 0.5f) ? new Color(0.05f, 0.05f, 0.05f, 1f) : new Color(0.95f, 0.95f, 0.95f, 1f)); Color[] array2 = (Color[])array.Clone(); for (int j = 0; j < 32; j++) { for (int k = 0; k < 32; k++) { if (solid[j * 32 + k]) { continue; } bool flag = false; for (int l = -1; l <= 1; l++) { if (flag) { break; } for (int m = -1; m <= 1; m++) { int num = k + m; int num2 = j + l; if (num >= 0 && num2 >= 0 && num < 32 && num2 < 32 && solid[num2 * 32 + num]) { flag = true; break; } } } if (flag) { array2[j * 32 + k] = val2; } } } val.SetPixels(array2); val.Apply(); return val; } private static Texture2D BuildArrowTex(Color fill) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; Color[] array = (Color[])(object)new Color[1024]; bool[] array2 = new bool[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = (float)j / 31f; float num2 = 1f - (float)i / 31f; array[i * 32 + j] = (Color)((array2[i * 32 + j] = PointInPoly(new Vector2(num, num2), ARROW)) ? fill : new Color(0f, 0f, 0f, 0f)); } } Color val2 = ((fill.r * 0.299f + fill.g * 0.587f + fill.b * 0.114f > 0.5f) ? new Color(0.05f, 0.05f, 0.05f, 1f) : new Color(0.95f, 0.95f, 0.95f, 1f)); Color[] array3 = (Color[])array.Clone(); for (int k = 0; k < 32; k++) { for (int l = 0; l < 32; l++) { if (array2[k * 32 + l]) { continue; } bool flag = false; for (int m = -1; m <= 1; m++) { if (flag) { break; } for (int n = -1; n <= 1; n++) { int num3 = l + n; int num4 = k + m; if (num3 >= 0 && num4 >= 0 && num3 < 32 && num4 < 32 && array2[num4 * 32 + num3]) { flag = true; break; } } } if (flag) { array3[k * 32 + l] = val2; } } } val.SetPixels(array3); val.Apply(); return val; } private static bool PointInPoly(Vector2 p, Vector2[] poly) { //IL_001d: 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_003b: 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) bool flag = false; int num = poly.Length; int num2 = 0; int num3 = num - 1; while (num2 < num) { if (poly[num2].y > p.y != poly[num3].y > p.y && p.x < (poly[num3].x - poly[num2].x) * (p.y - poly[num2].y) / (poly[num3].y - poly[num2].y) + poly[num2].x) { flag = !flag; } num3 = num2++; } return flag; } private static Color ParseHex(string hex, Color fallback) { //IL_0080: 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) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(hex)) { return fallback; } if (hex.StartsWith("#")) { hex = hex.Substring(1); } if (hex.Length != 6) { return fallback; } try { int num = Convert.ToInt32(hex.Substring(0, 2), 16); int num2 = Convert.ToInt32(hex.Substring(2, 2), 16); int num3 = Convert.ToInt32(hex.Substring(4, 2), 16); return new Color((float)num / 255f, (float)num2 / 255f, (float)num3 / 255f, 1f); } catch { return fallback; } } } internal static class CustomMapColors { private struct Preset { public string BaseArt; public Color? MapBlockColor; public Color? SecondaryColor; public Action Configure; } private static readonly Dictionary _profileCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary _presets = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "mapcolor_soft", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.52f, 0.6f, 0.72f), SecondaryColor = new Color(0.92f, 0.66f, 0.48f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-24f); ((ParameterOverride)(object)cg.temperature).Override(4f); ((ParameterOverride)(object)cg.postExposure).Override(-0.35f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.5f, 0.5f, 0.54f)); } } }, { "mapcolor_moss", new Preset { BaseArt = "Poison", MapBlockColor = new Color(0.44f, 0.64f, 0.4f), SecondaryColor = new Color(0.78f, 0.62f, 0.38f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-18f); ((ParameterOverride)(object)cg.temperature).Override(8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.5f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.42f, 0.47f, 0.42f)); } } }, { "mapcolor_cream", new Preset { BaseArt = "Gold", MapBlockColor = new Color(0.9f, 0.82f, 0.62f), SecondaryColor = new Color(0.56f, 0.74f, 0.92f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-16f); ((ParameterOverride)(object)cg.temperature).Override(-8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.32f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.54f, 0.53f, 0.52f)); } } }, { "mapcolor_lavender", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.72f, 0.62f, 0.92f), SecondaryColor = new Color(0.92f, 0.8f, 0.5f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-18f); ((ParameterOverride)(object)cg.temperature).Override(4f); ((ParameterOverride)(object)cg.postExposure).Override(-0.4f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.5f, 0.48f, 0.55f)); } } }, { "mapcolor_dusk", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.34f, 0.46f, 0.78f), SecondaryColor = new Color(0.96f, 0.64f, 0.3f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-14f); ((ParameterOverride)(object)cg.temperature).Override(8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.6f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.39f, 0.4f, 0.48f)); } } }, { "mapcolor_sand", new Preset { BaseArt = "Gold", MapBlockColor = new Color(0.9f, 0.72f, 0.42f), SecondaryColor = new Color(0.38f, 0.72f, 0.74f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-14f); ((ParameterOverride)(object)cg.temperature).Override(-8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.4f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.52f, 0.5f, 0.45f)); } } }, { "mapcolor_mono", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.82f, 0.82f, 0.83f), SecondaryColor = new Color(0.42f, 0.42f, 0.43f), Configure = delegate(ColorGrading cg) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-100f); ((ParameterOverride)(object)cg.postExposure).Override(-0.42f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.49f, 0.49f, 0.49f)); } } }, { "mapcolor_forest", new Preset { BaseArt = "Poison", MapBlockColor = new Color(0.26f, 0.54f, 0.3f), SecondaryColor = new Color(0.54f, 0.4f, 0.24f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-14f); ((ParameterOverride)(object)cg.temperature).Override(-4f); ((ParameterOverride)(object)cg.postExposure).Override(-0.54f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.39f, 0.45f, 0.39f)); } } }, { "mapcolor_amethyst", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.66f, 0.42f, 0.88f), SecondaryColor = new Color(0.9f, 0.72f, 0.38f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.48f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.45f, 0.42f, 0.49f)); } } }, { "mapcolor_charcoal", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.74f, 0.75f, 0.76f), SecondaryColor = new Color(0.44f, 0.45f, 0.47f), Configure = delegate(ColorGrading cg) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-80f); ((ParameterOverride)(object)cg.postExposure).Override(-0.6f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.39f, 0.39f, 0.41f)); } } }, { "mapcolor_crimson_map", new Preset { BaseArt = "Soviet", MapBlockColor = new Color(0.84f, 0.28f, 0.3f), SecondaryColor = new Color(0.3f, 0.68f, 0.64f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(-8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.56f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.44f, 0.39f, 0.4f)); } } }, { "mapcolor_slate", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.46f, 0.58f, 0.74f), SecondaryColor = new Color(0.84f, 0.56f, 0.32f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-20f); ((ParameterOverride)(object)cg.temperature).Override(6f); ((ParameterOverride)(object)cg.postExposure).Override(-0.46f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.46f, 0.48f, 0.51f)); } } }, { "mapcolor_rose", new Preset { BaseArt = "Gold", MapBlockColor = new Color(0.88f, 0.52f, 0.6f), SecondaryColor = new Color(0.44f, 0.74f, 0.64f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-14f); ((ParameterOverride)(object)cg.temperature).Override(4f); ((ParameterOverride)(object)cg.postExposure).Override(-0.4f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.52f, 0.48f, 0.51f)); } } }, { "mapcolor_mint", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.56f, 0.88f, 0.7f), SecondaryColor = new Color(0.98f, 0.58f, 0.5f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(-2f); ((ParameterOverride)(object)cg.postExposure).Override(-0.4f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.48f, 0.52f, 0.5f)); } } }, { "mapcolor_sunset", new Preset { BaseArt = "Gold", MapBlockColor = new Color(0.98f, 0.56f, 0.3f), SecondaryColor = new Color(0.56f, 0.42f, 0.78f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-6f); ((ParameterOverride)(object)cg.temperature).Override(-6f); ((ParameterOverride)(object)cg.postExposure).Override(-0.48f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.48f, 0.43f, 0.47f)); } } }, { "mapcolor_obsidian", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.42f, 0.48f, 0.6f), SecondaryColor = new Color(0.66f, 0.74f, 0.88f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-30f); ((ParameterOverride)(object)cg.temperature).Override(-8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.7f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.36f, 0.37f, 0.42f)); } } }, { "mapcolor_abyss", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.24f, 0.52f, 0.64f), SecondaryColor = new Color(0.42f, 0.86f, 0.88f), Configure = delegate(ColorGrading cg) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(-22f); ((ParameterOverride)(object)cg.tint).Override(-8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.7f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.34f, 0.4f, 0.44f)); } } }, { "mapcolor_pine", new Preset { BaseArt = "Poison", MapBlockColor = new Color(0.28f, 0.52f, 0.44f), SecondaryColor = new Color(0.62f, 0.4f, 0.26f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-14f); ((ParameterOverride)(object)cg.temperature).Override(-6f); ((ParameterOverride)(object)cg.postExposure).Override(-0.6f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.37f, 0.43f, 0.41f)); } } }, { "mapcolor_iron", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.56f, 0.6f, 0.66f), SecondaryColor = new Color(0.82f, 0.5f, 0.28f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-30f); ((ParameterOverride)(object)cg.temperature).Override(4f); ((ParameterOverride)(object)cg.postExposure).Override(-0.54f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.42f, 0.43f, 0.46f)); } } }, { "mapcolor_burgundy", new Preset { BaseArt = "Soviet", MapBlockColor = new Color(0.68f, 0.24f, 0.36f), SecondaryColor = new Color(0.38f, 0.54f, 0.82f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(6f); ((ParameterOverride)(object)cg.postExposure).Override(-0.64f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.41f, 0.36f, 0.42f)); } } }, { "mapcolor_magma", new Preset { BaseArt = "Soviet", MapBlockColor = new Color(0.82f, 0.26f, 0.16f), SecondaryColor = new Color(0.99f, 0.76f, 0.24f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-4f); ((ParameterOverride)(object)cg.temperature).Override(20f); ((ParameterOverride)(object)cg.postExposure).Override(-0.54f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.46f, 0.4f, 0.35f)); } } }, { "mapcolor_velvet", new Preset { BaseArt = "Sky", MapBlockColor = new Color(0.5f, 0.28f, 0.7f), SecondaryColor = new Color(0.9f, 0.7f, 0.36f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-10f); ((ParameterOverride)(object)cg.temperature).Override(8f); ((ParameterOverride)(object)cg.postExposure).Override(-0.64f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.4f, 0.36f, 0.45f)); } } }, { "mapcolor_blackwood", new Preset { BaseArt = "Gold", MapBlockColor = new Color(0.5f, 0.5f, 0.54f), SecondaryColor = new Color(0.9f, 0.54f, 0.24f), Configure = delegate(ColorGrading cg) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) ((ParameterOverride)(object)cg.saturation).Override(-26f); ((ParameterOverride)(object)cg.temperature).Override(12f); ((ParameterOverride)(object)cg.postExposure).Override(-0.66f); ((ParameterOverride)(object)cg.colorFilter).Override(new Color(0.38f, 0.37f, 0.38f)); } } } }; public static bool IsCustomSku(string sku) { if (sku != null) { return _presets.ContainsKey(sku); } return false; } public static string FriendlyName(string sku) { if (string.IsNullOrEmpty(sku)) { return "Default"; } string text = (sku.StartsWith("mapcolor_", StringComparison.OrdinalIgnoreCase) ? sku.Substring(9) : sku); if (text.EndsWith("_map", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 4); } text = text.Replace('_', ' ').Trim(); if (text.Length == 0) { return "Default"; } string[] array = text.Split(' '); for (int i = 0; i < array.Length; i++) { if (array[i].Length > 0) { array[i] = char.ToUpperInvariant(array[i][0]) + array[i].Substring(1); } } return string.Join(" ", array); } public static string GetBaseArt(string sku) { if (sku != null && _presets.TryGetValue(sku, out var value)) { return value.BaseArt; } return null; } public static Color? GetMapBlockColor(string sku) { if (sku != null && _presets.TryGetValue(sku, out var value)) { return value.MapBlockColor; } return null; } public static Color GetSecondaryColor(string sku) { //IL_0046: 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_004b: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (sku != null && _presets.TryGetValue(sku, out var value) && value.SecondaryColor.HasValue) { return value.SecondaryColor.Value; } Color val = (Color)(((??)GetMapBlockColor(sku)) ?? Color.white); return new Color(val.r * 0.6f, val.g * 0.6f, val.b * 0.6f, val.a); } public static PostProcessProfile BuildOrGetClone(string sku, PostProcessProfile baseProfile) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)baseProfile == (Object)null || !_presets.TryGetValue(sku, out var value)) { return null; } if (_profileCache.TryGetValue(sku, out var value2) && (Object)(object)value2 != (Object)null) { return value2; } try { PostProcessProfile val = Object.Instantiate(baseProfile); ((Object)val).name = "CR_MapColor_" + sku; ((Object)val).hideFlags = (HideFlags)61; if (val.HasSettings()) { val.RemoveSettings(); } ColorGrading val2 = ScriptableObject.CreateInstance(); ((Object)val2).hideFlags = (HideFlags)61; ((ParameterOverride)(object)((PostProcessEffectSettings)val2).enabled).Override(true); ((ParameterOverride)(object)val2.gradingMode).Override((GradingMode)0); value.Configure(val2); try { Color val3 = (Color)(((??)GetMapBlockColor(sku)) ?? new Color(0.5f, 0.5f, 0.5f)); Color val4 = default(Color); ((Color)(ref val4))..ctor(Mathf.Clamp01(0.35f + val3.r * 0.75f), Mathf.Clamp01(0.35f + val3.g * 0.75f), Mathf.Clamp01(0.35f + val3.b * 0.75f)); Color val5 = Color.Lerp(new Color(0.5f, 0.5f, 0.5f), val4, 0.6f); ((ParameterOverride)(object)val2.colorFilter).Override(val5); float num = Mathf.Max(val3.r, Mathf.Max(val3.g, val3.b)); float num2 = Mathf.Min(val3.r, Mathf.Min(val3.g, val3.b)); if (!(num - num2 < 0.08f)) { ((ParameterOverride)(object)val2.saturation).Override(12f); } } catch { } val.AddSettings((PostProcessEffectSettings)(object)val2); _profileCache[sku] = val; return val; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MAPCOLOR] Clone " + sku + " failed: " + ex.Message)); return null; } } } public static class GameStateWatcher { [CompilerGenerated] private static class <>O { public static LogCallback <0>__OnUnityLog; } private static bool wasInRoom = false; private static bool isTracking = false; private static bool wasGameInProgress = false; private static bool pcolorRoomApplied = false; private static DateTime matchStartTime; private static int lastP1Points = 0; private static int lastP2Points = 0; private static int lastP1Rounds = 0; private static int lastP2Rounds = 0; private static int p1Points = 0; private static int p2Points = 0; private static int p1Rounds = 0; private static int p2Rounds = 0; private static int currentRound = 1; private static string localSteamId = ""; private static string localDisplayName = ""; private static string opponentSteamId = ""; private static string opponentDisplayName = ""; private static int localTeamId = -1; private static bool playersIdentified = false; private static bool opponentSteamIdResolved = false; private static bool opponentIsRanked = false; private static bool opponentRankChecked = false; private static float lastOpponentRankCheck = -999f; private static bool seriesPreflightSent = false; private static bool matchIsRanked = false; private static bool opponentCardsViaHarmony = false; private static List preMatchOpponentCards = new List(); private static List localCards = new List(); private static List opponentCards = new List(); private static List localOffers = new List(); private static readonly List emptyOffers = new List(); private static int lastKnownP1CardCount = 0; private static int lastKnownP2CardCount = 0; private static List broadcastCardNames = new List(); private static int lastKnownOpponentBroadcastCount = 0; private const string CARD_PROP_KEY = "cr_cards"; private const string FPS_PROP_KEY = "cr_fps"; private static int fpsFrameCount = 0; private static float fpsTimeAccum = 0f; private static float fpsBroadcastTimer = 0f; private static int opponentAvgFps = 0; private static List preMatchCards = new List(); private static int preMatchPickCount = 0; private static string photonRoomId = ""; private static string photonRegion = ""; private static bool gameOverReported = false; private static bool opponentWasPresent = false; private static bool opponentDCReported = false; private static FieldInfo f_p1Points; private static FieldInfo f_p2Points; private static FieldInfo f_p1Rounds; private static FieldInfo f_p2Rounds; private static FieldInfo f_roundsToWinGame; private static bool fieldsResolved = false; private static int roundsToWin = 5; private static float pollTimer = 0f; private static DateTime roomJoinTime; private static DateTime sessionStartTime = DateTime.UtcNow; private static Dictionary sessionTimeByOpponent = new Dictionary(); private static int sessionMatchCount = 0; private static Dictionary sessionWLByOpponent = new Dictionary(); private static int sessionRankedWins = 0; private static int sessionRankedLosses = 0; private static int sessionRankedSeriesWins = 0; private static int sessionRankedSeriesLosses = 0; private static int currentSeriesGamesWon = 0; private static int currentSeriesGamesLost = 0; private static int sessionCasualWins = 0; private static int sessionCasualLosses = 0; private static int sessionTeamSeriesWins = 0; private static int sessionTeamSeriesLosses = 0; private static bool achTookDamage = false; private static bool achPhoenixUsed = false; private static bool achDied = false; private static int achMaxOpponentRounds = 0; private static bool achWasDown04 = false; private static bool lastDeadState = false; private static int lastRemainingRespawns = -1; private static bool achFiredShot = false; private static bool achMoved = false; private static bool _loggedFirstFire; private static bool _loggedFirstHit; private static bool _loggedFirstBlockAct; private static bool _loggedFirstBlockOk; private static float _lastBlockSuccessTime = -999f; private static int _hitsRemaining; private const float BLOCK_ACTIVE_WINDOW = 0.5f; private static bool inPickPhase = false; private const string SID_STEAM_ID = "76561198040410653"; private const double SESSION_INACTIVITY_HOURS = 3.0; private const string PP_SESSION_LAST_ACTIVITY = "cr_session_last_activity_unix"; private const string PP_SESSION_START = "cr_session_start_unix"; private const string PP_SESSION_MATCHES = "cr_session_match_count"; private const string PP_SESSION_RW = "cr_session_ranked_wins"; private const string PP_SESSION_RL = "cr_session_ranked_losses"; private const string PP_SESSION_CW = "cr_session_casual_wins"; private const string PP_SESSION_CL = "cr_session_casual_losses"; private const string PP_SESSION_RSW = "cr_session_rseries_wins"; private const string PP_SESSION_RSL = "cr_session_rseries_losses"; private const string PP_SESSION_T2W = "cr_session_tseries_wins"; private const string PP_SESSION_T2L = "cr_session_tseries_losses"; private const string PP_SESSION_WL_BY_OPP = "cr_session_wl_by_opp"; private const string PP_SESSION_TIME_BY_OPP = "cr_session_time_by_opp"; private static bool _runInBackgroundOverridden = false; private static bool _origRunInBackground = false; private static DateTime _stuckOverlayDismissedAt = DateTime.MinValue; private static bool _rankedSyncSent; public static bool pendingRegicideCheck = false; private static bool logListenerRegistered = false; private static int pickCountThisMatch = 0; private static string _lastLocalPickedCardName; public static int LocalAvgFps { get { if (!(fpsTimeAccum > 0.5f)) { return 0; } return (int)Math.Round((double)fpsFrameCount / (double)fpsTimeAccum); } } public static int OpponentAvgFps => opponentAvgFps; public static int LocalShotsThisMatch { get; private set; } public static int LocalBlocksThisMatch { get; private set; } public static int LocalBulletsFiredThisMatch { get; private set; } public static int LocalBulletsHitThisMatch { get; private set; } public static int LocalBlocksActivatedThisMatch { get; private set; } public static int LocalBlocksSuccessfulThisMatch { get; private set; } public static int LocalBlockRawAbsorbs { get; private set; } public static int LocalBlockDedupeDrops { get; private set; } public static float LastBlockActivatedTime { get; private set; } = -999f; public static float LastBlockSuccessfulTime { get; private set; } = -999f; public static float LastBlockAbsorbTime { get; private set; } = -999f; public static float LastLocalHitTime { get; private set; } = -999f; public static float LastBlockMissTime { get; private set; } = -999f; public static string LastBlockEventLabel { get; private set; } = ""; public static MatchTracker.MatchResult LastResult { get; private set; } public static bool HasPendingResult { get; private set; } = false; public static bool MatchIsRanked => matchIsRanked; public static int LastP1Points => p1Points; public static int LastP2Points => p2Points; public static Dictionary SessionTimeByOpponent => sessionTimeByOpponent; public static Dictionary SessionWLByOpponent => sessionWLByOpponent; public static int SessionMatchCount => sessionMatchCount; public static int SessionRankedWins => sessionRankedWins; public static int SessionRankedLosses => sessionRankedLosses; public static int SessionRankedSeriesWins => sessionRankedSeriesWins; public static int SessionRankedSeriesLosses => sessionRankedSeriesLosses; public static int CurrentSeriesGamesWon => currentSeriesGamesWon; public static int CurrentSeriesGamesLost => currentSeriesGamesLost; public static int SessionCasualWins => sessionCasualWins; public static int SessionCasualLosses => sessionCasualLosses; public static int SessionTeamSeriesWins => sessionTeamSeriesWins; public static int SessionTeamSeriesLosses => sessionTeamSeriesLosses; public static DateTime SessionStartTime => sessionStartTime; public static bool ShouldShowMatchFoundStuckOverlay { get; private set; } public static int SecondsInUnstartedRoom { get; private set; } public static bool LocalAliveInCombatNow { get; private set; } public static bool IsInMatch => isTracking; public static bool IsInRoom => wasInRoom; public static bool LeavingForRanked { get; set; } = false; public static string LocalSteamId => localSteamId; public static string LocalDisplayName => localDisplayName; public static string OpponentDisplayName => opponentDisplayName; public static string OpponentSteamId => opponentSteamId; public static int P1Rounds => p1Rounds; public static int P2Rounds => p2Rounds; public static int P1Points => p1Points; public static int P2Points => p2Points; public static int LocalTeamId => localTeamId; public static int CurrentRound => currentRound; public static int LocalOffersCount => localOffers.Count; public static string LastLocalPickedCardName => _lastLocalPickedCardName; public static void OnLocalBulletFired(int projectiles) { if (isTracking && !inPickPhase) { if (projectiles < 1) { projectiles = 1; } LocalBulletsFiredThisMatch += projectiles; _hitsRemaining += projectiles; if (!_loggedFirstFire) { _loggedFirstFire = true; Plugin.Log.LogInfo((object)$"[STATS] first bullet fired this match (projectiles={projectiles})"); } } } public static void OnLocalBulletHit() { if (isTracking && !inPickPhase && _hitsRemaining > 0) { _hitsRemaining--; LocalBulletsHitThisMatch++; if (!_loggedFirstHit) { _loggedFirstHit = true; Plugin.Log.LogInfo((object)"[STATS] first bullet-hit this match"); } } } public static void OnLocalBlockActivated() { if (isTracking && !inPickPhase) { LocalBlocksActivatedThisMatch++; LastBlockActivatedTime = Time.time; float num = Time.time - LastLocalHitTime; if (num >= 0f && num < 0.25f) { LastBlockMissTime = Time.time; LastBlockEventLabel = $"TOO SLOW (block +{num * 1000f:F0}ms after hit)"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] TOO-SLOW act={LocalBlocksActivatedThisMatch} hit_to_block={num * 1000f:F0}ms"); } else { LastBlockEventLabel = $"ACTIVATED #{LocalBlocksActivatedThisMatch}"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] ACTIVATED act={LocalBlocksActivatedThisMatch} succ={LocalBlocksSuccessfulThisMatch}/{LocalBlockRawAbsorbs}"); } if (!_loggedFirstBlockAct) { _loggedFirstBlockAct = true; Plugin.Log.LogInfo((object)"[STATS] first block activation this match"); } } } public static void OnLocalPlayerHit(float damage) { if (isTracking && !inPickPhase) { LastLocalHitTime = Time.time; LastBlockMissTime = Time.time; float num = Time.time - LastBlockActivatedTime; if (num > 0f && num < 0.5f) { LastBlockEventLabel = $"HIT (block active, {num * 1000f:F0}ms in) — unblockable?"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] HIT-ACTIVE act={LocalBlocksActivatedThisMatch} since_act={num * 1000f:F0}ms dmg={damage:F1}"); } else if (num > 0.5f && num < 2f) { LastBlockEventLabel = $"TOO EARLY (blocked {num * 1000f:F0}ms before hit)"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] TOO-EARLY since_act={num * 1000f:F0}ms dmg={damage:F1}"); } else { LastBlockEventLabel = "HIT (no recent block)"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] HIT-NOBLK since_act={num:F1}s dmg={damage:F1}"); } } } public static void OnLocalBlockSuccessful() { if (!isTracking || inPickPhase) { return; } LocalBlockRawAbsorbs++; LastBlockAbsorbTime = Time.time; float num = Time.time - _lastBlockSuccessTime; if (num < 1f) { LocalBlockDedupeDrops++; LastBlockEventLabel = $"ABSORB (deduped, +{num:F2}s)"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] ABSORB-DEDUP raw={LocalBlockRawAbsorbs} since_last_credit={num:F2}s credited={LocalBlocksSuccessfulThisMatch}"); return; } _lastBlockSuccessTime = Time.time; LocalBlocksSuccessfulThisMatch++; LastBlockSuccessfulTime = Time.time; LastBlockEventLabel = $"SUCCESSFUL #{LocalBlocksSuccessfulThisMatch}"; Plugin.Log.LogInfo((object)$"[BLOCK-DBG] SUCCESS act={LocalBlocksActivatedThisMatch} succ={LocalBlocksSuccessfulThisMatch} raw={LocalBlockRawAbsorbs} drops={LocalBlockDedupeDrops}"); if (!_loggedFirstBlockOk) { _loggedFirstBlockOk = true; Plugin.Log.LogInfo((object)"[STATS] first successful block this match"); } } public static void IncrementSessionRankedSeries(bool won) { if (won) { sessionRankedSeriesWins++; } else { sessionRankedSeriesLosses++; } currentSeriesGamesWon = 0; currentSeriesGamesLost = 0; Plugin.Log.LogInfo((object)$"[SESSION] Ranked series tally: {sessionRankedSeriesWins}-{sessionRankedSeriesLosses}; current series counters reset"); SaveSessionState(); } public static void ResetCurrentSeriesScore() { currentSeriesGamesWon = 0; currentSeriesGamesLost = 0; } public static void RecordSessionTeamSeries(bool won) { if (won) { sessionTeamSeriesWins++; } else { sessionTeamSeriesLosses++; } SaveSessionState(); } private static long _DtToUnix(DateTime utc) { DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return (long)(utc.ToUniversalTime() - dateTime).TotalSeconds; } private static DateTime _UnixToDt(long secs) { return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(secs); } public static void SaveSessionState() { try { PlayerPrefs.SetString("cr_session_last_activity_unix", _DtToUnix(DateTime.UtcNow).ToString()); PlayerPrefs.SetString("cr_session_start_unix", _DtToUnix(sessionStartTime).ToString()); PlayerPrefs.SetInt("cr_session_match_count", sessionMatchCount); PlayerPrefs.SetInt("cr_session_ranked_wins", sessionRankedWins); PlayerPrefs.SetInt("cr_session_ranked_losses", sessionRankedLosses); PlayerPrefs.SetInt("cr_session_casual_wins", sessionCasualWins); PlayerPrefs.SetInt("cr_session_casual_losses", sessionCasualLosses); PlayerPrefs.SetInt("cr_session_rseries_wins", sessionRankedSeriesWins); PlayerPrefs.SetInt("cr_session_rseries_losses", sessionRankedSeriesLosses); PlayerPrefs.SetInt("cr_session_tseries_wins", sessionTeamSeriesWins); PlayerPrefs.SetInt("cr_session_tseries_losses", sessionTeamSeriesLosses); StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (KeyValuePair item in sessionWLByOpponent) { if (item.Value != null && item.Value.Length >= 4) { string value = (item.Key ?? "").Replace("|", "/").Replace("=", "-").Replace(",", "."); if (!flag) { stringBuilder.Append('|'); } stringBuilder.Append(value).Append('=').Append(item.Value[0]) .Append(',') .Append(item.Value[1]) .Append(',') .Append(item.Value[2]) .Append(',') .Append(item.Value[3]); flag = false; } } PlayerPrefs.SetString("cr_session_wl_by_opp", stringBuilder.ToString()); StringBuilder stringBuilder2 = new StringBuilder(); bool flag2 = true; foreach (KeyValuePair item2 in sessionTimeByOpponent) { string value2 = (item2.Key ?? "").Replace("|", "/").Replace("=", "-"); if (!flag2) { stringBuilder2.Append('|'); } stringBuilder2.Append(value2).Append('=').Append(item2.Value.ToString("F2", CultureInfo.InvariantCulture)); flag2 = false; } PlayerPrefs.SetString("cr_session_time_by_opp", stringBuilder2.ToString()); PlayerPrefs.Save(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SESSION] save failed: " + ex.Message)); } } private static void LoadSessionStateOrReset() { try { string text = PlayerPrefs.GetString("cr_session_last_activity_unix", ""); if (string.IsNullOrEmpty(text)) { sessionStartTime = DateTime.UtcNow; Plugin.Log.LogInfo((object)"[SESSION] no prior session - starting fresh"); return; } if (!long.TryParse(text, out var result)) { sessionStartTime = DateTime.UtcNow; return; } DateTime dateTime = _UnixToDt(result); double totalHours = (DateTime.UtcNow - dateTime).TotalHours; if (totalHours > 3.0 || totalHours < 0.0) { sessionStartTime = DateTime.UtcNow; Plugin.Log.LogInfo((object)$"[SESSION] last activity {totalHours:F1}h ago (>{3.0}h) - starting fresh"); return; } sessionStartTime = _UnixToDt(long.Parse(PlayerPrefs.GetString("cr_session_start_unix", result.ToString()))); sessionMatchCount = PlayerPrefs.GetInt("cr_session_match_count", 0); sessionRankedWins = PlayerPrefs.GetInt("cr_session_ranked_wins", 0); sessionRankedLosses = PlayerPrefs.GetInt("cr_session_ranked_losses", 0); sessionCasualWins = PlayerPrefs.GetInt("cr_session_casual_wins", 0); sessionCasualLosses = PlayerPrefs.GetInt("cr_session_casual_losses", 0); sessionRankedSeriesWins = PlayerPrefs.GetInt("cr_session_rseries_wins", 0); sessionRankedSeriesLosses = PlayerPrefs.GetInt("cr_session_rseries_losses", 0); sessionTeamSeriesWins = PlayerPrefs.GetInt("cr_session_tseries_wins", 0); sessionTeamSeriesLosses = PlayerPrefs.GetInt("cr_session_tseries_losses", 0); sessionWLByOpponent.Clear(); string[] array = (PlayerPrefs.GetString("cr_session_wl_by_opp", "") ?? "").Split('|'); foreach (string text2 in array) { if (string.IsNullOrEmpty(text2)) { continue; } int num = text2.IndexOf('='); if (num > 0) { string key = text2.Substring(0, num); string[] array2 = text2.Substring(num + 1).Split(','); if (array2.Length == 4 && int.TryParse(array2[0], out var result2) && int.TryParse(array2[1], out var result3) && int.TryParse(array2[2], out var result4) && int.TryParse(array2[3], out var result5)) { sessionWLByOpponent[key] = new int[4] { result2, result3, result4, result5 }; } } } sessionTimeByOpponent.Clear(); array = (PlayerPrefs.GetString("cr_session_time_by_opp", "") ?? "").Split('|'); foreach (string text3 in array) { if (string.IsNullOrEmpty(text3)) { continue; } int num2 = text3.IndexOf('='); if (num2 > 0) { string key2 = text3.Substring(0, num2); if (float.TryParse(text3.Substring(num2 + 1), NumberStyles.Float, CultureInfo.InvariantCulture, out var result6)) { sessionTimeByOpponent[key2] = result6; } } } Plugin.Log.LogInfo((object)($"[SESSION] restored prior session ({totalHours:F1}h since last activity): " + $"{sessionMatchCount} games, {sessionRankedWins}-{sessionRankedLosses}R / {sessionCasualWins}-{sessionCasualLosses}C, " + $"{sessionWLByOpponent.Count} opponents")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SESSION] load failed: " + ex.Message + " - starting fresh")); sessionStartTime = DateTime.UtcNow; } } public static void Initialize() { LoadSessionStateOrReset(); IdentifyLocalPlayer(); RegisterLogListener(); Plugin.Log.LogInfo((object)"GameStateWatcher initialized"); } public static void Poll() { pollTimer += Time.deltaTime; if (!(pollTimer < 0.1f)) { pollTimer = 0f; PollRoomState(); PollMatchState(); } } public static void TickFrame() { if (!isTracking) { return; } float unscaledDeltaTime = Time.unscaledDeltaTime; if (!(unscaledDeltaTime <= 0f) && !(unscaledDeltaTime > 1f)) { fpsFrameCount++; fpsTimeAccum += unscaledDeltaTime; fpsBroadcastTimer += unscaledDeltaTime; if (fpsBroadcastTimer >= 3f) { fpsBroadcastTimer = 0f; BroadcastFps(); PollOpponentFps(); } } } private static void BroadcastFps() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null) { int localAvgFps = LocalAvgFps; if (localAvgFps > 0) { Hashtable val = new Hashtable(); val[(object)"cr_fps"] = localAvgFps; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } catch { } } private static void PollOpponentFps() { try { if (!PhotonNetwork.InRoom) { return; } Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null) { return; } Player[] array = playerList; foreach (Player val in array) { if (val != null && !val.IsLocal && val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_fps")) { try { opponentAvgFps = Convert.ToInt32(val.CustomProperties[(object)"cr_fps"]); break; } catch { break; } } } } catch { } } public static void DismissMatchFoundStuckOverlay() { _stuckOverlayDismissedAt = DateTime.UtcNow; ShouldShowMatchFoundStuckOverlay = false; } private static void PollRoomState() { //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) bool inRoom = PhotonNetwork.InRoom; if (inRoom && !_runInBackgroundOverridden) { try { _origRunInBackground = Application.runInBackground; Application.runInBackground = true; _runInBackgroundOverridden = true; Plugin.Log.LogInfo((object)$"[FOCUS] In Photon room — Application.runInBackground forced true (was {_origRunInBackground})"); } catch { } } else if (!inRoom && _runInBackgroundOverridden) { try { Application.runInBackground = _origRunInBackground; _runInBackgroundOverridden = false; Plugin.Log.LogInfo((object)$"[FOCUS] Left Photon room — runInBackground restored to {_origRunInBackground}"); } catch { } } if (inRoom && !isTracking && !inPickPhase) { int num = (SecondsInUnstartedRoom = (int)(DateTime.UtcNow - roomJoinTime).TotalSeconds); bool flag = false; bool flag2 = false; try { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = ((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null); Room currentRoom2 = PhotonNetwork.CurrentRoom; string text = ((currentRoom2 != null) ? currentRoom2.Name : null) ?? ""; flag = (val != null && ((Dictionary)(object)val).ContainsKey((object)"cr_ff")) || text.StartsWith("ranked_") || text.StartsWith("team_") || text.StartsWith("sct-"); PlayerManager instance = PlayerManager.instance; flag2 = (Object)(object)instance != (Object)null && instance.players != null && instance.players.Count >= 1; } catch { } bool flag3 = false; try { flag3 = PhotonNetwork.OfflineMode; } catch { } bool flag4 = (DateTime.UtcNow - _stuckOverlayDismissedAt).TotalSeconds > 60.0; ShouldShowMatchFoundStuckOverlay = !flag && !flag3 && !flag2 && num >= 25 && flag4; } else { SecondsInUnstartedRoom = 0; ShouldShowMatchFoundStuckOverlay = false; } if (inRoom && !wasInRoom) { Room currentRoom3 = PhotonNetwork.CurrentRoom; photonRoomId = ((currentRoom3 != null) ? currentRoom3.Name : null) ?? ""; photonRegion = PhotonNetwork.CloudRegion ?? ""; roomJoinTime = DateTime.UtcNow; IdentifyLocalPlayer(); playersIdentified = false; opponentSteamIdResolved = false; opponentRankChecked = false; opponentIsRanked = false; matchIsRanked = false; try { Room currentRoom4 = PhotonNetwork.CurrentRoom; Hashtable val2 = ((currentRoom4 != null) ? ((RoomInfo)currentRoom4).CustomProperties : null); Room currentRoom5 = PhotonNetwork.CurrentRoom; string text2 = ((currentRoom5 != null) ? currentRoom5.Name : null) ?? ""; if ((val2 != null && ((Dictionary)(object)val2).ContainsKey((object)"cr_ff")) || text2.StartsWith("ranked_") || text2.StartsWith("team_") || text2.StartsWith("sct-")) { matchIsRanked = true; opponentIsRanked = true; Plugin.Log.LogInfo((object)("[POLL] mod-issued competitive room detected (" + text2 + ") — matchIsRanked forced true")); } } catch { } seriesPreflightSent = false; lastOpponentRankCheck = -999f; currentSeriesGamesWon = 0; currentSeriesGamesLost = 0; Plugin.Log.LogInfo((object)("[POLL] Joined room: " + photonRoomId + " (region: " + photonRegion + ")")); try { NametagStyler.PublishToPhoton(); } catch { } try { PlayerColorCosmetic.PublishLocalProps(); } catch { } try { TrailCosmetic.PublishLocalProps(); } catch { } try { PlayerEffectCosmetic.PublishLocalProps(); } catch { } } if (!inRoom && wasInRoom) { AccumulateSessionTime(); if (isTracking && !gameOverReported) { int num3 = ((localTeamId == 0) ? p1Rounds : p2Rounds); int num4 = ((localTeamId == 0) ? p2Rounds : p1Rounds); string arg = (matchIsRanked ? "RANKED" : "CASUAL"); if (LeavingForRanked) { Plugin.Log.LogInfo((object)$"[POLL] === {arg} Canceled === Left for ranked queue at {num3}-{num4} (not counted)"); CompetitiveUI.ShowNotification("Left match for ranked queue", new Color(0.4f, 0.8f, 1f)); LeavingForRanked = false; } else if (num3 >= 4 && num4 >= 4) { Plugin.Log.LogInfo((object)$"[POLL] === {arg} DC Win (4-4 tiebreak) === Opponent DC'd at {num3}-{num4}"); OnGameOver(localTeamId); } else if (num3 >= 4) { Plugin.Log.LogInfo((object)$"[POLL] === {arg} DC Win === Opponent disconnected at {num3}-{num4}"); OnGameOver(localTeamId); } else { if (num4 >= 4) { Plugin.Log.LogInfo((object)$"[POLL] === {arg} Canceled === Opp DC'd while ahead at {num3}-{num4} (no win awarded)"); } else { Plugin.Log.LogInfo((object)$"[POLL] === {arg} Canceled === Disconnect at {num3}-{num4} (not counted)"); } CompetitiveUI.ShowNotification("Match canceled (DC)", new Color(1f, 0.7f, 0.3f)); } } Plugin.Log.LogInfo((object)"[POLL] Left room"); PerfGate.DumpAndReset(); ResetMatchState(); } if (inRoom && !opponentSteamIdResolved) { TryResolveOpponent(); } if (inRoom && !seriesPreflightSent && opponentSteamIdResolved && !string.IsNullOrEmpty(opponentSteamId) && !opponentSteamId.StartsWith("photon_") && OpponentHasMod()) { ConfigEntry rankedEnabled = Plugin.RankedEnabled; if (rankedEnabled != null && rankedEnabled.Value && string.IsNullOrEmpty(ApiClient.ActiveRankedSeriesId) && !string.IsNullOrEmpty(localSteamId)) { bool flag5 = false; try { Room currentRoom6 = PhotonNetwork.CurrentRoom; flag5 = ((Dictionary)(object)((currentRoom6 != null) ? ((RoomInfo)currentRoom6).CustomProperties : null))?.ContainsKey((object)"cr_ff") ?? false; } catch { } string text3 = ""; try { Room currentRoom7 = PhotonNetwork.CurrentRoom; text3 = ((currentRoom7 != null) ? currentRoom7.Name : null) ?? ""; } catch { } bool flag6 = text3.StartsWith("ranked_") || text3.StartsWith("team_") || text3.StartsWith("sct-"); if (!flag5 && !flag6) { seriesPreflightSent = true; Plugin.Log.LogInfo((object)("[POLL] Eager preflight: opponent " + opponentSteamId + " has mod props — firing /series/preflight before /mod/check completes")); ApiClient.SendSeriesPreflight(localSteamId, opponentSteamId); } } } if (inRoom && opponentSteamIdResolved && !opponentSteamId.StartsWith("photon_")) { bool firstCheck = !opponentRankChecked; bool shouldRetry = !firstCheck && !opponentIsRanked && OpponentHasMod() && Time.realtimeSinceStartup - lastOpponentRankCheck >= 5f; if (firstCheck || shouldRetry) { opponentRankChecked = true; lastOpponentRankCheck = Time.realtimeSinceStartup; ApiClient.CheckOpponentRanked(opponentSteamId, delegate(bool isRanked) { bool flag8 = opponentIsRanked; opponentIsRanked = isRanked; bool flag9 = false; try { Room currentRoom8 = PhotonNetwork.CurrentRoom; flag9 = ((Dictionary)(object)((currentRoom8 != null) ? ((RoomInfo)currentRoom8).CustomProperties : null))?.ContainsKey((object)"cr_ff") ?? false; } catch { } if (flag9) { matchIsRanked = true; } else { matchIsRanked = Plugin.RankedEnabled.Value && opponentIsRanked && OpponentHasMod(); } if (flag8 != opponentIsRanked || firstCheck) { Plugin.Log.LogInfo((object)string.Format("[POLL] Opponent ranked: {0}, hasMod: {1}, Match ranked: {2}{3}", opponentIsRanked, OpponentHasMod(), matchIsRanked, shouldRetry ? " (retry)" : "")); } if (matchIsRanked && !flag9 && !seriesPreflightSent && string.IsNullOrEmpty(ApiClient.ActiveRankedSeriesId) && !string.IsNullOrEmpty(localSteamId) && !string.IsNullOrEmpty(opponentSteamId) && !opponentSteamId.StartsWith("photon_")) { seriesPreflightSent = true; ApiClient.SendSeriesPreflight(localSteamId, opponentSteamId); } }); } } if (inRoom && isTracking && !gameOverReported) { try { Player[] playerList = PhotonNetwork.PlayerList; int num5 = ((playerList != null) ? playerList.Length : 0); if (num5 >= 2) { opponentWasPresent = true; } if (opponentWasPresent && num5 <= 1 && !opponentDCReported) { opponentDCReported = true; int num6 = ((localTeamId == 0) ? p1Rounds : p2Rounds); int num7 = ((localTeamId == 0) ? p2Rounds : p1Rounds); int num8 = p1Points + p2Points; int num9 = p1Rounds + p2Rounds; bool flag7 = num8 >= 2 || num9 >= 1; if (matchIsRanked && flag7 && num6 < 4 && num7 < 4 && opponentSteamIdResolved && !opponentSteamId.StartsWith("photon_")) { Plugin.Log.LogInfo((object)$"[DC] Opponent {opponentDisplayName} disconnected at game-rounds={num6}-{num7}, pts={num8}, series-games={num9} — reporting leave"); ApiClient.ReportDisconnect(localSteamId, opponentSteamId); } else { Plugin.Log.LogInfo((object)$"[DC] Opponent left (ranked={matchIsRanked}, pts={num8}, series-games={num9}, rounds={num6}-{num7}) — not eligible for leave tracking"); } } } catch { } } wasInRoom = inRoom; } private static void AccumulateSessionTime() { if (!string.IsNullOrEmpty(opponentDisplayName) && opponentDisplayName != "Opponent") { float num = (float)(DateTime.UtcNow - roomJoinTime).TotalMinutes; if (sessionTimeByOpponent.ContainsKey(opponentDisplayName)) { sessionTimeByOpponent[opponentDisplayName] += num; } else { sessionTimeByOpponent[opponentDisplayName] = num; } roomJoinTime = DateTime.UtcNow; } } private static void TryResolveOpponent() { try { Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null) { return; } Player[] array = playerList; foreach (Player val in array) { if (val == null || val.IsLocal) { continue; } opponentDisplayName = StripRichText(val.NickName ?? "Opponent"); Hashtable customProperties = val.CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).Count > 0) { if (((Dictionary)(object)customProperties).ContainsKey((object)"u_id")) { opponentSteamId = customProperties[(object)"u_id"].ToString(); opponentSteamIdResolved = true; Plugin.Log.LogInfo((object)("[POLL] Opponent: " + opponentDisplayName + " (Steam: " + opponentSteamId + ")")); break; } if (((Dictionary)(object)customProperties).ContainsKey((object)"unity_id")) { opponentSteamId = customProperties[(object)"unity_id"].ToString(); opponentSteamIdResolved = true; Plugin.Log.LogInfo((object)("[POLL] Opponent: " + opponentDisplayName + " (Steam: " + opponentSteamId + ")")); break; } } if (!playersIdentified) { playersIdentified = true; opponentSteamId = $"photon_{val.ActorNumber}"; Plugin.Log.LogInfo((object)("[POLL] Opponent found: " + opponentDisplayName + " (waiting for Steam ID...)")); } break; } } catch { } } private static void IdentifyLocalPlayer() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) try { CSteamID steamID = SteamUser.GetSteamID(); if (steamID.m_SteamID != 0L) { localSteamId = steamID.m_SteamID.ToString(); localDisplayName = StripRichText(SteamFriends.GetPersonaName()); MaybeSyncRankedStateOnce(); return; } } catch { } try { Player localPlayer = PhotonNetwork.LocalPlayer; localSteamId = ((localPlayer != null) ? localPlayer.UserId : null) ?? "unknown"; Player localPlayer2 = PhotonNetwork.LocalPlayer; localDisplayName = StripRichText(((localPlayer2 != null) ? localPlayer2.NickName : null) ?? "Unknown"); MaybeSyncRankedStateOnce(); } catch { localSteamId = "unknown"; localDisplayName = "Unknown"; } } private static void MaybeSyncRankedStateOnce() { if (_rankedSyncSent || string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { return; } try { bool flag = Plugin.RankedEnabled != null && Plugin.RankedEnabled.Value; ApiClient.ToggleRanked(localSteamId, flag); _rankedSyncSent = true; Plugin.Log.LogInfo((object)$"[POLL] Initial ranked state synced to server: enabled={flag}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POLL] Initial ranked sync failed: " + ex.Message)); } } private static void DetermineLocalTeam() { try { Player localPlayer = PhotonNetwork.LocalPlayer; Hashtable val = ((localPlayer != null) ? localPlayer.CustomProperties : null); if (val != null && ((Dictionary)(object)val).ContainsKey((object)"t_id")) { localTeamId = Convert.ToInt32(val[(object)"t_id"]); Plugin.Log.LogInfo((object)$"[POLL] Local team: {localTeamId} (from Photon t_id)"); CardChoiceEndPickPatch.FlushPendingPicks(localTeamId); return; } } catch { } try { PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { return; } foreach (Player player in instance.players) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component != (Object)null) || !component.IsMine) { continue; } CharacterData component2 = ((Component)player).GetComponent(); if ((Object)(object)component2 != (Object)null) { FieldInfo field = typeof(CharacterData).GetField("teamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { localTeamId = (int)field.GetValue(component2); Plugin.Log.LogInfo((object)$"[POLL] Local team: {localTeamId} (from CharacterData)"); CardChoiceEndPickPatch.FlushPendingPicks(localTeamId); break; } } for (int i = 0; i < instance.players.Count; i++) { Player obj2 = instance.players[i]; PhotonView val2 = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); if ((Object)(object)val2 != (Object)null && val2.IsMine) { localTeamId = i; Plugin.Log.LogInfo((object)$"[POLL] Local team: {localTeamId} (from index)"); CardChoiceEndPickPatch.FlushPendingPicks(localTeamId); return; } } } } catch (Exception ex) { Plugin.Log.LogError((object)("[POLL] Team detection error: " + ex.Message)); } } private static void PollMatchState() { if (!PhotonNetwork.InRoom) { return; } GM_ArmsRace instance = GM_ArmsRace.instance; if ((Object)(object)instance == (Object)null) { return; } if (!fieldsResolved) { ResolveFields(instance); if (!fieldsResolved) { return; } } if (!pcolorRoomApplied) { try { PlayerManager instance2 = PlayerManager.instance; if ((((Object)(object)instance2 != (Object)null && instance2.players != null) ? instance2.players.Count : 0) >= 2) { pcolorRoomApplied = true; PlayerColorCosmetic.OnMatchStart(); try { TrailCosmetic.OnMatchStart(); } catch { } try { PlayerEffectCosmetic.OnMatchStart(); } catch { } } } catch { } } int fieldInt = GetFieldInt(instance, f_p1Points); int fieldInt2 = GetFieldInt(instance, f_p2Points); int fieldInt3 = GetFieldInt(instance, f_p1Rounds); int fieldInt4 = GetFieldInt(instance, f_p2Rounds); bool flag = fieldInt3 > 0 || fieldInt4 > 0 || fieldInt > 0 || fieldInt2 > 0; if (flag && !wasGameInProgress && !isTracking) { OnMatchStarted(); } if (isTracking) { if (fieldInt != lastP1Points || fieldInt2 != lastP2Points) { p1Points = fieldInt; p2Points = fieldInt2; if (matchIsRanked && fieldInt3 == 0 && fieldInt4 == 0 && !string.IsNullOrEmpty(ApiClient.ActiveRankedSeriesId) && !string.IsNullOrEmpty(LocalSteamId)) { ApiClient.PostLivePoints(ApiClient.ActiveRankedSeriesId, LocalSteamId, fieldInt, fieldInt2); } } if (fieldInt3 != lastP1Rounds || fieldInt4 != lastP2Rounds) { p1Rounds = fieldInt3; p2Rounds = fieldInt4; currentRound = p1Rounds + p2Rounds + 1; if (fieldInt3 > lastP1Rounds) { Plugin.Log.LogInfo((object)$"[POLL] Round: P1! Rounds: {p1Rounds}-{p2Rounds}"); } if (fieldInt4 > lastP2Rounds) { Plugin.Log.LogInfo((object)$"[POLL] Round: P2! Rounds: {p1Rounds}-{p2Rounds}"); } try { PlayerColorCosmetic.OnRoundStart(); } catch { } try { PlayerEffectCosmetic.OnRoundStart(); } catch { } int num = ((localTeamId == 0) ? p1Rounds : p2Rounds); int num2 = ((localTeamId == 0) ? p2Rounds : p1Rounds); if (num2 > achMaxOpponentRounds) { achMaxOpponentRounds = num2; } if (num == 0 && num2 >= 4) { achWasDown04 = true; } if (!gameOverReported && (fieldInt3 >= roundsToWin || fieldInt4 >= roundsToWin)) { OnGameOver((fieldInt3 <= fieldInt4) ? 1 : 0); } } PollCardPicks(); PollAchievementState(); } lastP1Points = fieldInt; lastP2Points = fieldInt2; lastP1Rounds = fieldInt3; lastP2Rounds = fieldInt4; wasGameInProgress = flag; } private static void OnMatchStarted() { //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Expected O, but got Unknown isTracking = true; gameOverReported = false; matchStartTime = DateTime.UtcNow; try { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = ((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null); Room currentRoom2 = PhotonNetwork.CurrentRoom; string text = ((currentRoom2 != null) ? currentRoom2.Name : null) ?? ""; if ((val != null && ((Dictionary)(object)val).ContainsKey((object)"cr_ff")) || text.StartsWith("ranked_") || text.StartsWith("team_") || text.StartsWith("sct-")) { matchIsRanked = true; } else if (opponentRankChecked && opponentIsRanked && OpponentHasMod() && Plugin.RankedEnabled != null && Plugin.RankedEnabled.Value) { matchIsRanked = true; } } catch { } TrailCosmetic.OnMatchStart(); PlayerColorCosmetic.OnMatchStart(); try { PlayerEffectCosmetic.OnMatchStart(); } catch { } achTookDamage = false; achPhoenixUsed = false; achDied = false; achMaxOpponentRounds = 0; achWasDown04 = false; lastDeadState = false; lastRemainingRespawns = -1; achFiredShot = false; achMoved = false; inPickPhase = false; pendingRegicideCheck = false; LocalShotsThisMatch = 0; LocalBlocksThisMatch = 0; LocalBulletsFiredThisMatch = 0; LocalBulletsHitThisMatch = 0; LocalBlocksActivatedThisMatch = 0; LocalBlocksSuccessfulThisMatch = 0; LocalBlockRawAbsorbs = 0; LocalBlockDedupeDrops = 0; LastBlockActivatedTime = -999f; LastBlockSuccessfulTime = -999f; LastBlockAbsorbTime = -999f; LastLocalHitTime = -999f; LastBlockMissTime = -999f; LastBlockEventLabel = ""; fpsFrameCount = 0; fpsTimeAccum = 0f; fpsBroadcastTimer = 0f; opponentAvgFps = 0; _hitsRemaining = 0; _lastBlockSuccessTime = -999f; _loggedFirstFire = (_loggedFirstHit = (_loggedFirstBlockAct = (_loggedFirstBlockOk = false))); if (CardRarityLookup.Count == 0) { try { CardRarityLookup.ScanAll(); } catch { } } p1Points = 0; p2Points = 0; p1Rounds = 0; p2Rounds = 0; currentRound = 1; localCards.Clear(); opponentCards.Clear(); localOffers.Clear(); lastKnownP1CardCount = 0; lastKnownP2CardCount = 0; pickCountThisMatch = 0; broadcastCardNames.Clear(); try { if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null) { Hashtable val2 = new Hashtable(); val2[(object)"cr_cards"] = ""; val2[(object)"cr_fps"] = 0; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } catch { } if (preMatchCards.Count > 0) { Plugin.Log.LogInfo((object)$"[POLL] Recovering {preMatchCards.Count} pre-match card(s)"); foreach (MatchTracker.CardPickData preMatchCard in preMatchCards) { pickCountThisMatch++; preMatchCard.PickOrder = pickCountThisMatch; preMatchCard.RoundNumber = 1; localCards.Add(preMatchCard); broadcastCardNames.Add(preMatchCard.CardName); localOffers.Add(new MatchTracker.CardOfferData { CardName = preMatchCard.CardName, RoundNumber = 1, WasPicked = true }); Plugin.Log.LogInfo((object)$"[POLL] Card: Pre-match picked {preMatchCard.CardName} [#{pickCountThisMatch}] (+synth offer)"); } try { if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null) { string text2 = string.Join("|", broadcastCardNames.ToArray()); Hashtable val3 = new Hashtable(); val3[(object)"cr_cards"] = text2; PhotonNetwork.LocalPlayer.SetCustomProperties(val3, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)("[POLL] Broadcast recovered cards: " + text2)); } } catch { } } preMatchCards.Clear(); preMatchPickCount = 0; if (preMatchOpponentCards.Count > 0) { Plugin.Log.LogInfo((object)$"[HARMONY-CARD] Recovering {preMatchOpponentCards.Count} pre-match opponent card(s)"); foreach (MatchTracker.CardPickData preMatchOpponentCard in preMatchOpponentCards) { preMatchOpponentCard.RoundNumber = 1; preMatchOpponentCard.PickOrder = opponentCards.Count + 1; opponentCards.Add(preMatchOpponentCard); opponentCardsViaHarmony = true; Plugin.Log.LogInfo((object)$"[HARMONY-CARD] Opp pre-match recovered: {preMatchOpponentCard.CardName} [#{preMatchOpponentCard.PickOrder}]"); } } preMatchOpponentCards.Clear(); lastKnownOpponentBroadcastCount = 0; try { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val4 in playerList) { if (val4 != null && !val4.IsLocal && val4.CustomProperties != null && ((Dictionary)(object)val4.CustomProperties).ContainsKey((object)"cr_cards")) { string text3 = val4.CustomProperties[(object)"cr_cards"].ToString(); if (!string.IsNullOrEmpty(text3)) { lastKnownOpponentBroadcastCount = text3.Split('|').Length; Plugin.Log.LogInfo((object)$"[POLL] Ignoring {lastKnownOpponentBroadcastCount} stale opponent cards from previous match"); } break; } } } catch { } IdentifyLocalPlayer(); TryResolveOpponent(); DetermineLocalTeam(); matchIsRanked = Plugin.RankedEnabled.Value && opponentIsRanked && OpponentHasMod(); string text4 = (matchIsRanked ? "RANKED" : "CASUAL"); Plugin.Log.LogInfo((object)("[POLL] === " + text4 + " Match Started ===")); Plugin.Log.LogInfo((object)$"[POLL] Me: {localDisplayName} ({localSteamId}) team {localTeamId}"); Plugin.Log.LogInfo((object)$"[POLL] Opp: {opponentDisplayName} ({opponentSteamId}) oppRanked={opponentIsRanked}"); } private static void OnGameOver(int winnerTeam) { if (!isTracking || gameOverReported) { return; } gameOverReported = true; sessionMatchCount++; if (!opponentSteamIdResolved) { TryResolveOpponent(); } bool flag = winnerTeam == localTeamId; string arg = (matchIsRanked ? "RANKED" : "CASUAL"); Plugin.Log.LogInfo((object)$"[POLL] === {arg} Match Over === Winner: team {winnerTeam}"); Plugin.Log.LogInfo((object)(flag ? ("[POLL] YOU WON vs " + opponentDisplayName + "!") : ("[POLL] You lost to " + opponentDisplayName))); Plugin.Log.LogInfo((object)$"[POLL] Final: P1 {p1Rounds}r - P2 {p2Rounds}r"); List list = new List(); bool flag2 = false; try { Room currentRoom = PhotonNetwork.CurrentRoom; flag2 = ((Dictionary)(object)((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null))?.ContainsKey((object)"cr_ff") ?? false; } catch { } if (flag2 && PhotonNetwork.PlayerList != null && PhotonNetwork.PlayerList.Length >= 4) { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (val != null && (PhotonNetwork.LocalPlayer == null || val.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)) { string nickName = val.NickName; if (!string.IsNullOrEmpty(nickName)) { list.Add(nickName); } } } } if (list.Count == 0) { list.Add(opponentDisplayName ?? "Unknown"); } foreach (string item in list) { if (!sessionWLByOpponent.ContainsKey(item)) { sessionWLByOpponent[item] = new int[4]; } if (matchIsRanked) { if (flag) { sessionWLByOpponent[item][0]++; } else { sessionWLByOpponent[item][1]++; } } else if (flag) { sessionWLByOpponent[item][2]++; } else { sessionWLByOpponent[item][3]++; } } if (matchIsRanked) { if (flag) { sessionRankedWins++; } else { sessionRankedLosses++; } if (currentSeriesGamesWon >= 2 || currentSeriesGamesLost >= 2) { currentSeriesGamesWon = 0; currentSeriesGamesLost = 0; } if (flag) { currentSeriesGamesWon++; } else { currentSeriesGamesLost++; } } else if (flag) { sessionCasualWins++; } else { sessionCasualLosses++; } AccumulateSessionTime(); SaveSessionState(); LastResult = new MatchTracker.MatchResult { Won = flag, MyRounds = ((localTeamId == 0) ? p1Rounds : p2Rounds), TheirRounds = ((localTeamId == 0) ? p2Rounds : p1Rounds), OpponentName = opponentDisplayName, Timestamp = DateTime.UtcNow }; HasPendingResult = true; string p1SteamId; string p1Name; string p2SteamId; string p2Name; if (localTeamId == 0) { p1SteamId = localSteamId; p1Name = localDisplayName; p2SteamId = opponentSteamId; p2Name = opponentDisplayName; } else { p1SteamId = opponentSteamId; p1Name = opponentDisplayName; p2SteamId = localSteamId; p2Name = localDisplayName; } int num = (int)(DateTime.UtcNow - matchStartTime).TotalSeconds; bool flag3 = true; if (opponentSteamIdResolved && !opponentSteamId.StartsWith("photon_")) { bool flag4 = false; try { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && !val2.IsLocal && val2.CustomProperties != null && ((Dictionary)(object)val2.CustomProperties).ContainsKey((object)"cr_cards")) { flag4 = true; break; } } } catch { } if (flag4) { long result = 0L; long result2 = 0L; long.TryParse(localSteamId, out result); long.TryParse(opponentSteamId, out result2); flag3 = result <= result2; if (!flag3) { Plugin.Log.LogInfo((object)"[POLL] Opponent will report this match (lower Steam ID)"); } } } string reportRoomId = $"{photonRoomId}_{matchStartTime:HHmmss}_r{p1Rounds + p2Rounds}"; bool flag5 = false; try { if (PhotonNetwork.OfflineMode) { flag5 = true; } if (!string.IsNullOrEmpty(photonRoomId) && photonRoomId.IndexOf("offline", StringComparison.OrdinalIgnoreCase) >= 0) { flag5 = true; } } catch { } if (flag5) { Plugin.Log.LogInfo((object)("[POLL] Skipping match report — offline/practice detected (room='" + photonRoomId + "')")); flag3 = false; } try { Player[] playerList2 = PhotonNetwork.PlayerList; int num2 = ((playerList2 != null) ? playerList2.Length : (-1)); bool flag6 = !string.IsNullOrEmpty(ApiClient.ActiveTeamSeriesId); bool flag7 = false; try { Room currentRoom2 = PhotonNetwork.CurrentRoom; flag7 = ((Dictionary)(object)((currentRoom2 != null) ? ((RoomInfo)currentRoom2).CustomProperties : null))?.ContainsKey((object)"cr_ff") ?? false; } catch { } Plugin.Log.LogInfo((object)string.Format("[2v2-REPORT-ROUTE] shouldReport={0} ActiveTeamSeriesId={1} PlayerList.Length={2} cr_ff={3}", flag3, flag6 ? ApiClient.ActiveTeamSeriesId : "(null)", num2, flag7)); if (flag3 && flag6 && PhotonNetwork.PlayerList != null && PhotonNetwork.PlayerList.Length == 4 && TryReportTeamMatch(reportRoomId, num)) { EvaluateAchievements(flag); isTracking = false; matchIsRanked = false; return; } if (flag7 || flag6) { Plugin.Log.LogWarning((object)$"[2v2-REPORT-ROUTE] BLOCKING 1v1 fallback in 2v2 context: shouldReport={flag3} hasSeries={flag6} playerListLen={num2} cr_ff={flag7} — match will not be reported"); EvaluateAchievements(flag); isTracking = false; matchIsRanked = false; return; } } catch (Exception ex) { Plugin.Log.LogError((object)("[POLL] 2v2 routing error: " + ex.Message)); } if (flag3) { try { Room currentRoom3 = PhotonNetwork.CurrentRoom; string text = ((currentRoom3 != null) ? currentRoom3.Name : null) ?? "(no room)"; bool flag8 = text.StartsWith("sct-"); bool flag9 = text.StartsWith("ranked_"); Plugin.Log.LogInfo((object)$"[REPORT-ROUTE] 1v1 path: room={text} isRanked={matchIsRanked} tournament={flag8} ranked_queue={flag9} reporter={localSteamId} opponent={opponentSteamId}"); } catch { } ApiClient.ReportMatch(p1SteamId, p1Name, p2SteamId, p2Name, p1Rounds, p2Rounds, p1Points, p2Points, (localTeamId == 0) ? localCards : opponentCards, (localTeamId == 0) ? opponentCards : localCards, (localTeamId == 0) ? localOffers : emptyOffers, (localTeamId == 0) ? emptyOffers : localOffers, reportRoomId, photonRegion, num, matchStartTime, localSteamId, matchIsRanked, LocalShotsThisMatch, LocalBlocksThisMatch, LocalBulletsFiredThisMatch, LocalBulletsHitThisMatch, LocalBlocksActivatedThisMatch, LocalBlocksSuccessfulThisMatch, LocalAvgFps, OpponentAvgFps); } EvaluateAchievements(flag); isTracking = false; matchIsRanked = false; } private static bool TryReportTeamMatch(string reportRoomId, int duration) { if (PhotonNetwork.PlayerList == null || PhotonNetwork.PlayerList.Length != 4) { ManualLogSource log = Plugin.Log; Player[] playerList = PhotonNetwork.PlayerList; log.LogWarning((object)$"[2v2-REPORT] aborting: PlayerList.Length={((playerList != null) ? playerList.Length : (-1))} (expected 4)"); return false; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { Plugin.Log.LogWarning((object)("[2v2-REPORT] aborting: PlayerManager.instance=" + (((Object)(object)instance == (Object)null) ? "null" : "set") + " pm.players=" + ((instance?.players == null) ? "null" : "set"))); return false; } Player[] playerList2 = PhotonNetwork.PlayerList; Dictionary, int)> dictionary = new Dictionary, int)>(); Player[] array = playerList2; foreach (Player val in array) { if (val == null) { continue; } string text = ResolvePhotonSteamId(val); if (string.IsNullOrEmpty(text) || text.StartsWith("photon_")) { Plugin.Log.LogWarning((object)$"[2v2-REPORT] couldn't resolve Steam ID for actor {val.ActorNumber}"); return false; } string text2 = StripRichText(val.NickName ?? text); if (string.IsNullOrEmpty(text2)) { text2 = text; } if (text2.Length > 60) { text2 = text2.Substring(0, 60); } int item = -1; foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Owner != null && component.Owner.ActorNumber == val.ActorNumber) { item = player.TeamID; break; } } } List list = new List(); if (val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_cards")) { string text3 = val.CustomProperties[(object)"cr_cards"]?.ToString() ?? ""; if (!string.IsNullOrEmpty(text3)) { int num = 1; string[] array2 = text3.Split('|'); for (int j = 0; j < array2.Length; j++) { string name = ToTitleCase(array2[j].Trim()); name = CardRarityLookup.GetCanonicalName(name); if (!string.IsNullOrEmpty(name)) { list.Add(new MatchTracker.CardPickData { CardName = name, CardRarity = CardRarityLookup.GetRarity(name), PickOrder = num++, RoundNumber = 1 }); } } } } int item2 = 0; if (val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_fps")) { try { item2 = Convert.ToInt32(val.CustomProperties[(object)"cr_fps"]); } catch { } } if (val.IsLocal) { if (localCards != null && localCards.Count > 0) { list = new List(localCards); } int localAvgFps = LocalAvgFps; if (localAvgFps > 0) { item2 = localAvgFps; } } dictionary[text] = (text2, item, list, item2); } if (dictionary.Count != 4) { Plugin.Log.LogWarning((object)$"[2v2-REPORT] resolved {dictionary.Count}/4 players, aborting"); return false; } string text4 = null; long num2 = long.MaxValue; foreach (string key in dictionary.Keys) { if (long.TryParse(key, out var result) && result < num2) { num2 = result; text4 = key; } } if (text4 == null) { text4 = localSteamId; } if (text4 != localSteamId) { Plugin.Log.LogInfo((object)("[2v2-REPORT] reporter is " + text4 + ", not me (" + localSteamId + ") — skipping")); return true; } List list2 = new List(); List list3 = new List(); foreach (KeyValuePair, int)> item3 in dictionary) { if (item3.Value.Item2 == 0) { list2.Add(item3.Key); } else if (item3.Value.Item2 == 1) { list3.Add(item3.Key); } } if (list2.Count != 2 || list3.Count != 2) { Plugin.Log.LogWarning((object)$"[2v2-REPORT] team split is {list2.Count}/{list3.Count}, aborting"); return false; } list2.Sort(StringComparer.Ordinal); list3.Sort(StringComparer.Ordinal); int num3 = p1Rounds; int num4 = p2Rounds; int t1Points = p1Points; int t2Points = p2Points; int num5 = ((num3 > num4) ? 1 : 2); string text5 = list2[0]; string text6 = list2[1]; string text7 = list3[0]; string text8 = list3[1]; ApiClient.ReportTeamMatch(ApiClient.ActiveTeamSeriesId, text5, dictionary[text5].Item1, dictionary[text5].Item3, text6, dictionary[text6].Item1, dictionary[text6].Item3, text7, dictionary[text7].Item1, dictionary[text7].Item3, text8, dictionary[text8].Item1, dictionary[text8].Item3, num3, num4, t1Points, t2Points, reportRoomId, photonRegion, duration, matchStartTime, localSteamId, matchIsRanked, num5, dictionary[text5].Item4, dictionary[text6].Item4, dictionary[text7].Item4, dictionary[text8].Item4); Plugin.Log.LogInfo((object)$"[2v2-REPORT] submitted: t1={text5},{text6} t2={text7},{text8} winner=T{num5}"); return true; } private static string ResolvePhotonSteamId(Player pp) { try { Hashtable customProperties = pp.CustomProperties; long result; if (customProperties != null) { if (((Dictionary)(object)customProperties).ContainsKey((object)"u_id")) { string text = customProperties[(object)"u_id"]?.ToString(); if (!string.IsNullOrEmpty(text) && long.TryParse(text, out result)) { return text; } } if (((Dictionary)(object)customProperties).ContainsKey((object)"unity_id")) { string text2 = customProperties[(object)"unity_id"]?.ToString(); if (!string.IsNullOrEmpty(text2) && long.TryParse(text2, out result)) { return text2; } } } if (!string.IsNullOrEmpty(pp.UserId) && long.TryParse(pp.UserId, out result)) { return pp.UserId; } } catch { } return $"photon_{pp.ActorNumber}"; } private static void PollAchievementState() { if (!isTracking) { LocalAliveInCombatNow = false; return; } bool flag = false; try { PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { return; } foreach (Player player in instance.players) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsMine) { continue; } CharacterData component2 = ((Component)player).GetComponent(); if ((Object)(object)component2 == (Object)null) { break; } if (!component2.dead && component2.health > 0f) { flag = true; } if (!component2.dead && component2.health > 0f && component2.health < component2.MaxHealth) { if (!achTookDamage) { Plugin.Log.LogInfo((object)"[ACH] Player took damage"); } achTookDamage = true; } if (component2.dead && !lastDeadState) { achDied = true; } lastDeadState = component2.dead; CharacterStatModifiers stats = component2.stats; if ((Object)(object)stats != (Object)null && stats.respawns > 0 && stats.remainingRespawns < stats.respawns) { if (!achPhoenixUsed) { Plugin.Log.LogInfo((object)"[ACH] Phoenix life consumed"); } achPhoenixUsed = true; } break; } } catch { } LocalAliveInCombatNow = flag && !inPickPhase; if (flag && !inPickPhase) { if (!achFiredShot && Input.GetMouseButton(0)) { achFiredShot = true; Plugin.Log.LogInfo((object)"[ACH] Player fired a shot"); } if (Input.GetMouseButtonDown(0)) { LocalShotsThisMatch++; } if (Input.GetMouseButtonDown(1)) { LocalBlocksThisMatch++; } bool flag2 = false; try { flag2 = CompetitiveUI.IsChatInputOpen || NativeUI.IsOpen; } catch { } if (!flag2 && !achMoved && (Input.GetKey((KeyCode)119) || Input.GetKey((KeyCode)97) || Input.GetKey((KeyCode)115) || Input.GetKey((KeyCode)100) || Input.GetKey((KeyCode)32) || Input.GetKey((KeyCode)273) || Input.GetKey((KeyCode)274) || Input.GetKey((KeyCode)276) || Input.GetKey((KeyCode)275))) { achMoved = true; Plugin.Log.LogInfo((object)"[ACH] Player moved"); } } } private static void EvaluateAchievements(bool localWon) { try { int num = ((localTeamId == 0) ? p1Rounds : p2Rounds); int num2 = ((localTeamId == 0) ? p2Rounds : p1Rounds); if (num < roundsToWin && num2 < roundsToWin) { Plugin.Log.LogInfo((object)$"[ACH] Skipping — incomplete game ({num}-{num2}, need {roundsToWin})"); return; } bool flag = localWon && num2 == 0; string steamId = localSteamId; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (MatchTracker.CardPickData localCard in localCards) { string text = localCard.CardName ?? ""; hashSet.Add(text); if (dictionary.ContainsKey(text)) { dictionary[text]++; } else { dictionary[text] = 1; } } foreach (MatchTracker.CardPickData preMatchCard in preMatchCards) { string text2 = preMatchCard.CardName ?? ""; hashSet.Add(text2); if (dictionary.ContainsKey(text2)) { dictionary[text2]++; } else { dictionary[text2] = 1; } } if (localWon && !achTookDamage) { Plugin.Log.LogInfo((object)"[ACH] Evaluating: Untouchable — PASSED"); ApiClient.UnlockAchievement(steamId, "untouchable"); } if (flag) { if (hashSet.Contains("Sneaky") || hashSet.Contains("Sneaky Bullets")) { ApiClient.UnlockAchievement(steamId, "silent_assassin"); } if (hashSet.Contains("Mayhem")) { ApiClient.UnlockAchievement(steamId, "total_mayhem"); } if (hashSet.Contains("Glass Cannon") || hashSet.Contains("Glasscannon")) { ApiClient.UnlockAchievement(steamId, "fragile_perfection"); } if (hashSet.Contains("Chase")) { ApiClient.UnlockAchievement(steamId, "no_escape"); } } bool flag2 = hashSet.Contains("Phoenix"); if (flag && flag2 && !achPhoenixUsed && !achDied) { Plugin.Log.LogInfo((object)"[ACH] Evaluating: Rise from the Ashes — PASSED"); ApiClient.UnlockAchievement(steamId, "rise_from_the_ashes"); } if (localWon && achWasDown04) { Plugin.Log.LogInfo((object)"[ACH] Evaluating: The Comeback Kid — PASSED"); ApiClient.UnlockAchievement(steamId, "the_comeback_kid"); } foreach (KeyValuePair item in dictionary) { if (item.Value >= 5) { Plugin.Log.LogInfo((object)$"[ACH] Evaluating: Stacked Deck — PASSED ({item.Key} x{item.Value})"); ApiClient.UnlockAchievement(steamId, "stacked_deck"); break; } } if (matchIsRanked && localWon && opponentSteamId == "76561198040410653") { pendingRegicideCheck = true; } if (localWon && !achFiredShot) { Plugin.Log.LogInfo((object)"[ACH] Evaluating: Pacifist — PASSED"); ApiClient.UnlockAchievement(steamId, "pacifist"); } if (localWon && !achMoved) { Plugin.Log.LogInfo((object)"[ACH] Evaluating: Immovable Object — PASSED"); ApiClient.UnlockAchievement(steamId, "immovable_object"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ACH] Achievement evaluation error: " + ex.Message)); } } public static void RegisterLogListener() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (!logListenerRegistered) { object obj = <>O.<0>__OnUnityLog; if (obj == null) { LogCallback val = OnUnityLog; <>O.<0>__OnUnityLog = val; obj = (object)val; } Application.logMessageReceived += (LogCallback)obj; logListenerRegistered = true; Plugin.Log.LogInfo((object)"[POLL] Unity log listener registered for card tracking"); } } public static void UnregisterLogListener() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if (logListenerRegistered) { object obj = <>O.<0>__OnUnityLog; if (obj == null) { LogCallback val = OnUnityLog; <>O.<0>__OnUnityLog = val; obj = (object)val; } Application.logMessageReceived -= (LogCallback)obj; logListenerRegistered = false; } } private static void OnUnityLog(string message, string stackTrace, LogType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)type != 3) { return; } if (message.StartsWith("PICK PHASE")) { if (!inPickPhase) { Plugin.Log.LogInfo((object)"[ACH] Pick phase entered — input gating disabled"); } inPickPhase = true; } else if (message.StartsWith("MOVE PLAYERS END")) { if (inPickPhase) { Plugin.Log.LogInfo((object)"[ACH] Combat begins — input gating enabled"); } inPickPhase = false; if (!isTracking) { try { OnMatchStarted(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ACH] early start hook: " + ex.Message)); } } try { if (NativeUI.IsOpen) { NativeUI.Close(); } } catch { } } else if (message.StartsWith("Round over") || message.StartsWith("Point over")) { inPickPhase = false; } if (!message.StartsWith("Picking Card: ")) { return; } string name = ToTitleCase(message.Substring("Picking Card: ".Length).Replace("(Clone)", "").Trim()); name = CardRarityLookup.GetCanonicalName(name); if (string.IsNullOrEmpty(name)) { return; } if (!isTracking) { preMatchPickCount++; preMatchCards.Add(new MatchTracker.CardPickData { CardName = name, CardRarity = CardRarityLookup.GetRarity(name), PickOrder = preMatchPickCount, RoundNumber = 1 }); Plugin.Log.LogInfo((object)$"[POLL] Card stored (pre-match): {name} [#{preMatchPickCount}]"); return; } pickCountThisMatch++; MatchTracker.CardPickData item = new MatchTracker.CardPickData { CardName = name, CardRarity = CardRarityLookup.GetRarity(name), PickOrder = pickCountThisMatch, RoundNumber = currentRound }; localCards.Add(item); _lastLocalPickedCardName = name; Plugin.Log.LogInfo((object)$"[POLL] Card: Local picked {name} [#{pickCountThisMatch}]"); bool flag = false; for (int i = 0; i < localOffers.Count; i++) { MatchTracker.CardOfferData cardOfferData = localOffers[i]; if (cardOfferData.WasPicked && cardOfferData.RoundNumber == currentRound && cardOfferData.CardName == name) { flag = true; break; } } if (!flag) { localOffers.Add(new MatchTracker.CardOfferData { CardName = name, RoundNumber = currentRound, WasPicked = true }); Plugin.Log.LogInfo((object)$"[POLL] Synthesized picked offer for {name} round={currentRound} (Harmony EndPick didn't fire)"); } BroadcastCardPick(name); } private static void BroadcastCardPick(string cardName) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown try { if (PhotonNetwork.InRoom) { broadcastCardNames.Add(cardName); string text = string.Join("|", broadcastCardNames.ToArray()); Hashtable val = new Hashtable(); val[(object)"cr_cards"] = text; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)("[POLL] Broadcast cards: " + text)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POLL] Card broadcast failed: " + ex.Message)); } } public static void OnOpponentCardPicked(string cardName, string rarity) { cardName = ToTitleCase(cardName); cardName = CardRarityLookup.GetCanonicalName(cardName); if (!isTracking) { preMatchOpponentCards.Add(new MatchTracker.CardPickData { CardName = cardName, CardRarity = rarity, PickOrder = preMatchOpponentCards.Count + 1, RoundNumber = 1 }); Plugin.Log.LogInfo((object)("[HARMONY-CARD] Opp card stored (pre-match): " + cardName)); } else { opponentCardsViaHarmony = true; MatchTracker.CardPickData cardPickData = new MatchTracker.CardPickData { CardName = cardName, CardRarity = rarity, PickOrder = opponentCards.Count + 1, RoundNumber = currentRound }; opponentCards.Add(cardPickData); Plugin.Log.LogInfo((object)$"[HARMONY-CARD] Opp card added: {cardName} [#{cardPickData.PickOrder}] (via Harmony)"); } } private static void PollCardPicks() { try { if (!PhotonNetwork.InRoom || opponentCardsViaHarmony) { return; } Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null) { return; } Player[] array = playerList; foreach (Player val in array) { if (val == null || val.IsLocal) { continue; } Hashtable customProperties = val.CustomProperties; if (customProperties == null || !((Dictionary)(object)customProperties).ContainsKey((object)"cr_cards")) { continue; } string text = customProperties[(object)"cr_cards"].ToString(); if (string.IsNullOrEmpty(text)) { continue; } string[] array2 = text.Split('|'); int num = array2.Length; if (num < lastKnownOpponentBroadcastCount) { Plugin.Log.LogInfo((object)$"[POLL] Opponent broadcast reset detected ({lastKnownOpponentBroadcastCount} -> {num}), re-syncing"); lastKnownOpponentBroadcastCount = 0; } if (num <= lastKnownOpponentBroadcastCount) { break; } for (int j = lastKnownOpponentBroadcastCount; j < num; j++) { string name = ToTitleCase(array2[j].Trim()); name = CardRarityLookup.GetCanonicalName(name); if (!string.IsNullOrEmpty(name)) { MatchTracker.CardPickData item = new MatchTracker.CardPickData { CardName = name, CardRarity = CardRarityLookup.GetRarity(name), PickOrder = j + 1, RoundNumber = currentRound }; opponentCards.Add(item); Plugin.Log.LogInfo((object)("[POLL] Card: Opp picked " + name + " [via mod sync]")); } } lastKnownOpponentBroadcastCount = num; break; } } catch { } } private static void ResolveFields(GM_ArmsRace gm) { try { Type type = ((object)gm).GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; f_p1Points = type.GetField("p1Points", bindingAttr); f_p2Points = type.GetField("p2Points", bindingAttr); f_p1Rounds = type.GetField("p1Rounds", bindingAttr); f_p2Rounds = type.GetField("p2Rounds", bindingAttr); f_roundsToWinGame = type.GetField("roundsToWinGame", bindingAttr); if (f_roundsToWinGame == null) { f_roundsToWinGame = type.GetField("roundsToWin", bindingAttr); } if (f_roundsToWinGame == null) { f_roundsToWinGame = type.GetField("m_roundsToWinGame", bindingAttr); } if (f_roundsToWinGame != null) { roundsToWin = GetFieldInt(gm, f_roundsToWinGame); if (roundsToWin <= 0) { roundsToWin = 5; } Plugin.Log.LogInfo((object)$"[POLL] Rounds to win: {roundsToWin}"); } else { roundsToWin = 5; Plugin.Log.LogInfo((object)$"[POLL] roundsToWinGame field not found, defaulting to {roundsToWin}"); } if (f_p1Points != null && f_p1Rounds != null) { fieldsResolved = true; Plugin.Log.LogInfo((object)"[POLL] GM_ArmsRace fields resolved"); } } catch (Exception ex) { Plugin.Log.LogError((object)("[POLL] Field resolution failed: " + ex.Message)); } } private static int GetFieldInt(object obj, FieldInfo field) { if (field == null || obj == null) { return 0; } try { return (int)field.GetValue(obj); } catch { return 0; } } public static bool OpponentHasMod() { try { if (!PhotonNetwork.InRoom) { return false; } Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null) { return false; } Player[] array = playerList; foreach (Player val in array) { if (val == null || val.IsLocal) { continue; } Hashtable customProperties = val.CustomProperties; if (customProperties == null) { continue; } foreach (object key in ((Dictionary)(object)customProperties).Keys) { if (key is string text && text.StartsWith("cr_", StringComparison.Ordinal)) { return true; } } } } catch { } return false; } private static string StripRichText(string input) { if (string.IsNullOrEmpty(input)) { return input; } return Regex.Replace(input, "<.*?>", "").Trim(); } private static string ToTitleCase(string input) { if (string.IsNullOrEmpty(input)) { return input; } string[] array = input.ToLower().Split(' '); for (int i = 0; i < array.Length; i++) { if (array[i].Length > 0) { array[i] = char.ToUpper(array[i][0]) + array[i].Substring(1); } } return string.Join(" ", array); } private static void ResetMatchStateWithTrail() { TrailCosmetic.OnMatchEnd(); PlayerColorCosmetic.OnMatchEnd(); try { PlayerEffectCosmetic.OnMatchEnd(); } catch { } ResetMatchState(); } private static void ResetMatchState() { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown isTracking = false; gameOverReported = false; wasGameInProgress = false; pcolorRoomApplied = false; p1Points = 0; p2Points = 0; p1Rounds = 0; p2Rounds = 0; lastP1Points = 0; lastP2Points = 0; lastP1Rounds = 0; lastP2Rounds = 0; currentRound = 1; localTeamId = -1; playersIdentified = false; opponentSteamIdResolved = false; opponentRankChecked = false; opponentIsRanked = false; matchIsRanked = false; localCards.Clear(); opponentCards.Clear(); localOffers.Clear(); lastKnownP1CardCount = 0; lastKnownP2CardCount = 0; pickCountThisMatch = 0; broadcastCardNames.Clear(); lastKnownOpponentBroadcastCount = 0; preMatchCards.Clear(); preMatchPickCount = 0; opponentCardsViaHarmony = false; preMatchOpponentCards.Clear(); fieldsResolved = false; opponentWasPresent = false; opponentDCReported = false; achTookDamage = false; achPhoenixUsed = false; achDied = false; achMaxOpponentRounds = 0; achWasDown04 = false; lastDeadState = false; lastRemainingRespawns = -1; achFiredShot = false; achMoved = false; inPickPhase = false; pendingRegicideCheck = false; LocalShotsThisMatch = 0; LocalBlocksThisMatch = 0; LocalBulletsFiredThisMatch = 0; LocalBulletsHitThisMatch = 0; LocalBlocksActivatedThisMatch = 0; LocalBlocksSuccessfulThisMatch = 0; LocalBlockRawAbsorbs = 0; LocalBlockDedupeDrops = 0; LastBlockActivatedTime = -999f; LastBlockSuccessfulTime = -999f; LastBlockAbsorbTime = -999f; LastLocalHitTime = -999f; LastBlockMissTime = -999f; LastBlockEventLabel = ""; fpsFrameCount = 0; fpsTimeAccum = 0f; fpsBroadcastTimer = 0f; opponentAvgFps = 0; _hitsRemaining = 0; _lastBlockSuccessTime = -999f; try { if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null) { Hashtable val = new Hashtable(); val[(object)"cr_cards"] = ""; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } catch { } } public static void OnLocalCardOffered(string cardName, bool wasPicked, int round) { if (!string.IsNullOrEmpty(cardName)) { localOffers.Add(new MatchTracker.CardOfferData { CardName = cardName, RoundNumber = round, WasPicked = wasPicked }); if (wasPicked) { _lastLocalPickedCardName = cardName; } } } public static bool LocalOffersPickedIn(int fromIndex) { if (fromIndex < 0) { fromIndex = 0; } for (int i = fromIndex; i < localOffers.Count; i++) { if (localOffers[i].WasPicked) { return true; } } return false; } } public static class MatchTracker { public class CardPickData { public string CardName; public string CardRarity; public int PickOrder; public int RoundNumber; } public class CardOfferData { public string CardName; public int RoundNumber; public bool WasPicked; } public class MatchResult { public bool Won; public int MyRounds; public int TheirRounds; public string OpponentName; public DateTime Timestamp; } public static bool IsInMatch => GameStateWatcher.IsInMatch; public static bool IsInRoom => GameStateWatcher.IsInRoom; public static string LocalSteamId => GameStateWatcher.LocalSteamId; public static string LocalDisplayName => GameStateWatcher.LocalDisplayName; public static string OpponentDisplayName => GameStateWatcher.OpponentDisplayName; public static MatchResult LastResult => GameStateWatcher.LastResult; public static bool HasPendingResult => GameStateWatcher.HasPendingResult; public static int P1Rounds => GameStateWatcher.P1Rounds; public static int P2Rounds => GameStateWatcher.P2Rounds; public static int P1Points => GameStateWatcher.P1Points; public static int P2Points => GameStateWatcher.P2Points; public static int LocalTeamId => GameStateWatcher.LocalTeamId; public static void Initialize() { } } internal class NametagFontRenderer : MonoBehaviour { private class LabelState { public object OriginalFont; public string LastAppliedSku; } private const float POLL_INTERVAL = 0.5f; private static readonly Dictionary _skuToTmpFontName = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "nametag_typeface_caveat", "caveat" }, { "nametag_typeface_permanentmarker", "permanentmarker" }, { "nametag_typeface_courierprime", "courierprime" }, { "nametag_typeface_pacifico", "pacifico" }, { "nametag_typeface_playfairdisplay", "playfairdisplay" }, { "nametag_typeface_specialelite", "specialelite" }, { "nametag_typeface_vt323", "vt323" }, { "nametag_typeface_medievalsharp", "medievalsharp" }, { "nametag_typeface_smokum", "smokum" }, { "nametag_typeface_rye", "rye" }, { "nametag_typeface_orbitron", "orbitron" }, { "nametag_typeface_greatvibes", "greatvibes" }, { "nametag_typeface_cinzeldecorative", "cinzeldecorative" }, { "nametag_typeface_pressstart2p", "pressstart2p" }, { "nametag_typeface_audiowide", "audiowide" }, { "nametag_typeface_monoton", "monoton" }, { "nametag_typeface_bungeeshade", "bungeeshade" }, { "nametag_typeface_metalmania", "metalmania" }, { "nametag_typeface_unifrakturmaguntia", "unifrakturmaguntia" }, { "nametag_typeface_creepster", "creepster" }, { "nametag_typeface_rubikpuddles", "rubikpuddles" }, { "nametag_typeface_rubikmarkerhatch", "rubikmarkerhatch" } }; private static Dictionary _bundledFontsByName; private static bool _bundleLoadAttempted; private static object _fontBundle; private static Type _tTmpText; private static Type _tTmpFontAsset; private static PropertyInfo _pText; private static PropertyInfo _pFont; private static MethodInfo _mCreateFontAsset; private static MethodInfo _mSetAllDirty; private static MethodInfo _mUpdateMaterial; private static MethodInfo _mForceMeshUpdate; private static bool _reflectionReady; private readonly Dictionary _states = new Dictionary(); private static readonly Dictionary _fontAssetCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly HashSet _fontBuildFailed = new HashSet(StringComparer.OrdinalIgnoreCase); private static bool _reflectionLoggedMissing; private static bool _loggedFirstApply; private static bool TryBindReflection() { if (_reflectionReady) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (_tTmpText == null) { _tTmpText = assembly.GetType("TMPro.TMP_Text"); } if (_tTmpFontAsset == null) { _tTmpFontAsset = assembly.GetType("TMPro.TMP_FontAsset"); } if (_tTmpText != null && _tTmpFontAsset != null) { break; } } if (_tTmpText == null || _tTmpFontAsset == null) { if (!_reflectionLoggedMissing) { _reflectionLoggedMissing = true; Plugin.Log.LogWarning((object)$"[TYPEFACE] TMP types not found (tmpText={_tTmpText != null}, tmpFontAsset={_tTmpFontAsset != null}) — custom fonts disabled."); } return false; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; _pText = _tTmpText.GetProperty("text", bindingAttr); _pFont = _tTmpText.GetProperty("font", bindingAttr); _mCreateFontAsset = _tTmpFontAsset.GetMethod("CreateFontAsset", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Font) }, null); if (_mCreateFontAsset == null) { MethodInfo[] methods = _tTmpFontAsset.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "CreateFontAsset")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(Font)) { _mCreateFontAsset = methodInfo; break; } } } } BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public; _mSetAllDirty = _tTmpText.GetMethod("SetAllDirty", bindingAttr2); _mUpdateMaterial = _tTmpText.GetMethod("UpdateMaterial", bindingAttr2); _mForceMeshUpdate = _tTmpText.GetMethod("ForceMeshUpdate", bindingAttr2, null, new Type[2] { typeof(bool), typeof(bool) }, null); _reflectionReady = _pText != null && _pFont != null && _mCreateFontAsset != null; if (!_reflectionReady && !_reflectionLoggedMissing) { _reflectionLoggedMissing = true; Plugin.Log.LogWarning((object)$"[TYPEFACE] reflection incomplete (pText={_pText != null}, pFont={_pFont != null}, mCreateFontAsset={_mCreateFontAsset != null}) — custom fonts disabled."); } else if (_reflectionReady) { Plugin.Log.LogInfo((object)"[TYPEFACE] reflection bound OK — custom fonts enabled."); } return _reflectionReady; } catch { return false; } } private void OnEnable() { ((MonoBehaviour)this).StartCoroutine(PollLoop()); } private void OnDisable() { ((MonoBehaviour)this).StopAllCoroutines(); RestoreAllLabels(); } private IEnumerator PollLoop() { WaitForSeconds wait = new WaitForSeconds(0.5f); while (true) { try { ScanAndApply(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TYPEFACE] scan error: " + ex.Message)); } yield return wait; } } private void ScanAndApply() { if (!TryBindReflection()) { return; } if (!PhotonNetwork.InRoom) { if (_states.Count > 0) { RestoreAllLabels(); } return; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (val == null) { continue; } string text = NametagStyler.Clean(val.NickName ?? ""); if (string.IsNullOrEmpty(text)) { continue; } string value = ""; try { if (val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).TryGetValue((object)"cr_nametag_typeface", out object value2)) { value = value2?.ToString() ?? ""; } } catch { } dictionary[text] = value; } if (dictionary.Count == 0) { return; } Object[] array = Object.FindObjectsOfType(_tTmpText); HashSet hashSet = new HashSet(); Object[] array2 = array; foreach (Object obj2 in array2) { Component val2 = (Component)(object)((obj2 is Component) ? obj2 : null); if (val2 != null) { hashSet.Add(val2); string name; try { name = (_pText.GetValue(val2) as string) ?? ""; } catch { continue; } string text2 = NametagStyler.Clean(name); string value3; if (string.IsNullOrEmpty(text2)) { RestoreLabel(val2); } else if (!dictionary.TryGetValue(text2, out value3)) { RestoreLabel(val2); } else { ApplyFont(val2, value3); } } } if (_states.Count <= 0) { return; } List list = null; foreach (KeyValuePair state in _states) { if (!hashSet.Contains(state.Key)) { if (list == null) { list = new List(); } list.Add(state.Key); } } if (list == null) { return; } foreach (Component item in list) { _states.Remove(item); } } private void ApplyFont(Component comp, string sku) { if (!_states.TryGetValue(comp, out var value)) { value = new LabelState(); try { value.OriginalFont = _pFont.GetValue(comp); } catch { return; } if (value.OriginalFont == null) { return; } _states[comp] = value; } if (string.IsNullOrEmpty(sku)) { if (value.LastAppliedSku != "") { try { _pFont.SetValue(comp, value.OriginalFont); } catch { } value.LastAppliedSku = ""; } } else { if (sku == value.LastAppliedSku) { return; } object orBuildFontAsset = GetOrBuildFontAsset(sku); if (orBuildFontAsset != null) { try { _pFont.SetValue(comp, orBuildFontAsset); } catch { return; } try { _mSetAllDirty?.Invoke(comp, null); } catch { } try { _mUpdateMaterial?.Invoke(comp, null); } catch { } try { _mForceMeshUpdate?.Invoke(comp, new object[2] { true, true }); } catch { } value.LastAppliedSku = sku; Plugin.Log.LogInfo((object)("[TYPEFACE] Applied " + sku + " to label '" + ((Object)comp).name + "'")); } } } public static object GetOrBuildFontAsset(string sku) { if (string.IsNullOrEmpty(sku)) { return null; } if (_fontAssetCache.TryGetValue(sku, out var value)) { return value; } if (_fontBuildFailed.Contains(sku)) { return null; } if (!TryBindReflection()) { return null; } if (!_skuToTmpFontName.TryGetValue(sku, out var value2)) { Plugin.Log.LogWarning((object)("[TYPEFACE] sku '" + sku + "' not in _skuToTmpFontName map — marking failed.")); _fontBuildFailed.Add(sku); return null; } EnsureBundleLoaded(); if (_bundledFontsByName != null && _bundledFontsByName.TryGetValue(value2, out var value3) && value3 != null) { _fontAssetCache[sku] = value3; Plugin.Log.LogInfo((object)("[TYPEFACE] Resolved " + sku + " → " + value2 + " (from bundle)")); return value3; } Plugin.Log.LogWarning((object)$"[TYPEFACE] TMP font '{value2}' for sku '{sku}' not in bundle — disabled. (Bundle present? {_bundledFontsByName != null})"); _fontBuildFailed.Add(sku); return null; } private static void EnsureBundleLoaded() { if (_bundleLoadAttempted) { return; } _bundleLoadAttempted = true; try { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "comp-rounds-fonts"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("[TYPEFACE] Font bundle not found at " + text + " — typefaces disabled. Run the Unity Font Bundler to produce it.")); return; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[TYPEFACE] AssetBundle.LoadFromFile returned null for " + text + " — corrupt or wrong Unity version.")); return; } _fontBundle = val; string[] allAssetNames = val.GetAllAssetNames(); _bundledFontsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); string[] array = allAssetNames; foreach (string text2 in array) { Object val2 = val.LoadAsset(text2, _tTmpFontAsset); if (!(val2 == (Object)null)) { string name = val2.name; if (!string.IsNullOrEmpty(name)) { _bundledFontsByName[name] = val2; } } } Plugin.Log.LogInfo((object)$"[TYPEFACE] Font bundle loaded: {_bundledFontsByName.Count} TMP_FontAssets available."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TYPEFACE] Bundle load failed: " + ex.Message)); } } public static void LogAvailableTmpFonts() { if (!TryBindReflection()) { return; } try { Object[] array = Resources.FindObjectsOfTypeAll(_tTmpFontAsset); int num = ((array != null) ? array.Length : 0); Plugin.Log.LogInfo((object)$"[TYPEFACE] Available TMP_FontAssets in memory: {num}"); if (array == null) { return; } HashSet hashSet = new HashSet(); Object[] array2 = array; foreach (Object obj in array2) { string text = ((obj != null) ? obj.name : null) ?? "(unnamed)"; if (hashSet.Add(text)) { Plugin.Log.LogInfo((object)("[TYPEFACE] - " + text)); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TYPEFACE] LogAvailableTmpFonts failed: " + ex.Message)); } } public static bool ApplyFontToLabel(object tmpLabel, string sku, Dictionary originalFontStore) { if (tmpLabel == null) { return false; } if (!TryBindReflection()) { return false; } if (!_loggedFirstApply) { _loggedFirstApply = true; ManualLogSource log = Plugin.Log; string[] obj = new string[5] { "[TYPEFACE] first ApplyFontToLabel call: sku='", sku, "' label='", null, null }; object obj2 = ((tmpLabel is Component) ? tmpLabel : null); obj[3] = ((obj2 != null) ? ((Object)obj2).name : null) ?? "(null)"; obj[4] = "'"; log.LogInfo((object)string.Concat(obj)); } try { object value = _pFont.GetValue(tmpLabel); if (originalFontStore != null && !originalFontStore.ContainsKey(tmpLabel) && value != null) { originalFontStore[tmpLabel] = value; } object value2; object obj3 = ((originalFontStore != null && originalFontStore.TryGetValue(tmpLabel, out value2)) ? value2 : value); object obj4 = (string.IsNullOrEmpty(sku) ? obj3 : GetOrBuildFontAsset(sku)); if (obj4 == null) { obj4 = obj3; } if (obj4 == null || value == obj4) { return false; } _pFont.SetValue(tmpLabel, obj4); try { _mSetAllDirty?.Invoke(tmpLabel, null); } catch { } try { _mUpdateMaterial?.Invoke(tmpLabel, null); } catch { } try { _mForceMeshUpdate?.Invoke(tmpLabel, new object[2] { true, true }); } catch { } return true; } catch { return false; } } private void RestoreLabel(Component comp) { if ((Object)(object)comp == (Object)null || !_states.TryGetValue(comp, out var value)) { return; } if (!string.IsNullOrEmpty(value.LastAppliedSku) && value.OriginalFont != null) { try { _pFont.SetValue(comp, value.OriginalFont); } catch { } } value.LastAppliedSku = ""; } private void RestoreAllLabels() { foreach (KeyValuePair state in _states) { if (!((Object)(object)state.Key == (Object)null) && !string.IsNullOrEmpty(state.Value.LastAppliedSku) && state.Value.OriginalFont != null) { try { _pFont.SetValue(state.Key, state.Value.OriginalFont); } catch { } state.Value.LastAppliedSku = ""; } } } } internal class NametagGlowRenderer : MonoBehaviour { private class LabelState { public Material OriginalMaterial; public string LastAppliedSku; public Material AppliedMaterial; } private class MaterialCacheKey : IEquatable { public Material BaseMaterial; public string Sku; public bool Equals(MaterialCacheKey other) { if (other != null && BaseMaterial == other.BaseMaterial) { return Sku == other.Sku; } return false; } public override bool Equals(object obj) { return Equals(obj as MaterialCacheKey); } public override int GetHashCode() { Material baseMaterial = BaseMaterial; return ((baseMaterial != null) ? ((Object)baseMaterial).GetInstanceID() : 0) ^ (Sku?.GetHashCode() ?? 0); } } private const float POLL_INTERVAL = 0.5f; private static Type _tTmpText; private static PropertyInfo _pText; private static PropertyInfo _pFontSharedMaterial; private static PropertyInfo _pFontMaterial; private static MethodInfo _mSetMaterialDirty; private static MethodInfo _mSetVerticesDirty; private static MethodInfo _mSetLayoutDirty; private static MethodInfo _mUpdateMaterial; private static bool _reflectionReady; private readonly Dictionary _states = new Dictionary(); private readonly Dictionary _matCache = new Dictionary(); private static bool TryBindReflection() { if (_reflectionReady) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { _tTmpText = assemblies[i].GetType("TMPro.TMP_Text"); if (_tTmpText != null) { break; } } if (_tTmpText == null) { return false; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; _pText = _tTmpText.GetProperty("text", bindingAttr); _pFontSharedMaterial = _tTmpText.GetProperty("fontSharedMaterial", bindingAttr); _pFontMaterial = _tTmpText.GetProperty("fontMaterial", bindingAttr); _mSetMaterialDirty = _tTmpText.GetMethod("SetMaterialDirty", bindingAttr); _mSetVerticesDirty = _tTmpText.GetMethod("SetVerticesDirty", bindingAttr); _mSetLayoutDirty = _tTmpText.GetMethod("SetLayoutDirty", bindingAttr); _mUpdateMaterial = _tTmpText.GetMethod("UpdateMaterial", bindingAttr); _reflectionReady = _pText != null && _pFontSharedMaterial != null; return _reflectionReady; } catch { return false; } } private void OnEnable() { ((MonoBehaviour)this).StartCoroutine(PollLoop()); } private void OnDisable() { ((MonoBehaviour)this).StopAllCoroutines(); RestoreAllLabels(); } private IEnumerator PollLoop() { WaitForSeconds wait = new WaitForSeconds(0.5f); while (true) { try { ScanAndApply(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[GLOW] scan error: " + ex.Message)); } yield return wait; } } private void ScanAndApply() { if (!TryBindReflection()) { return; } if (!PhotonNetwork.InRoom) { if (_states.Count > 0) { RestoreAllLabels(); } return; } Dictionary dictionary = new Dictionary(StringComparer.Ordinal); Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (val == null) { continue; } string text = NametagStyler.Clean(val.NickName ?? ""); if (string.IsNullOrEmpty(text)) { continue; } string value = ""; try { if (val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).TryGetValue((object)"cr_nametag_glow", out object value2)) { value = value2?.ToString() ?? ""; } } catch { } dictionary[text] = value; } if (dictionary.Count == 0) { return; } Object[] array = Object.FindObjectsOfType(_tTmpText); HashSet hashSet = new HashSet(); Object[] array2 = array; foreach (Object obj2 in array2) { Component val2 = (Component)(object)((obj2 is Component) ? obj2 : null); if (val2 != null) { hashSet.Add(val2); string name; try { name = (_pText.GetValue(val2) as string) ?? ""; } catch { continue; } string text2 = NametagStyler.Clean(name); string value3; if (string.IsNullOrEmpty(text2)) { RestoreLabel(val2); } else if (!dictionary.TryGetValue(text2, out value3)) { RestoreLabel(val2); } else { ApplyGlow(val2, value3); } } } if (_states.Count <= 0) { return; } List list = null; foreach (KeyValuePair state in _states) { if (!hashSet.Contains(state.Key)) { if (list == null) { list = new List(); } list.Add(state.Key); } } if (list == null) { return; } foreach (Component item in list) { _states.Remove(item); } } private void ApplyGlow(Component comp, string sku) { if (!_states.TryGetValue(comp, out var value)) { value = new LabelState(); Material val; try { object? value2 = _pFontSharedMaterial.GetValue(comp); val = (Material)((value2 is Material) ? value2 : null); } catch { return; } if ((Object)(object)val == (Object)null) { return; } if (((Object)val).name != null && ((Object)val).name.Contains(" + nametag_")) { Material val2 = null; foreach (KeyValuePair item in _matCache) { if (item.Value == val) { val2 = item.Key.BaseMaterial; break; } } value.OriginalMaterial = val2 ?? val; } else { value.OriginalMaterial = val; } _states[comp] = value; } if (string.IsNullOrEmpty(sku)) { if (value.LastAppliedSku != "") { try { _pFontSharedMaterial.SetValue(comp, value.OriginalMaterial); } catch { } value.LastAppliedSku = ""; } } else { if (sku == value.LastAppliedSku) { return; } MaterialCacheKey key = new MaterialCacheKey { BaseMaterial = value.OriginalMaterial, Sku = sku }; if (!_matCache.TryGetValue(key, out var value3) || (Object)(object)value3 == (Object)null) { value3 = BuildGlowMaterial(value.OriginalMaterial, sku); if ((Object)(object)value3 == (Object)null) { return; } _matCache[key] = value3; } try { if (_pFontMaterial != null) { _pFontMaterial.SetValue(comp, value3); } else { _pFontSharedMaterial.SetValue(comp, value3); } } catch { return; } try { _mSetMaterialDirty?.Invoke(comp, null); } catch { } try { _mSetVerticesDirty?.Invoke(comp, null); } catch { } try { _mSetLayoutDirty?.Invoke(comp, null); } catch { } try { _mUpdateMaterial?.Invoke(comp, null); } catch { } value.LastAppliedSku = sku; value.AppliedMaterial = value3; Plugin.Log.LogInfo((object)("[GLOW] Applied " + sku + " to label '" + ((Object)comp).name + "'")); } } public static Material BuildGlowMaterial(Material baseMat, string sku) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0033: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_022e: 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_024c: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)baseMat == (Object)null) { return null; } try { Material val = new Material(baseMat); ((Object)val).name = ((Object)baseMat).name + " + " + sku; ((Object)val).hideFlags = (HideFlags)61; Color glowColor = NametagStyler.GetGlowColor(sku); try { val.DisableKeyword("UNDERLAY_ON"); } catch { } try { val.DisableKeyword("GLOW_ON"); } catch { } if (val.HasProperty("_OutlineColor")) { val.SetColor("_OutlineColor", glowColor); } if (val.HasProperty("_OutlineWidth")) { val.SetFloat("_OutlineWidth", 0.15f); } if (val.HasProperty("_OutlineSoftness")) { val.SetFloat("_OutlineSoftness", 0.25f); } if (val.HasProperty("_FaceColor")) { val.SetColor("_FaceColor", Color.white); } if (val.HasProperty("_FaceDilate")) { val.SetFloat("_FaceDilate", 0f); } if (val.HasProperty("_UnderlayColor")) { val.SetColor("_UnderlayColor", Color.clear); } if (val.HasProperty("_UnderlayDilate")) { val.SetFloat("_UnderlayDilate", 0f); } if (val.HasProperty("_UnderlaySoftness")) { val.SetFloat("_UnderlaySoftness", 0f); } if (val.HasProperty("_GlowOuter")) { val.SetFloat("_GlowOuter", 0f); } if (val.HasProperty("_GlowPower")) { val.SetFloat("_GlowPower", 0f); } float num = (val.HasProperty("_OutlineWidth") ? val.GetFloat("_OutlineWidth") : (-1f)); float num2 = (val.HasProperty("_OutlineSoftness") ? val.GetFloat("_OutlineSoftness") : (-1f)); Color val2 = (val.HasProperty("_FaceColor") ? val.GetColor("_FaceColor") : Color.magenta); Color val3 = (val.HasProperty("_OutlineColor") ? val.GetColor("_OutlineColor") : Color.magenta); Plugin.Log.LogInfo((object)$"[GLOW] post-set props: outlineWidth={num} outlineSoftness={num2} faceColor=({val2.r:F2},{val2.g:F2},{val2.b:F2},{val2.a:F2}) outlineColor=({val3.r:F2},{val3.g:F2},{val3.b:F2},{val3.a:F2})"); string text = ""; try { text = string.Join(",", val.shaderKeywords); } catch { } ManualLogSource log = Plugin.Log; string[] obj4 = new string[9] { "[GLOW] Built material for ", sku, " (base=", ((Object)baseMat).name, ", shader=", null, null, null, null }; Shader shader = val.shader; obj4[5] = ((shader != null) ? ((Object)shader).name : null); obj4[6] = ", keywords=["; obj4[7] = text; obj4[8] = "])"; log.LogInfo((object)string.Concat(obj4)); return val; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[GLOW] BuildGlowMaterial(" + sku + ") failed: " + ex.Message)); return null; } } public static bool ApplyGlowToLabel(object tmpLabel, string sku, Dictionary originalMaterialStore, Dictionary glowMaterialCache) { if (tmpLabel == null) { return false; } if (!TryBindReflection()) { return false; } try { object? value = _pFontSharedMaterial.GetValue(tmpLabel); Material val = (Material)((value is Material) ? value : null); if (originalMaterialStore != null && !originalMaterialStore.ContainsKey(tmpLabel) && (Object)(object)val != (Object)null) { originalMaterialStore[tmpLabel] = val; } Material value2; Material val2 = ((originalMaterialStore != null && originalMaterialStore.TryGetValue(tmpLabel, out value2)) ? value2 : val); Material value3; if (string.IsNullOrEmpty(sku)) { value3 = val2; } else if (glowMaterialCache == null || !glowMaterialCache.TryGetValue(sku, out value3) || (Object)(object)value3 == (Object)null) { value3 = BuildGlowMaterial(val2, sku); if (glowMaterialCache != null && (Object)(object)value3 != (Object)null) { glowMaterialCache[sku] = value3; } } if ((Object)(object)value3 == (Object)null || val == value3) { return false; } if (_pFontMaterial != null) { _pFontMaterial.SetValue(tmpLabel, value3); } else { _pFontSharedMaterial.SetValue(tmpLabel, value3); } try { _mSetMaterialDirty?.Invoke(tmpLabel, null); } catch { } try { _mSetVerticesDirty?.Invoke(tmpLabel, null); } catch { } try { _mUpdateMaterial?.Invoke(tmpLabel, null); } catch { } return true; } catch { return false; } } private void RestoreLabel(Component comp) { if ((Object)(object)comp == (Object)null || !_states.TryGetValue(comp, out var value)) { return; } if (!string.IsNullOrEmpty(value.LastAppliedSku) && (Object)(object)value.OriginalMaterial != (Object)null) { try { _pFontSharedMaterial.SetValue(comp, value.OriginalMaterial); } catch { } } value.LastAppliedSku = ""; } private void RestoreAllLabels() { foreach (KeyValuePair state in _states) { if (!((Object)(object)state.Key == (Object)null) && !string.IsNullOrEmpty(state.Value.LastAppliedSku) && !((Object)(object)state.Value.OriginalMaterial == (Object)null)) { try { _pFontSharedMaterial.SetValue(state.Key, state.Value.OriginalMaterial); } catch { } state.Value.LastAppliedSku = ""; } } } } internal static class NametagStyler { private static string _baseName; private static readonly Dictionary _tagsBySku = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "nametag_bold", ("", "") }, { "nametag_italic", ("", "") }, { "nametag_underline", ("", "") }, { "nametag_strike", ("", "") }, { "nametag_color_red", ("", "") }, { "nametag_color_cyan", ("", "") }, { "nametag_color_gold", ("", "") }, { "nametag_color_purple", ("", "") }, { "nametag_color_green", ("", "") }, { "nametag_color_pink", ("", "") }, { "nametag_neon_pink", ("", "") }, { "nametag_neon_cyan", ("", "") }, { "nametag_neon_lime", ("", "") }, { "nametag_neon_orange", ("", "") }, { "nametag_neon_violet", ("", "") }, { "nametag_neon_toxic", ("", "") }, { "nametag_neon_glowyellow", ("", "") }, { "nametag_font_caps", ("", "") }, { "nametag_font_smallcaps", ("", "") }, { "nametag_font_spaced", ("", "") }, { "nametag_size_smaller", ("", "") }, { "nametag_size_bigger", ("", "") }, { "nametag_size_huge", ("", "") }, { "nametag_size_xl", ("", "") }, { "nametag_color_emerald", ("", "") }, { "nametag_color_amber", ("", "") }, { "nametag_color_coral", ("", "") }, { "nametag_color_indigo", ("", "") }, { "nametag_float", ("", "") } }; private static readonly string[] _RAINBOW_COLORS = new string[6] { "#FF5566", "#FFB347", "#FFEE55", "#88FF99", "#55CCFF", "#BB88FF" }; private static readonly Dictionary _GRADIENT_PAIRS = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "nametag_gradient_sunset", (new Color(1f, 0.7f, 0.28f), new Color(0.9f, 0.3f, 0.54f)) }, { "nametag_gradient_aurora", (new Color(0.3f, 1f, 0.85f), new Color(0.65f, 0.4f, 1f)) }, { "nametag_gradient_ocean", (new Color(0.35f, 0.95f, 1f), new Color(0.15f, 0.2f, 0.65f)) }, { "nametag_gradient_ember", (new Color(1f, 0.95f, 0.3f), new Color(0.8f, 0.15f, 0.1f)) }, { "nametag_gradient_galaxy", (new Color(1f, 0.35f, 0.85f), new Color(0.35f, 0.65f, 1f)) } }; private static string _BuildRainbow(string clean) { if (string.IsNullOrEmpty(clean)) { return clean; } if (clean.IndexOf('<') >= 0) { return clean; } StringBuilder stringBuilder = new StringBuilder(clean.Length * 18); int num = 0; foreach (char c in clean) { if (char.IsWhiteSpace(c)) { stringBuilder.Append(c); continue; } stringBuilder.Append("') .Append(c) .Append(""); num++; } return stringBuilder.ToString(); } private static string _BuildGradientLerp(string clean, Color start, Color end) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(clean)) { return clean; } if (clean.IndexOf('<') >= 0) { return clean; } int num = 0; string text = clean; for (int i = 0; i < text.Length; i++) { if (!char.IsWhiteSpace(text[i])) { num++; } } switch (num) { case 0: return clean; case 1: return "" + clean + ""; default: { StringBuilder stringBuilder = new StringBuilder(clean.Length * 18); int num2 = 0; text = clean; foreach (char c in text) { if (char.IsWhiteSpace(c)) { stringBuilder.Append(c); continue; } float num3 = (float)num2 / (float)(num - 1); Color val = Color.Lerp(start, end, num3); stringBuilder.Append("') .Append(c) .Append(""); num2++; } return stringBuilder.ToString(); } } } public static Color GetGlowColor(string sku) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: 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_0298: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(sku)) { return Color.clear; } return (Color)(sku switch { "nametag_glow_red" => new Color(1f, 0.27f, 0.33f, 1f), "nametag_glow_blue" => new Color(0.27f, 0.53f, 1f, 1f), "nametag_glow_gold" => new Color(1f, 0.8f, 0.27f, 1f), "nametag_glow_pink" => new Color(1f, 0.53f, 0.8f, 1f), "nametag_neon_pink" => new Color(1f, 0.12f, 0.55f, 1f), "nametag_neon_cyan" => new Color(0.12f, 0.94f, 1f, 1f), "nametag_neon_lime" => new Color(0.36f, 1f, 0.12f, 1f), "nametag_neon_orange" => new Color(1f, 0.48f, 0.12f, 1f), "nametag_neon_violet" => new Color(0.83f, 0.13f, 1f, 1f), "nametag_neon_toxic" => new Color(0.66f, 1f, 0.12f, 1f), "nametag_neon_glowyellow" => new Color(1f, 0.98f, 0.61f, 1f), _ => Color.clear, }); } public static string GetSubgroup(string sku) { if (string.IsNullOrEmpty(sku)) { return null; } if (sku.StartsWith("nametag_color_", StringComparison.OrdinalIgnoreCase)) { return "color"; } if (sku.StartsWith("nametag_neon_", StringComparison.OrdinalIgnoreCase)) { return "color"; } if (sku.StartsWith("nametag_glow_", StringComparison.OrdinalIgnoreCase)) { return "glow"; } if (sku.StartsWith("nametag_size_", StringComparison.OrdinalIgnoreCase)) { return "size"; } if (sku.StartsWith("nametag_typeface_", StringComparison.OrdinalIgnoreCase)) { return "typeface"; } if (sku.StartsWith("nametag_font_", StringComparison.OrdinalIgnoreCase)) { return "font"; } if (sku == "nametag_rainbow" || sku.StartsWith("nametag_gradient_", StringComparison.OrdinalIgnoreCase)) { return "color"; } return null; } public static string GetActiveTypefaceSku(List activeSkus) { if (activeSkus == null) { return ""; } foreach (string activeSku in activeSkus) { if (!string.IsNullOrEmpty(activeSku) && activeSku.StartsWith("nametag_typeface_", StringComparison.OrdinalIgnoreCase)) { return activeSku; } } return ""; } public static string Clean(string name) { if (string.IsNullOrEmpty(name)) { return name; } return Regex.Replace(name, "<.*?>", "").Trim(); } public static string WrapForSku(string name, string sku) { if (string.IsNullOrEmpty(name)) { return name; } if (sku == null) { return name; } if (_tagsBySku.TryGetValue(sku, out (string, string) value)) { return value.Item1 + name + value.Item2; } return name; } public static string Wrap(string name, List activeSkus) { //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) string text = Clean(name); if (string.IsNullOrEmpty(text)) { return text; } if (activeSkus == null || activeSkus.Count == 0) { return text; } string[][] array = new string[8][] { new string[3] { "nametag_font_caps", "nametag_font_smallcaps", "nametag_font_spaced" }, new string[4] { "nametag_size_smaller", "nametag_size_bigger", "nametag_size_huge", "nametag_size_xl" }, new string[17] { "nametag_color_red", "nametag_color_cyan", "nametag_color_gold", "nametag_color_purple", "nametag_color_green", "nametag_color_pink", "nametag_color_emerald", "nametag_color_amber", "nametag_color_coral", "nametag_color_indigo", "nametag_neon_pink", "nametag_neon_cyan", "nametag_neon_lime", "nametag_neon_orange", "nametag_neon_violet", "nametag_neon_toxic", "nametag_neon_glowyellow" }, new string[1] { "nametag_strike" }, new string[1] { "nametag_underline" }, new string[1] { "nametag_italic" }, new string[1] { "nametag_bold" }, new string[1] { "nametag_float" } }; string text2 = text; foreach (string activeSku in activeSkus) { if (!string.IsNullOrEmpty(activeSku)) { if (activeSku == "nametag_rainbow") { text2 = _BuildRainbow(text2); break; } if (_GRADIENT_PAIRS.TryGetValue(activeSku, out (Color, Color) value)) { text2 = _BuildGradientLerp(text2, value.Item1, value.Item2); break; } } } string[][] array2 = array; foreach (string[] array3 in array2) { foreach (string text3 in array3) { if (activeSkus.Contains(text3) && _tagsBySku.TryGetValue(text3, out (string, string) value2)) { text2 = value2.Item1 + text2 + value2.Item2; break; } } } return text2; } public static string GetActiveGlowSku(List activeSkus) { if (activeSkus == null) { return ""; } foreach (string activeSku in activeSkus) { if (!string.IsNullOrEmpty(activeSku) && activeSku.StartsWith("nametag_glow_", StringComparison.OrdinalIgnoreCase)) { return activeSku; } } foreach (string activeSku2 in activeSkus) { if (!string.IsNullOrEmpty(activeSku2) && activeSku2.StartsWith("nametag_neon_", StringComparison.OrdinalIgnoreCase)) { return activeSku2; } } return ""; } public static void PublishToPhoton() { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown try { if (!PhotonNetwork.IsConnected || PhotonNetwork.LocalPlayer == null) { return; } if (string.IsNullOrEmpty(_baseName)) { _baseName = Clean(PhotonNetwork.LocalPlayer.NickName); } string text = Clean(PhotonNetwork.LocalPlayer.NickName); if (!string.IsNullOrEmpty(text)) { _baseName = text; } if (string.IsNullOrEmpty(_baseName)) { return; } List list = ApiClient.CachedPlayerStats?.active_nametag_skus; string text2 = Wrap(_baseName, list); if (PhotonNetwork.LocalPlayer.NickName != text2) { PhotonNetwork.LocalPlayer.NickName = text2; Plugin.Log.LogInfo((object)$"[NAMETAG] Published '{text2}' ({list?.Count ?? 0} style(s))"); } string activeGlowSku = GetActiveGlowSku(list); string activeTypefaceSku = GetActiveTypefaceSku(list); try { Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; object value; bool flag = !((Dictionary)(object)customProperties).TryGetValue((object)"cr_nametag_glow", out value) || (value?.ToString() ?? "") != activeGlowSku; object value2; bool flag2 = !((Dictionary)(object)customProperties).TryGetValue((object)"cr_nametag_typeface", out value2) || (value2?.ToString() ?? "") != activeTypefaceSku; if (flag || flag2) { Hashtable val = new Hashtable(); if (flag) { val[(object)"cr_nametag_glow"] = activeGlowSku; } if (flag2) { val[(object)"cr_nametag_typeface"] = activeTypefaceSku; } PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } catch { } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NAMETAG] Publish failed: " + ex.Message)); } } } internal static class ClickGuard { private static float lastTime = -1f; public static bool Claim() { if (Time.unscaledTime - lastTime < 0.2f) { return false; } lastTime = Time.unscaledTime; return true; } } internal static class UIFactory { public struct ScrollViewRefs { public GameObject scrollGO; public GameObject content; public RectTransform contentRT; } internal static Type tImage; internal static Type tButton; internal static Type tCanvas; internal static Type tLE; internal static Type tScrollRect; internal static Type tMask; private static Type tVLG; private static Type tHLG; private static Type tCSF; internal static Type tGR; internal static Type tCanvasScaler; private static Type tTMP; private static bool typesReady; private static object tmpFont; private static bool fontReady; public static Type tListMenu; public static Type tListMenuPage; public static Type tGoBack; private static PropertyInfo pTmpText; private static PropertyInfo pTmpFontSize; private static PropertyInfo pTmpColor; private static PropertyInfo pTmpAlignment; private static PropertyInfo pTmpFont; private static PropertyInfo pTmpOverflow; private static PropertyInfo pTmpRichText; private static PropertyInfo pTmpFontStyle; private static PropertyInfo pTmpRaycastTarget; private static PropertyInfo pTmpCharSpacing; private static PropertyInfo pImgColor; private static PropertyInfo pImgRaycastTarget; private static PropertyInfo pBtnOnClick; private static MethodInfo mOnClickAdd; private static PropertyInfo pSRContent; private static PropertyInfo pSRViewport; private static PropertyInfo pSRVertical; private static PropertyInfo pSRHorizontal; private static PropertyInfo pSRMovementType; private static PropertyInfo pSRScrollSensitivity; private static PropertyInfo pVLGSpacing; private static PropertyInfo pVLGPadding; private static PropertyInfo pVLGChildForceW; private static PropertyInfo pVLGChildForceH; private static PropertyInfo pVLGChildControlW; private static PropertyInfo pVLGChildControlH; private static PropertyInfo pHLGSpacing; private static PropertyInfo pHLGPadding; private static PropertyInfo pHLGChildForceW; private static PropertyInfo pHLGChildForceH; private static PropertyInfo pHLGChildControlW; private static PropertyInfo pHLGChildControlH; private static PropertyInfo pCSFFit; private static PropertyInfo pLEMinW; private static PropertyInfo pLEMinH; private static PropertyInfo pLEPrefW; private static PropertyInfo pLEPrefH; private static PropertyInfo pLEFlexW; private static PropertyInfo pLEFlexH; private static PropertyInfo pLEIgnore; public const int AlignTopLeft = 257; public const int AlignTopCenter = 258; public const int AlignTopRight = 260; public const int AlignMidLeft = 513; public const int AlignMidCenter = 514; public const int AlignMidRight = 516; public static bool Ready { get { if (typesReady) { return fontReady; } return false; } } public static bool InitTypes() { if (typesReady) { return true; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (tImage == null) { tImage = assembly.GetType("UnityEngine.UI.Image"); } if (tButton == null) { tButton = assembly.GetType("UnityEngine.UI.Button"); } if (tScrollRect == null) { tScrollRect = assembly.GetType("UnityEngine.UI.ScrollRect"); } if (tMask == null) { tMask = assembly.GetType("UnityEngine.UI.Mask"); } if (tVLG == null) { tVLG = assembly.GetType("UnityEngine.UI.VerticalLayoutGroup"); } if (tHLG == null) { tHLG = assembly.GetType("UnityEngine.UI.HorizontalLayoutGroup"); } if (tCSF == null) { tCSF = assembly.GetType("UnityEngine.UI.ContentSizeFitter"); } if (tLE == null) { tLE = assembly.GetType("UnityEngine.UI.LayoutElement"); } if (tGR == null) { tGR = assembly.GetType("UnityEngine.UI.GraphicRaycaster"); } if (tTMP == null) { tTMP = assembly.GetType("TMPro.TextMeshProUGUI"); } if (tCanvas == null) { tCanvas = assembly.GetType("UnityEngine.Canvas"); } if (tCanvasScaler == null) { tCanvasScaler = assembly.GetType("UnityEngine.UI.CanvasScaler"); } if (tListMenu == null) { tListMenu = assembly.GetType("ListMenu"); } if (tListMenuPage == null) { tListMenuPage = assembly.GetType("ListMenuPage"); } if (tGoBack == null) { tGoBack = assembly.GetType("GoBack"); } } if (tImage == null || tTMP == null || tButton == null) { Plugin.Log.LogWarning((object)"[UI] Missing UI types"); return false; } if (tListMenu == null || tListMenuPage == null) { Plugin.Log.LogWarning((object)"[UI] Missing ROUNDS types"); return false; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; pTmpText = tTMP.GetProperty("text", bindingAttr); pTmpFontSize = tTMP.GetProperty("fontSize", bindingAttr); pTmpColor = tTMP.GetProperty("color", bindingAttr); pTmpAlignment = tTMP.GetProperty("alignment", bindingAttr); pTmpFont = tTMP.GetProperty("font", bindingAttr); pTmpOverflow = tTMP.GetProperty("overflowMode", bindingAttr); pTmpRichText = tTMP.GetProperty("richText", bindingAttr); pTmpFontStyle = tTMP.GetProperty("fontStyle", bindingAttr); pTmpRaycastTarget = tTMP.GetProperty("raycastTarget", bindingAttr); pTmpCharSpacing = tTMP.GetProperty("characterSpacing", bindingAttr); pImgColor = tImage.GetProperty("color", bindingAttr); pImgRaycastTarget = tImage.GetProperty("raycastTarget", bindingAttr); pBtnOnClick = tButton.GetProperty("onClick", bindingAttr); if (pBtnOnClick != null) { mOnClickAdd = pBtnOnClick.PropertyType.GetMethod("AddListener", new Type[1] { typeof(UnityAction) }); } pSRContent = tScrollRect?.GetProperty("content", bindingAttr); pSRViewport = tScrollRect?.GetProperty("viewport", bindingAttr); pSRVertical = tScrollRect?.GetProperty("vertical", bindingAttr); pSRHorizontal = tScrollRect?.GetProperty("horizontal", bindingAttr); pSRMovementType = tScrollRect?.GetProperty("movementType", bindingAttr); pSRScrollSensitivity = tScrollRect?.GetProperty("scrollSensitivity", bindingAttr); if (tVLG != null) { pVLGSpacing = tVLG.GetProperty("spacing", bindingAttr); pVLGPadding = tVLG.GetProperty("padding", bindingAttr); pVLGChildForceW = tVLG.GetProperty("childForceExpandWidth", bindingAttr); pVLGChildForceH = tVLG.GetProperty("childForceExpandHeight", bindingAttr); pVLGChildControlW = tVLG.GetProperty("childControlWidth", bindingAttr); pVLGChildControlH = tVLG.GetProperty("childControlHeight", bindingAttr); } if (tHLG != null) { pHLGSpacing = tHLG.GetProperty("spacing", bindingAttr); pHLGPadding = tHLG.GetProperty("padding", bindingAttr); pHLGChildForceW = tHLG.GetProperty("childForceExpandWidth", bindingAttr); pHLGChildForceH = tHLG.GetProperty("childForceExpandHeight", bindingAttr); pHLGChildControlW = tHLG.GetProperty("childControlWidth", bindingAttr); pHLGChildControlH = tHLG.GetProperty("childControlHeight", bindingAttr); } if (tCSF != null) { pCSFFit = tCSF.GetProperty("verticalFit", bindingAttr); } if (tLE != null) { pLEMinW = tLE.GetProperty("minWidth", bindingAttr); pLEMinH = tLE.GetProperty("minHeight", bindingAttr); pLEPrefW = tLE.GetProperty("preferredWidth", bindingAttr); pLEPrefH = tLE.GetProperty("preferredHeight", bindingAttr); pLEFlexW = tLE.GetProperty("flexibleWidth", bindingAttr); pLEFlexH = tLE.GetProperty("flexibleHeight", bindingAttr); pLEIgnore = tLE.GetProperty("ignoreLayout", bindingAttr); } typesReady = true; return true; } public static bool InitFont() { if (fontReady) { return true; } if (!typesReady) { return false; } Object[] array = Object.FindObjectsOfType(tTMP); foreach (Object obj in array) { try { object obj2 = pTmpFont?.GetValue(obj); if (obj2 != null) { tmpFont = obj2; fontReady = true; return true; } } catch { } } return false; } public static GameObject CreatePanel(string name, Transform parent, Color bgColor, Vector2? sizeDelta = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; if (sizeDelta.HasValue) { val2.sizeDelta = sizeDelta.Value; } if (bgColor.a > 0f) { Component obj = val.AddComponent(tImage); pImgColor?.SetValue(obj, bgColor); pImgRaycastTarget?.SetValue(obj, true); } return val; } private static string _BoldWrap(string s) { if (string.IsNullOrEmpty(s)) { return s; } if (s.StartsWith("") && s.EndsWith("")) { return s; } return "" + s + ""; } public static object CreateText(string name, Transform parent, string text, float fontSize, Color color, int alignment = 257, Vector2? sizeDelta = null, bool richText = true, bool raycastTarget = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0039: 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_003e: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_00d2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); Vector2 val2 = (val.AddComponent().sizeDelta = (Vector2)(((??)sizeDelta) ?? new Vector2(200f, 24f))); if (val2.x > 0f && val2.y > 0f) { AddLE(val, -1f, -1f, val2.x, val2.y); } Component val4 = val.AddComponent(tTMP); pTmpText?.SetValue(val4, richText ? _BoldWrap(text) : text); pTmpFontSize?.SetValue(val4, fontSize); pTmpColor?.SetValue(val4, color); pTmpRichText?.SetValue(val4, richText); pTmpRaycastTarget?.SetValue(val4, raycastTarget); if (tmpFont != null) { pTmpFont?.SetValue(val4, tmpFont); } pTmpCharSpacing?.SetValue(val4, 1f); try { pTmpFontStyle?.SetValue(val4, Enum.ToObject(pTmpFontStyle.PropertyType, 1)); } catch { } try { Type type = pTmpAlignment?.PropertyType; if (type != null) { pTmpAlignment.SetValue(val4, Enum.ToObject(type, alignment)); } } catch { } return val4; } public static GameObject CreateButton(string name, Transform parent, string label, float fontSize, Color textColor, Color bgColor, UnityAction onClick, Vector2? sizeDelta = null) { //IL_002e: 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) //IL_0033: 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_0038: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown Vector2 val = (Vector2)(((??)sizeDelta) ?? new Vector2(100f, 28f)); GameObject val2 = CreatePanel(name, parent, bgColor, val); RectTransform component = val2.GetComponent(); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); component.anchorMax = val3; component.anchorMin = val3; component.sizeDelta = val; AddLE(val2, -1f, -1f, val.x, val.y); CreateText(name + "_Txt", val2.transform, label, fontSize, textColor, 514, Vector2.zero); RectTransform component2 = ((Component)val2.transform.GetChild(0)).GetComponent(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; Component component3 = ((Component)val2.transform.GetChild(0)).GetComponent(tLE); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } Component obj = val2.AddComponent(tButton); try { PropertyInfo property = tButton.GetProperty("targetGraphic", BindingFlags.Instance | BindingFlags.Public); Component component4 = val2.GetComponent(tImage); if (property != null && (Object)(object)component4 != (Object)null) { property.SetValue(obj, component4); } } catch { } if (pBtnOnClick != null && mOnClickAdd != null && onClick != null) { UnityAction val4 = (UnityAction)delegate { if (ClickGuard.Claim()) { onClick.Invoke(); } }; mOnClickAdd.Invoke(pBtnOnClick.GetValue(obj), new object[1] { val4 }); } if (onClick != null) { val2.AddComponent().onClick = delegate { if (ClickGuard.Claim()) { onClick.Invoke(); } }; } return val2; } public static ScrollViewRefs CreateScrollView(string name, Transform parent, float spacing = 2f, bool childForceExpandWidth = true) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0170: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) ScrollViewRefs result = default(ScrollViewRefs); GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; GameObject val2 = new GameObject("Viewport"); val2.transform.SetParent(val.transform, false); RectTransform val3 = val2.AddComponent(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Component obj2 = val2.AddComponent(tImage); pImgColor?.SetValue(obj2, (object)new Color(0f, 0f, 0f, 0.01f)); tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, true); if (tMask != null) { Component obj3 = val2.AddComponent(tMask); tMask.GetProperty("showMaskGraphic", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj3, false); } GameObject val4 = new GameObject("Content"); val4.transform.SetParent(val2.transform, false); RectTransform val5 = val4.AddComponent(); val5.anchorMin = new Vector2(0f, 1f); val5.anchorMax = new Vector2(1f, 1f); val5.pivot = new Vector2(0.5f, 1f); val5.sizeDelta = Vector2.zero; if (tVLG != null) { Component obj4 = val4.AddComponent(tVLG); pVLGSpacing?.SetValue(obj4, spacing); pVLGChildForceW?.SetValue(obj4, childForceExpandWidth); pVLGChildForceH?.SetValue(obj4, false); pVLGChildControlW?.SetValue(obj4, true); pVLGChildControlH?.SetValue(obj4, true); } if (tCSF != null) { Component obj5 = val4.AddComponent(tCSF); Type type = pCSFFit?.PropertyType; if (type != null) { pCSFFit.SetValue(obj5, Enum.ToObject(type, 2)); } } Component obj6 = val.AddComponent(tScrollRect); pSRContent?.SetValue(obj6, val5); pSRViewport?.SetValue(obj6, val3); pSRVertical?.SetValue(obj6, true); pSRHorizontal?.SetValue(obj6, false); pSRScrollSensitivity?.SetValue(obj6, 25f); Type type2 = pSRMovementType?.PropertyType; if (type2 != null) { pSRMovementType.SetValue(obj6, Enum.ToObject(type2, 1)); } result.scrollGO = val; result.content = val4; result.contentRT = val5; return result; } public static void AddVLG(GameObject go, float spacing = 2f, int padL = 0, int padR = 0, int padT = 0, int padB = 0, bool forceExpandW = true, bool forceExpandH = false) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (!(tVLG == null)) { Component obj = go.AddComponent(tVLG); pVLGSpacing?.SetValue(obj, spacing); pVLGPadding?.SetValue(obj, (object?)new RectOffset(padL, padR, padT, padB)); pVLGChildForceW?.SetValue(obj, forceExpandW); pVLGChildForceH?.SetValue(obj, forceExpandH); pVLGChildControlW?.SetValue(obj, true); pVLGChildControlH?.SetValue(obj, true); } } public static void AddHLG(GameObject go, float spacing = 4f, int padL = 0, int padR = 0, int padT = 0, int padB = 0, bool forceExpandW = false, bool forceExpandH = true) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (!(tHLG == null)) { Component obj = go.AddComponent(tHLG); pHLGSpacing?.SetValue(obj, spacing); pHLGPadding?.SetValue(obj, (object?)new RectOffset(padL, padR, padT, padB)); pHLGChildForceW?.SetValue(obj, forceExpandW); pHLGChildForceH?.SetValue(obj, forceExpandH); pHLGChildControlW?.SetValue(obj, true); pHLGChildControlH?.SetValue(obj, true); } } public static void AddLE(GameObject go, float minW = -1f, float minH = -1f, float prefW = -1f, float prefH = -1f, float flexW = -1f, float flexH = -1f) { if (!(tLE == null)) { Component obj = go.AddComponent(tLE); if (minW >= 0f) { pLEMinW?.SetValue(obj, minW); } if (minH >= 0f) { pLEMinH?.SetValue(obj, minH); } if (prefW >= 0f) { pLEPrefW?.SetValue(obj, prefW); } if (prefH >= 0f) { pLEPrefH?.SetValue(obj, prefH); } if (flexW >= 0f) { pLEFlexW?.SetValue(obj, flexW); } if (flexH >= 0f) { pLEFlexH?.SetValue(obj, flexH); } } } public static Component CreateFillBar(string name, Transform parent, Color bgColor, Color fillColor, float height = 8f) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00f3: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name + "_BG"); val.transform.SetParent(parent, false); val.AddComponent(); AddLE(val, -1f, -1f, -1f, height, -1f, 0f); val.AddComponent(tImage); pImgColor?.SetValue(val.GetComponent(tImage), bgColor); GameObject val2 = new GameObject(name + "_Fill"); val2.transform.SetParent(val.transform, false); RectTransform obj = val2.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = new Vector2(0f, 1f); obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; val2.AddComponent(tImage); PropertyInfo propertyInfo = pImgColor; if ((object)propertyInfo != null) { propertyInfo.SetValue(val2.GetComponent(tImage), fillColor); return (Component)(object)obj; } return (Component)(object)obj; } public static void SetFill(Component f, float a) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)f == (Object)null)) { RectTransform val = (RectTransform)(object)((f is RectTransform) ? f : null); if ((Object)(object)val != (Object)null) { val.anchorMax = new Vector2(Mathf.Clamp01(a), 1f); } } } public static void SetText(object t, string s) { if (t != null) { pTmpText?.SetValue(t, _BoldWrap(s ?? "")); } } public static void SetColor(object t, Color c) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (t != null) { pTmpColor?.SetValue(t, c); } } public static void SetBold(object t, bool b) { if (t == null) { return; } try { Type type = pTmpFontStyle?.PropertyType; if (type != null) { pTmpFontStyle.SetValue(t, Enum.ToObject(type, b ? 1 : 0)); } } catch { } } public static void SetWordWrap(object t, bool on) { if (t == null || tTMP == null) { return; } try { tTMP.GetProperty("enableWordWrapping", BindingFlags.Instance | BindingFlags.Public)?.SetValue(t, on); } catch { } } public static void SetTextAutoHeight(object tmp, float minH = 0f) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (tmp == null || tLE == null) { return; } try { GameObject gameObject = ((Component)tmp).gameObject; Component val = gameObject.GetComponent(tLE); if ((Object)(object)val == (Object)null) { val = gameObject.AddComponent(tLE); } tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val, -1f); tLE.GetProperty("preferredWidth", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val, -1f); if (minH > 0f) { tLE.GetProperty("minHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val, minH); } } catch { } } public static void SetOverflowMode(object t, int mode) { if (t == null || pTmpOverflow == null) { return; } try { pTmpOverflow.SetValue(t, Enum.ToObject(pTmpOverflow.PropertyType, mode)); } catch { } } public static void SetCharSpacing(object t, float spacing) { if (t != null) { pTmpCharSpacing?.SetValue(t, spacing); } } public static void SetImageColor(GameObject go, Color c) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)go == (Object)null)) { Component component = go.GetComponent(tImage); if ((Object)(object)component != (Object)null) { pImgColor?.SetValue(component, c); } } } public static object GetButtonText(GameObject btn) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)btn == (Object)null) { return null; } foreach (Transform item in btn.transform) { Component[] components = ((Component)item).GetComponents(); foreach (Component val in components) { if (((object)val).GetType().Name == "TextMeshProUGUI") { return val; } } } return null; } } public class ClickHandler : MonoBehaviour { public Action onClick; private RectTransform rt; private Camera canvasCamera; private bool cameraResolved; private void Awake() { rt = ((Component)this).GetComponent(); } private void ResolveCamera() { cameraResolved = true; canvasCamera = null; Transform val = ((Component)this).transform; while ((Object)(object)val != (Object)null) { Component component = ((Component)val).GetComponent(UIFactory.tCanvas); if ((Object)(object)component != (Object)null) { try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; if ((int)UIFactory.tCanvas.GetProperty("renderMode", bindingAttr).GetValue(component) != 0) { ref Camera reference = ref canvasCamera; object? obj = UIFactory.tCanvas.GetProperty("worldCamera", bindingAttr)?.GetValue(component); reference = (Camera)((obj is Camera) ? obj : null); if ((Object)(object)canvasCamera == (Object)null) { canvasCamera = Camera.main; } } break; } catch { break; } } val = val.parent; } } private void Update() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00c3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rt == (Object)null || onClick == null || !((Component)this).gameObject.activeInHierarchy || !Input.GetMouseButtonDown(0)) { return; } if (!cameraResolved) { ResolveCamera(); } Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); if ((Object)(object)canvasCamera != (Object)null) { for (int i = 0; i < 4; i++) { array[i] = canvasCamera.WorldToScreenPoint(array[i]); } } Vector3 mousePosition = Input.mousePosition; if (mousePosition.x >= array[0].x && mousePosition.x <= array[2].x && mousePosition.y >= array[0].y && mousePosition.y <= array[2].y) { onClick(); } } } public static class NativeUI { public struct ChatEntry { public string Line; public DateTime AddedUtc; } private class HistoryRow { public GameObject root; public GameObject seriesGO; public object txtResult; public object txtOpp; public object txtFps; public object txtXP; public object txtDate; public object txtCards; public object txtOppCards; public object txtSeriesHead; public object txtSeriesElo; } private class LBRow { public GameObject root; public GameObject hlWrap; public object txtRank; public object txtLv; public object txtName; public object txtRating; public object txtW; public object txtL; public object txtWL; public object txtGold; public string steamId; } private class CardRow { public GameObject root; public GameObject hl; public object txtName; public object txtRarity; public object txtPicks; public object txtWins; public object txtWR; public object txtPass; public object txtTier; public GameObject tierBtn; public string cardName; } private class AchRow { public GameObject root; public object txtIcon; public object txtName; public object txtDesc; public object txtDate; } private struct CardStatTuple { public bool positive; public string amount; public string stat; } private class ShopRow { public GameObject root; public object txtName; public object txtDesc; public object txtPrice; public GameObject buyBtn; public GameObject setActiveBtn; public GameObject previewBtn; public object buyBtnTxt; public object previewBtnTxt; public long itemId; public string sku; public string previewColor; public int previewPrice; } private struct SGroup { public string series_id; public List matches; } private struct BracketRowPurpose { public bool isHeader; public string groupKey; } private class TeamLBRow { public GameObject root; public object txtRank; public object txtName; public object txtRating; public object txtWL; public object txtWR; public object txtMate; public object txtGold; public object txtXp; } private class TeamHistRow { public GameObject root; public object txtLine1; public object txtLine2; public GameObject cardsRow; public object txtCardsLeft; public object txtCardsRight; public string seriesKey; public bool isHeader; } [CompilerGenerated] private static class <>O { public static UnityAction <0>__ToggleHistoryCardMode; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__188_0; public static UnityAction <>9__188_1; public static UnityAction <>9__188_2; public static UnityAction <>9__188_3; public static UnityAction <>9__188_4; public static UnityAction <>9__189_0; public static UnityAction <>9__189_1; public static UnityAction <>9__189_2; public static UnityAction <>9__189_3; public static UnityAction <>9__189_4; public static UnityAction <>9__189_5; public static UnityAction <>9__193_0; public static Action <>9__193_5; public static UnityAction <>9__193_1; public static UnityAction <>9__193_2; public static UnityAction <>9__193_3; public static UnityAction <>9__193_4; public static UnityAction <>9__196_0; public static UnityAction <>9__196_1; public static UnityAction <>9__196_2; public static UnityAction <>9__196_3; public static UnityAction <>9__196_4; public static UnityAction <>9__196_5; public static UnityAction <>9__196_6; public static UnityAction <>9__196_7; public static UnityAction <>9__196_8; public static Action <>9__197_1; public static UnityAction <>9__198_0; public static Func <>9__207_3; public static Func <>9__207_4; public static Action <>9__207_2; public static Action <>9__252_3; public static Comparison <>9__253_0; public static Comparison <>9__253_1; public static Comparison <>9__253_2; public static Comparison <>9__253_3; public static Comparison <>9__253_4; public static Comparison <>9__253_5; public static Comparison <>9__253_6; public static Comparison <>9__253_7; public static UnityAction <>9__307_0; public static UnityAction <>9__307_1; public static UnityAction <>9__307_2; public static UnityAction <>9__307_3; public static UnityAction <>9__307_4; public static UnityAction <>9__307_5; public static UnityAction <>9__307_6; public static UnityAction <>9__307_7; public static UnityAction <>9__307_8; public static UnityAction <>9__307_9; public static UnityAction <>9__307_11; public static UnityAction <>9__307_12; public static UnityAction <>9__307_13; public static UnityAction <>9__307_14; public static UnityAction <>9__307_15; public static UnityAction <>9__307_16; public static UnityAction <>9__307_17; public static UnityAction <>9__307_18; public static UnityAction <>9__307_19; public static UnityAction <>9__307_20; public static UnityAction <>9__307_21; public static UnityAction <>9__307_22; public static Action <>9__307_25; public static UnityAction <>9__307_23; public static UnityAction <>9__307_24; public static Predicate <>9__311_0; public static Predicate <>9__311_1; public static Comparison <>9__319_0; public static Comparison <>9__319_1; public static Comparison <>9__319_2; public static Comparison <>9__319_3; public static Comparison <>9__319_4; public static Comparison <>9__319_5; public static Comparison <>9__319_6; public static Comparison <>9__319_7; public static UnityAction <>9__344_0; public static UnityAction <>9__344_1; public static UnityAction <>9__344_2; public static UnityAction <>9__344_3; public static UnityAction <>9__344_4; public static Func <>9__362_0; public static Func <>9__362_1; public static Func <>9__362_2; public static Func <>9__362_3; public static Func <>9__362_4; public static Func <>9__362_5; public static Func <>9__362_6; public static Func <>9__362_7; public static Predicate <>9__368_2; public static Predicate <>9__368_0; public static Comparison <>9__369_1; public static Comparison <>9__369_2; public static Comparison <>9__369_3; public static Comparison <>9__369_4; public static Comparison <>9__369_5; public static Comparison <>9__369_6; public static Comparison <>9__369_7; public static Comparison <>9__369_8; public static Func <>9__373_1; public static Func <>9__373_2; public static UnityAction <>9__405_0; public static UnityAction <>9__405_1; public static UnityAction <>9__405_2; public static UnityAction <>9__405_3; public static UnityAction <>9__405_4; public static UnityAction <>9__407_0; public static UnityAction <>9__407_1; public static UnityAction <>9__410_0; public static UnityAction <>9__460_0; public static UnityAction <>9__460_1; public static UnityAction <>9__460_2; public static UnityAction <>9__460_3; public static UnityAction <>9__460_4; public static UnityAction <>9__460_5; public static UnityAction <>9__460_6; public static UnityAction <>9__460_7; public static UnityAction <>9__460_8; public static UnityAction <>9__460_9; public static Comparison<(string key, int sideIdx, int round, string sideLabel)> <>9__478_1; public static Predicate <>9__478_2; public static UnityAction <>9__494_0; public static UnityAction <>9__494_1; public static UnityAction <>9__494_2; public static UnityAction <>9__494_3; public static UnityAction <>9__494_4; public static UnityAction <>9__494_5; public static UnityAction <>9__494_7; public static UnityAction <>9__494_8; internal void b__188_0() { Close(); } internal void b__188_1() { ApiClient.StartAutoUpdate(); } internal void b__188_2() { Application.OpenURL("https://discord.gg/comp-rounds"); } internal void b__188_3() { Application.OpenURL("https://github.com/SidNDeed/SidsCompetitiveRounds"); } internal void b__188_4() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= _nextManualRefreshAt) { _nextManualRefreshAt = Time.unscaledTime + 2f; RefreshData(); dirty = true; } else { CompetitiveUI.ShowNotification("Refreshing too fast - give it a sec", Color.yellow, 1.5f); } } internal void b__189_0() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.JoinQueue(localSteamId, MatchTracker.LocalDisplayName, null, rankedOnly: false); } } internal void b__189_1() { ApiClient.LeaveQueue(MatchTracker.LocalSteamId); } internal void b__189_2() { Plugin.RankedEnabled.Value = true; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ToggleRanked(localSteamId, enabled: true); } dirty = true; } internal void b__189_3() { Plugin.RankedEnabled.Value = false; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ToggleRanked(localSteamId, enabled: false); if (ApiClient.CurrentQueueState != ApiClient.QueueState.Idle) { ApiClient.LeaveQueue(localSteamId); } } dirty = true; } internal void b__189_4() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ReadyUp(localSteamId); } } internal void b__189_5() { ApiClient.DeclineMatch(MatchTracker.LocalSteamId); } internal void b__193_0() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.GenerateLinkCode(localSteamId); } } internal void b__193_5() { if (ClickGuard.Claim()) { discordRevealed = !discordRevealed; dirty = true; } } internal void b__193_1() { if (rankedPage > 0) { rankedPage--; dirty = true; } } internal void b__193_2() { rankedPage++; dirty = true; } internal void b__193_3() { if (casualPage > 0) { casualPage--; dirty = true; } } internal void b__193_4() { casualPage++; dirty = true; } internal void b__196_0() { if (liveSeriesPage > 0) { liveSeriesPage--; dirty = true; } } internal void b__196_1() { liveSeriesPage++; dirty = true; } internal void b__196_2() { if (recentSeriesPage > 0) { recentSeriesPage--; dirty = true; } } internal void b__196_3() { recentSeriesPage++; dirty = true; } internal void b__196_4() { if (lbPage > 0) { lbPage--; dirty = true; } } internal void b__196_5() { lbPage++; dirty = true; } internal void b__196_6() { if (h2hSeriesPage > 0) { h2hSeriesPage--; dirty = true; } } internal void b__196_7() { h2hSeriesPage++; dirty = true; } internal void b__196_8() { if (!string.IsNullOrEmpty(selectedSteamId) && !(selectedSteamId == MatchTracker.LocalSteamId)) { string localSteamId = MatchTracker.LocalSteamId; if (ApiClient.IsPlayerBlocked(selectedSteamId)) { ApiClient.UnblockPlayer(localSteamId, selectedSteamId); } else { ApiClient.BlockPlayer(localSteamId, selectedSteamId); } } } internal void b__197_1(ApiClient.PlayerStatsData d) { selectedStats = d; dirty = true; } internal void b__198_0() { ExportCardTierList(); } internal Type b__207_3(Assembly a) { return a.GetType("CardChoice"); } internal bool b__207_4(Type t) { return t != null; } internal void b__207_2() { if (ClickGuard.Claim()) { HideCardPreview(); } } internal void b__252_3(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] purchase complete ok={ok}"); UIFactory.SetText(txtShopStatus, ok ? "Purchased!" : ("Purchase failed: " + resp + "")); dirty = true; } internal int b__253_0(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal int b__253_1(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal int b__253_2(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { int num = a.price.CompareTo(b.price); if (num != 0) { return num; } return string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase); } internal int b__253_3(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { int num = g__rank|253_8(a.sku).CompareTo(g__rank|253_8(b.sku)); if (num != 0) { return num; } int num2 = a.price.CompareTo(b.price); if (num2 != 0) { return num2; } return string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase); } internal int b__253_4(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal int b__253_5(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal int b__253_6(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal int b__253_7(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { return a.price.CompareTo(b.price); } internal void b__307_0() { Plugin.Log.LogInfo((object)"[SETTINGS] Consent toggle clicked"); if (Plugin.DataConsentGranted) { Plugin.DataConsent.Value = "denied"; } else { Plugin.DataConsent.Value = "granted"; } ApiClient.OnConsentChanged(); dirty = true; } internal void b__307_1() { Plugin.Log.LogInfo((object)"[SETTINGS] FPS toggled"); Plugin.ShowFps.Value = !Plugin.ShowFps.Value; dirty = true; } internal void b__307_2() { Plugin.Log.LogInfo((object)"[SETTINGS] Ping/region toggled"); Plugin.ShowRegionPing.Value = !Plugin.ShowRegionPing.Value; dirty = true; } internal void b__307_3() { Plugin.Log.LogInfo((object)"[SETTINGS] In-game chat overlay toggled"); Plugin.ShowIngameChat.Value = !Plugin.ShowIngameChat.Value; dirty = true; } internal void b__307_4() { CursorColorCosmetic.CycleShape(); dirty = true; } internal void b__307_5() { Plugin.Log.LogInfo((object)"[SETTINGS] Trails toggled"); Plugin.ShowTrails.Value = !Plugin.ShowTrails.Value; if (Plugin.ShowTrails.Value) { if (GameStateWatcher.IsInMatch) { TrailCosmetic.OnMatchStart(); } } else { TrailCosmetic.OnMatchEnd(); } dirty = true; } internal void b__307_6() { Plugin.Log.LogInfo((object)"[SETTINGS] Block debug overlay toggled"); Plugin.ShowBlockDebug.Value = !Plugin.ShowBlockDebug.Value; dirty = true; } internal void b__307_7() { Plugin.Log.LogInfo((object)"[SETTINGS] Custom player colors toggled"); Plugin.ShowPlayerColors.Value = !Plugin.ShowPlayerColors.Value; try { PlayerColorCosmetic.OnShowPlayerColorsToggled(); } catch { } try { PlayerEffectCosmetic.OnShowPlayerColorsToggled(); } catch { } dirty = true; } internal void b__307_8() { Plugin.Log.LogInfo((object)"[SETTINGS] Input overlay toggled"); Plugin.ShowInputOverlay.Value = !Plugin.ShowInputOverlay.Value; dirty = true; } internal void b__307_9() { _perfSectionOpen = !_perfSectionOpen; if ((Object)(object)_perfSectionBody != (Object)null) { _perfSectionBody.SetActive(_perfSectionOpen); } dirty = true; } internal void b__307_11() { if (Plugin.PerfOptimizations != null) { Plugin.PerfOptimizations.Value = !Plugin.PerfOptimizations.Value; dirty = true; } } internal void b__307_12() { if (Plugin.PerfStunPlayerNullGuard != null) { Plugin.PerfStunPlayerNullGuard.Value = !Plugin.PerfStunPlayerNullGuard.Value; dirty = true; } } internal void b__307_13() { if (Plugin.PerfDespawnOffscreenBullets != null) { Plugin.PerfDespawnOffscreenBullets.Value = !Plugin.PerfDespawnOffscreenBullets.Value; dirty = true; } } internal void b__307_14() { if (Plugin.PerfSwallowHitSoundNREs != null) { Plugin.PerfSwallowHitSoundNREs.Value = !Plugin.PerfSwallowHitSoundNREs.Value; dirty = true; } } internal void b__307_15() { if (Plugin.PerfSwallowEdgeBounceNREs != null) { Plugin.PerfSwallowEdgeBounceNREs.Value = !Plugin.PerfSwallowEdgeBounceNREs.Value; dirty = true; } } internal void b__307_16() { if (Plugin.PerfSkipMenuUpdateInMatch != null) { Plugin.PerfSkipMenuUpdateInMatch.Value = !Plugin.PerfSkipMenuUpdateInMatch.Value; dirty = true; } } internal void b__307_17() { if (Plugin.PerfBulletHitParticleCap != null) { Plugin.PerfBulletHitParticleCap.Value = !Plugin.PerfBulletHitParticleCap.Value; dirty = true; } } internal void b__307_18() { if (Plugin.PerfClampObjectPoolInit != null) { Plugin.PerfClampObjectPoolInit.Value = !Plugin.PerfClampObjectPoolInit.Value; dirty = true; } } internal void b__307_19() { if (Plugin.PerfPauseCardPickParticles != null) { Plugin.PerfPauseCardPickParticles.Value = !Plugin.PerfPauseCardPickParticles.Value; dirty = true; } } internal void b__307_20() { Plugin.Log.LogInfo((object)"[SETTINGS] Notifications toggled"); Plugin.ShowNotifications.Value = !Plugin.ShowNotifications.Value; dirty = true; } internal void b__307_21() { CompetitiveUI.OpenBugReportModal(); } internal void b__307_22() { if (ClickGuard.Claim()) { deleteArmed = true; dirty = true; } } internal void b__307_23() { if (!ClickGuard.Claim()) { return; } string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { return; } deleteArmed = false; ApiClient.DeletePlayerData(localSteamId, delegate(bool ok, string msg) { Plugin.Log.LogInfo((object)$"[PRIVACY] Delete result: ok={ok} msg={msg}"); if (ok) { Plugin.DataConsent.Value = "denied"; ApiClient.OnConsentChanged(); if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Your data has been anonymized. Consent is now Denied."); } } else if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Deletion failed: " + msg + ""); } dirty = true; }); } internal void b__307_25(bool ok, string msg) { Plugin.Log.LogInfo((object)$"[PRIVACY] Delete result: ok={ok} msg={msg}"); if (ok) { Plugin.DataConsent.Value = "denied"; ApiClient.OnConsentChanged(); if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Your data has been anonymized. Consent is now Denied."); } } else if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Deletion failed: " + msg + ""); } dirty = true; } internal void b__307_24() { if (ClickGuard.Claim()) { deleteArmed = false; dirty = true; } } internal bool b__311_0(ApiClient.MatchHistoryEntry m) { return m.is_ranked; } internal bool b__311_1(ApiClient.MatchHistoryEntry m) { return !m.is_ranked; } internal int b__319_0(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.rank.CompareTo(b.rank); } return b.rank.CompareTo(a.rank); } internal int b__319_1(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.level.CompareTo(b.level); } return b.level.CompareTo(a.level); } internal int b__319_2(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return string.Compare(a.display_name, b.display_name, StringComparison.OrdinalIgnoreCase); } return string.Compare(b.display_name, a.display_name, StringComparison.OrdinalIgnoreCase); } internal int b__319_3(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.rating.CompareTo(b.rating); } return b.rating.CompareTo(a.rating); } internal int b__319_4(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.wins.CompareTo(b.wins); } return b.wins.CompareTo(a.wins); } internal int b__319_5(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.losses.CompareTo(b.losses); } return b.losses.CompareTo(a.losses); } internal int b__319_6(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { float value = ((a.losses > 0) ? ((float)a.wins / (float)a.losses) : ((float)a.wins * 100f)); float value2 = ((b.losses > 0) ? ((float)b.wins / (float)b.losses) : ((float)b.wins * 100f)); if (!lbSortDesc) { return value.CompareTo(value2); } return value2.CompareTo(value); } internal int b__319_7(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { if (!lbSortDesc) { return a.gold.CompareTo(b.gold); } return b.gold.CompareTo(a.gold); } internal void b__344_0() { compareSelected.Clear(); dirty = true; } internal void b__344_1() { compareSearch = ""; dirty = true; } internal void b__344_2() { compareMetric = (compareMetric - 1 + COMPARE_METRICS.Length) % COMPARE_METRICS.Length; dirty = true; } internal void b__344_3() { compareMetric = (compareMetric + 1) % COMPARE_METRICS.Length; dirty = true; } internal void b__344_4() { compareMetric = (compareMetric + 1) % COMPARE_METRICS.Length; dirty = true; } internal float b__362_0(ApiClient.PlayerStatsData ps) { if (ps.bullets_fired <= 0) { return 0f; } return (float)ps.bullets_hit * 100f / (float)ps.bullets_fired; } internal float b__362_1(ApiClient.PlayerStatsData ps) { if (ps.blocks_activated <= 0) { return 0f; } return (float)ps.blocks_successful * 100f / (float)ps.blocks_activated; } internal float b__362_2(ApiClient.PlayerStatsData ps) { return ps.avg_cards_per_game; } internal float b__362_3(ApiClient.PlayerStatsData ps) { return ps.avg_fps; } internal float b__362_4(ApiClient.PlayerStatsData ps) { return ps.peak_rating; } internal float b__362_5(ApiClient.PlayerStatsData ps) { return ps.total_xp; } internal float b__362_6(ApiClient.PlayerStatsData ps) { return ps.achievements_unlocked; } internal float b__362_7(ApiClient.PlayerStatsData ps) { return 0f; } internal bool b__368_2(SGroup g) { if (g.matches != null) { return g.matches.Count == 0; } return true; } internal bool b__368_0(ApiClient.MatchHistoryEntry m) { if (m.is_ranked && !string.IsNullOrEmpty(m.series_id)) { return m.series_id != "null"; } return false; } internal int b__369_1(ApiClient.CardStatData a, ApiClient.CardStatData b) { string value2; int value = g__TierRank|369_0(cardTierMap.TryGetValue(CardTierKey(cardFilter, a.card_name), out value2) ? value2 : ""); string value4; int value3 = g__TierRank|369_0(cardTierMap.TryGetValue(CardTierKey(cardFilter, b.card_name), out value4) ? value4 : ""); if (!cardSortDesc) { return value3.CompareTo(value); } return value.CompareTo(value3); } internal int b__369_2(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return string.Compare(a.card_name, b.card_name, StringComparison.OrdinalIgnoreCase); } return string.Compare(b.card_name, a.card_name, StringComparison.OrdinalIgnoreCase); } internal int b__369_3(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return string.Compare(a.card_rarity, b.card_rarity, StringComparison.OrdinalIgnoreCase); } return string.Compare(b.card_rarity, a.card_rarity, StringComparison.OrdinalIgnoreCase); } internal int b__369_4(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return a.times_picked.CompareTo(b.times_picked); } return b.times_picked.CompareTo(a.times_picked); } internal int b__369_5(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return a.wins_with_card.CompareTo(b.wins_with_card); } return b.wins_with_card.CompareTo(a.wins_with_card); } internal int b__369_6(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return a.win_rate.CompareTo(b.win_rate); } return b.win_rate.CompareTo(a.win_rate); } internal int b__369_7(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return a.pass_rate.CompareTo(b.pass_rate); } return b.pass_rate.CompareTo(a.pass_rate); } internal int b__369_8(ApiClient.CardStatData a, ApiClient.CardStatData b) { if (!cardSortDesc) { return a.times_picked.CompareTo(b.times_picked); } return b.times_picked.CompareTo(a.times_picked); } internal Type b__373_1(Assembly a) { return a.GetType("CardChoice"); } internal bool b__373_2(Type t) { return t != null; } internal void b__405_0() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.FetchFlaggedMatches(localSteamId); ApiClient.FetchBannedUsers(localSteamId); } } internal void b__405_1() { CompetitiveUI.OpenAdminPrompt("ban"); } internal void b__405_2() { CompetitiveUI.OpenAdminPrompt("grant"); } internal void b__405_3() { CompetitiveUI.OpenAdminPrompt("reverse"); } internal void b__405_4() { CompetitiveUI.OpenBugReportAdminViewer(); } internal void b__407_0() { } internal void b__407_1() { } internal void b__410_0() { } internal void b__460_0() { if (!(ApiClient.TournamentKind == "sync")) { ApiClient.TournamentKind = "sync"; ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId, force: true); dirty = true; } } internal void b__460_1() { if (!(ApiClient.TournamentKind == "async")) { ApiClient.TournamentKind = "async"; ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId, force: true); dirty = true; } } internal void b__460_2() { _CycleTz(); } internal void b__460_3() { _CycleDateFormat(); } internal void b__460_4() { string localSteamId = MatchTracker.LocalSteamId; ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id) && !string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.TournamentSignup(cachedTournament.tournament_id, localSteamId, MatchTracker.LocalDisplayName); } } internal void b__460_5() { string localSteamId = MatchTracker.LocalSteamId; ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id) && !string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.TournamentUnsignup(cachedTournament.tournament_id, localSteamId); } } internal void b__460_6() { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament == null || string.IsNullOrEmpty(cachedTournament.tournament_id)) { return; } List list = new List(); for (int i = 0; i < tSlotChecked.Count; i++) { int num = i; string[] time_slot_options = cachedTournament.time_slot_options; if (num >= ((time_slot_options != null) ? time_slot_options.Length : 0)) { break; } if (tSlotChecked[i]) { list.Add(cachedTournament.time_slot_options[i]); } } ApiClient.TournamentTimeVote(cachedTournament.tournament_id, MatchTracker.LocalSteamId, list.ToArray()); _tVoteLocalEdited = false; } internal void b__460_7() { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id)) { ApiClient.TournamentForceStartVote(cachedTournament.tournament_id, MatchTracker.LocalSteamId); } } internal void b__460_8() { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id)) { ApiClient.TournamentReady(cachedTournament.tournament_id, MatchTracker.LocalSteamId); } } internal void b__460_9() { //IL_0129: Unknown result type (might be due to invalid IL or missing references) ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament == null || cachedTournament.matches == null) { return; } ApiClient.TournamentMatchRow[] matches = cachedTournament.matches; foreach (ApiClient.TournamentMatchRow tournamentMatchRow in matches) { if ((tournamentMatchRow.status == "ready" || tournamentMatchRow.status == "active") && (tournamentMatchRow.p1_signup_id == cachedTournament.my_signup_id || tournamentMatchRow.p2_signup_id == cachedTournament.my_signup_id) && !string.IsNullOrEmpty(tournamentMatchRow.match_id)) { string text = ((!string.IsNullOrEmpty(tournamentMatchRow.photon_room_name)) ? tournamentMatchRow.photon_room_name : ("sct-" + tournamentMatchRow.match_id.Replace("-", "").Substring(0, 12))); _tournamentDispatchedMatches.Remove(tournamentMatchRow.match_id); Plugin.SetPendingRoom(text, cachedTournament.photon_region); CompetitiveUI.ShowNotification("Reconnecting to " + text + " (region " + (cachedTournament.photon_region ?? "default") + ")", new Color(0.5f, 0.8f, 1f)); break; } } } internal int b__478_1((string key, int sideIdx, int round, string sideLabel) a, (string key, int sideIdx, int round, string sideLabel) b) { int num = a.sideIdx.CompareTo(b.sideIdx); if (num != 0) { return num; } return a.round.CompareTo(b.round); } internal bool b__478_2(ApiClient.TournamentMatchRow mm) { if (!(mm.status == "ready")) { return mm.status == "active"; } return true; } internal void b__494_0() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"[TEAM-QUEUE-UI] Search Random clicked"); string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { Plugin.Log.LogWarning((object)("[TEAM-QUEUE-UI] LocalSteamId='" + localSteamId + "' — Steam not ready yet, ignoring click")); CompetitiveUI.ShowNotification("Steam ID not ready yet — try again in a few seconds", new Color(1f, 0.6f, 0.2f), 4f); return; } string text = ""; try { text = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { } Plugin.Log.LogInfo((object)("[TEAM-QUEUE-UI] joining auto team queue sid=" + localSteamId + " region='" + text + "'")); ApiClient.JoinTeamQueue(localSteamId, MatchTracker.LocalDisplayName, text); } internal void b__494_1() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"[TEAM-QUEUE-UI] Find Custom Lobby clicked"); string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { CompetitiveUI.ShowNotification("Steam ID not ready yet — try again in a few seconds", new Color(1f, 0.6f, 0.2f), 4f); return; } string text = ""; try { text = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { } Plugin.Log.LogInfo((object)("[TEAM-QUEUE-UI] joining manual team queue sid=" + localSteamId + " region='" + text + "'")); ApiClient.JoinTeamQueue(localSteamId, MatchTracker.LocalDisplayName, text, "manual"); } internal void b__494_2() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.LeaveTeamQueue(localSteamId); } } internal void b__494_3() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.ReadyUpTeam(localSteamId); } } internal void b__494_4() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.SetTeamPreferredTeam(localSteamId, 1); } } internal void b__494_5() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.SetTeamPreferredTeam(localSteamId, 2); } } internal void b__494_7() { teamSeriesPageReq = Math.Max(0, teamSeriesPageReq - 1); ApiClient.FetchAllSeriesPaged(teamSeriesPageReq, 10); } internal void b__494_8() { teamSeriesPageReq++; ApiClient.FetchAllSeriesPaged(teamSeriesPageReq, 10); } } private static readonly Color C_BG = new Color(0.06f, 0.07f, 0.09f, 0.96f); private static readonly Color C_PANEL = new Color(0.1f, 0.11f, 0.14f, 0.92f); private static readonly Color C_WHITE = Color.white; private static readonly Color C_SUB = new Color(0.8f, 0.85f, 1f); private static readonly Color C_LABEL = new Color(0.7f, 0.7f, 0.75f); private static readonly Color C_GOLD = new Color(1f, 0.85f, 0.3f); private static readonly Color C_BLUE = new Color(0.4f, 0.8f, 1f); private static readonly Color C_GREEN = Color.green; private static readonly Color C_RED = new Color(1f, 0.4f, 0.4f); private static readonly Color C_DIM = new Color(0.5f, 0.5f, 0.55f); private static readonly Color C_TAB = new Color(0.16f, 0.17f, 0.22f, 0.9f); private static readonly Color C_TABACT = new Color(0.22f, 0.38f, 0.65f, 0.95f); private static readonly Color C_BTN = new Color(0.18f, 0.2f, 0.26f, 0.92f); private static readonly Color C_COMMON = new Color(0.9f, 0.9f, 0.9f); private static readonly Color C_UNCOMMON = new Color(0.3f, 0.6f, 1f); private static readonly Color C_RARE = new Color(0.95f, 0.35f, 0.65f); private static GameObject pageGO; private static GameObject overlayCanvasGO; private static GameObject mainMenuGroup; private static bool isOpen; private static bool pageBuilt; private static bool dirty = true; private static bool inGameMode; private static int currentTab; private static Component listMenu; private static GameObject[] tabPanels; private static GameObject[] tabButtons; private static object[] tabTexts; private static object txtRating; private static object txtRD; private static object txtLevel; private static object txtXPProg; private static object txtTotalXP; private static object txtTopLeftName; private static Component xpFill; private static object txtRankedRec; private static object txtRankedStrk; private static object txtCasualRec; private static object txtCasualStrk; private static object txtSweeps; private static object txtTotalRec; private static object txtAccuracy; private static object txtSessionSum; private static object txtSessionSplit; private static object txtSessionSweeps; private static object txtOppSummary; private static object txtSessionOppLifetime; private static object txtTeam2v2Rec; private static object txtTeam2v2Strk; private static GameObject sessionOppContainer; private static List sessionOppTexts = new List(); private static object txtLinkCode; private static GameObject linkCodeBtn; private static bool discordRevealed = false; private static object txtChatLog; private static Component chatScrollRect; private const int CHAT_LINE_MAX_CHARS = 500; private static object txtLiveSeries; private static object txtLiveHeader; private static bool liveHeaderPulseFilled = true; private static float liveHeaderNextPulseAt; private const float LIVE_HEADER_PULSE_INTERVAL = 2.5f; private static GameObject liveBetsContainer; private static List liveBetRowPool = new List(); private static GameObject liveBetsPager; private static GameObject liveBetsPrev; private static GameObject liveBetsNext; private static object txtLiveBetsPage; private static int liveSeriesPage = 0; private const int LIVE_SERIES_PER_PAGE = 5; private static GameObject srvStatusRow; private static object txtServerStatus; private static float liveSeriesAutoRefreshAt; private static float _nextManualRefreshAt; private static List chatLines = new List(); private static readonly object chatLinesLock = new object(); private const int CHAT_LOG_MAX = 60; private static GameObject rankedContainer; private static GameObject casualContainer; private static List rankedRows = new List(); private static List casualRows = new List(); private static object txtRankedPage; private static object txtCasualPage; private static GameObject rPrev; private static GameObject rNext; private static GameObject cPrev; private static GameObject cNext; private static int rankedPage; private static int casualPage; private const string PP_CARD_NAMES_FULL = "cr_history_card_names_full"; private static bool _historyCardsFull = PlayerPrefs.GetInt("cr_history_card_names_full", 0) != 0; private static GameObject rCardModeBtn; private static GameObject cCardModeBtn; private static object rCardModeTxt; private static object cCardModeTxt; private static List lbRows = new List(); private static object txtLBCount; private static object txtLBDetail; private static string selectedSteamId = ""; private static ApiClient.PlayerStatsData selectedStats; private static List selectedViewHistory; private static int h2hSeriesPage = 0; private const int H2H_SERIES_PER_PAGE = 2; private static int h2hSeriesTotalPages = 1; private static GameObject h2hPager; private static GameObject h2hPrev; private static GameObject h2hNext; private static object txtH2hPage; private static string lbSort = "rating"; private static bool lbSortDesc = true; private static object[] lbSortTexts; private static GameObject[] lbSortBtns; private static int lbPage = 0; private static object txtLBPage; private static GameObject lbPrev; private static GameObject lbNext; private static GameObject lbBlockBtn; private static GameObject lbBlockRow; private static object lbBlockTxt; private static GameObject lbGraphPanel; private static object txtRecentSeries; private static int recentSeriesPage = 0; private static object txtSeriesPage; private static GameObject seriesPrev; private static GameObject seriesNext; private static List cardRows = new List(); private static int cardFilter; private static string cardSort = "times_picked"; private static bool cardSortDesc = true; private static object[] cardSortTexts; private static GameObject[] cardSortBtns; private static GameObject[] cardFilterBtns; private static object[] cardFilterTexts; private static List achRows = new List(); private static object txtRankedStatus; private static object txtQueueInfo; private static object txtMatchFound; private static object txtConnectLabel; private static object txtVersionStatus; private static GameObject updateBtn; private static GameObject qSearchBtn; private static GameObject qCancelBtn; private static GameObject qMatchPanel; private static GameObject readyBtn; private static GameObject declineBtn; private static GameObject connectLabel; private static GameObject rankOnBtn; private static GameObject rankOffBtn; private static object txtTournamentGame; private static GameObject tournamentIndRow; private static readonly float[] LB_COL_W = new float[8] { 40f, 40f, 250f, 88f, 56f, 56f, 69f, 76f }; private static readonly float[] CS_COL_W = new float[7] { 60f, 360f, 130f, 76f, 76f, 76f, 76f }; private static readonly string[] TIER_CYCLE = new string[8] { "", "S", "A", "B", "C", "D", "E", "F" }; private static Dictionary cardTierMap = new Dictionary(); private const float S = 1.25f; private static GameObject clickBlocker; private static float dataCheckTimer; private static int lastMatchCount = -1; private static int lastLBCount = -1; private static int lastCardCount = -1; private static float teamTabRefreshAt; private static float teamSeriesRefreshAt; public static int teamSeriesPageReq = 0; private static readonly string[] TAB_NAMES = new string[10] { "My Stats", "Leaderboard", "Card Stats", "Achievements", "Shop", "Settings", "Admin", "Tournaments", "2v2", "Compare" }; private static object txtLBPlayerName; private static readonly Dictionary CARD_DESC_FALLBACK = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "abyssalcountdown", "Stand still to summon dark powers." }, { "barrage", "Fire many bullets at the same time." }, { "bigbullet", "Bigger bullets." }, { "bigbullets", "Bigger bullets." }, { "bombsaway", "Spawn a bunch of small bombs around you when you block." }, { "brawler", "+200% HP for 3s after dealing damage." }, { "buckshot", "Adds a shotgun vibe to your attack." }, { "burst", "Multiple bullets are fired in a sequence." }, { "chase", "+60% movement when moving towards the opponent." }, { "chillingpresence", "Slightly slow nearby enemies." }, { "dazzle", "Bullets stun the opponent multiple times." }, { "decay", "Damage done to you is dealt over 4 seconds." }, { "demonicpact", "Shooting costs 10HP. Removes shooting cooldown." }, { "drillammo", "Bullets drill through walls." }, { "echo", "Blocking triggers another, delayed block." }, { "emp", "Blocking spawns a ring of slowing projectiles." }, { "empower", "Blocking increases the damage and speed of your next shot. The shot triggers any on-block abilities where it lands." }, { "explosivebullet", "Bullet explodes on impact." }, { "fastforward", "Bullets keep the default trajectory." }, { "frostslam", "Slows enemies around you when you block." }, { "grow", "Bullets get more damage over time when travelling." }, { "healingfield", "Blocking creates a healing field." }, { "homing", "Bullets home towards visible targets." }, { "implode", "Blocking pulls enemies towards you." }, { "lifestealer", "Steal HP from your opponent when near." }, { "overpower", "Deal 15% of your max HP to enemies around you when you block." }, { "parasite", "Bullets deal damage over 5 seconds." }, { "phoenix", "Respawn once on death." }, { "poison", "Bullets deal damage over 3 seconds." }, { "pristineperseverance", "+400% HP when above 90% HP." }, { "pristineperseverence", "+400% HP when above 90% HP." }, { "radarshot", "Blocking scans the area for enemies. You automatically shoot any enemy found." }, { "radiance", "Spawn damaging sun waves when reloading. The rate increases during the reload sequence." }, { "refresh", "You get block back when dealing damage." }, { "remote", "Steer bullet with right stick / mouse." }, { "ricochet", "Bullets lose half of their speed when they bounce." }, { "saw", "Blocking spawns a saw around you for a short while." }, { "scavenger", "Dealing damage reloads your weapon." }, { "shieldcharge", "Blocking launches you forward and gives you a second automatic block upon ending the charge." }, { "shieldsup", "Firing your last bullet triggers a block. Disables continuous reloading." }, { "shockwave", "Blocking pushes enemies away." }, { "silence", "Blocking silences enemies nearby." }, { "sneaky", "Bullets avoid the ground." }, { "staticfield", "Blocking creates a field that slows and deals damage." }, { "supernova", "Spawns a field that pulls enemies in and stuns after a while." }, { "tacticalreload", "Blocking reloads your weapon." }, { "targetbounce", "Bullets aim for visible targets when bouncing." }, { "tasteofblood", "+50% movement speed for 3s after dealing damage." }, { "teleport", "Blocking teleports you forward." }, { "thruster", "Bullets have thrusters that push targets." }, { "timeddetonation", "Bullets spawn bombs that explode after half a second." }, { "toxiccloud", "Bullets spawn a poison cloud on impact. Clouds deal damage and slow." }, { "trickster", "Bullets deal 80% more DMG per bounce (capped to your bounce count)." } }; private static readonly Dictionary CARD_STATS_FALLBACK = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "barrage", new CardStatTuple[4] { CST(p: true, "+4", "BULLETS"), CST(p: true, "+5", "AMMO"), CST(p: false, "-70%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "bigbullet", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "bigbullets", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "bombsaway", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "bouncy", new CardStatTuple[3] { CST(p: true, "+2", "BULLET BOUNCES"), CST(p: true, "+25%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "buckshot", new CardStatTuple[4] { CST(p: true, "+4", "BULLETS"), CST(p: true, "+5", "AMMO"), CST(p: false, "-60%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "burst", new CardStatTuple[4] { CST(p: true, "+2", "BULLETS"), CST(p: true, "+3", "AMMO"), CST(p: false, "-60%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "carefulplanning", new CardStatTuple[3] { CST(p: true, "+100%", "DAMAGE"), CST(p: false, "-150%", "ATKSPD"), CST(p: false, "+0.5s", "RELOAD") } }, { "chase", new CardStatTuple[1] { CST(p: true, "+30%", "HEALTH") } }, { "chillingpresence", new CardStatTuple[1] { CST(p: true, "+25%", "HP") } }, { "coldbullets", new CardStatTuple[2] { CST(p: true, "+70%", "BULLET SLOW"), CST(p: false, "+0.25s", "RELOAD") } }, { "combine", new CardStatTuple[3] { CST(p: true, "+100%", "DAMAGE"), CST(p: false, "-2", "AMMO"), CST(p: false, "+0.5s", "RELOAD") } }, { "dazzle", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "decay", new CardStatTuple[1] { CST(p: true, "+50%", "HP") } }, { "defender", new CardStatTuple[2] { CST(p: true, "-30%", "BLOCK CD"), CST(p: true, "+30%", "HP") } }, { "demonicpact", new CardStatTuple[3] { CST(p: true, "+9", "BULLETS"), CST(p: true, "+2", "SPLASH DMG"), CST(p: false, "+0.25s", "RELOAD") } }, { "drillammo", new CardStatTuple[2] { CST(p: true, "+7m", "DRILL"), CST(p: false, "+0.25s", "RELOAD") } }, { "echo", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "emp", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "empower", new CardStatTuple[1] { CST(p: false, "+0.25s", "BLOCK CD") } }, { "explosivebullet", new CardStatTuple[2] { CST(p: false, "-100%", "ATKSPD"), CST(p: false, "+0.25s", "RELOAD") } }, { "fastball", new CardStatTuple[3] { CST(p: true, "+250%", "BULLET SPEED"), CST(p: false, "-50%", "ATKSPD"), CST(p: false, "+0.25s", "RELOAD") } }, { "fastforward", new CardStatTuple[2] { CST(p: true, "+100%", "PROJ SPEED"), CST(p: true, "+30%", "RELOAD SPD") } }, { "frostslam", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "glasscannon", new CardStatTuple[3] { CST(p: true, "+100%", "DAMAGE"), CST(p: false, "-100%", "HP"), CST(p: false, "+0.25s", "RELOAD") } }, { "grow", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "healingfield", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "homing", new CardStatTuple[3] { CST(p: false, "-25%", "DAMAGE"), CST(p: false, "-50%", "ATKSPD"), CST(p: false, "+0.25s", "RELOAD") } }, { "huge", new CardStatTuple[1] { CST(p: true, "+80%", "HP") } }, { "implode", new CardStatTuple[2] { CST(p: true, "+50%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "leech", new CardStatTuple[2] { CST(p: true, "+75%", "LIFE STEAL"), CST(p: true, "+30%", "HP") } }, { "lifestealer", new CardStatTuple[1] { CST(p: true, "+25%", "HP") } }, { "mayhem", new CardStatTuple[3] { CST(p: true, "+5", "BULLET BOUNCES"), CST(p: false, "-15%", "DAMAGE"), CST(p: false, "+0.5s", "RELOAD") } }, { "overpower", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "parasite", new CardStatTuple[4] { CST(p: true, "+50%", "LIFE STEAL"), CST(p: true, "+25%", "HP"), CST(p: true, "+25%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "phoenix", new CardStatTuple[1] { CST(p: false, "-35%", "HP") } }, { "poison", new CardStatTuple[3] { CST(p: true, "+70%", "DAMAGE"), CST(p: true, "+30%", "RELOAD SPD"), CST(p: false, "-1", "BULLET") } }, { "quickreload", new CardStatTuple[1] { CST(p: true, "-70%", "RELOAD") } }, { "quickshot", new CardStatTuple[2] { CST(p: true, "+150%", "BULLET SPEED"), CST(p: false, "+0.25s", "RELOAD") } }, { "radarshot", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "radiance", new CardStatTuple[1] { CST(p: true, "+30%", "HP") } }, { "remote", new CardStatTuple[2] { CST(p: false, "-40%", "BULLET SPEED"), CST(p: false, "+0.25s", "RELOAD") } }, { "ricochet", new CardStatTuple[3] { CST(p: true, "+2", "BULLET BOUNCES"), CST(p: true, "+25%", "ATKSPD"), CST(p: false, "+0.25s", "RELOAD") } }, { "riccochet", new CardStatTuple[3] { CST(p: true, "+2", "BULLET BOUNCES"), CST(p: true, "+25%", "ATKSPD"), CST(p: false, "+0.25s", "RELOAD") } }, { "saw", new CardStatTuple[2] { CST(p: true, "+30%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "scavenger", new CardStatTuple[1] { CST(p: false, "+0.5s", "RELOAD") } }, { "shieldcharge", new CardStatTuple[1] { CST(p: false, "+0.25s", "BLOCK CD") } }, { "shieldsup", new CardStatTuple[2] { CST(p: false, "+0.5s", "RELOAD"), CST(p: false, "+0.5s", "BLOCK CD") } }, { "shockwave", new CardStatTuple[2] { CST(p: true, "+50%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "silence", new CardStatTuple[2] { CST(p: true, "+25%", "HP"), CST(p: false, "+0.25s", "BLOCK CD") } }, { "sneaky", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "spray", new CardStatTuple[4] { CST(p: true, "+1000%", "ATKSPD"), CST(p: true, "+12", "AMMO"), CST(p: false, "-75%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "staticfield", new CardStatTuple[1] { CST(p: false, "+0.25s", "BLOCK CD") } }, { "steadyshot", new CardStatTuple[3] { CST(p: true, "+40%", "HP"), CST(p: true, "+100%", "BULLET SPEED"), CST(p: false, "+0.25s", "RELOAD") } }, { "supernova", new CardStatTuple[2] { CST(p: true, "+50%", "HP"), CST(p: false, "+0.5s", "BLOCK CD") } }, { "tacticalreload", new CardStatTuple[1] { CST(p: false, "+0.25s", "BLOCK CD") } }, { "tank", new CardStatTuple[3] { CST(p: true, "+100%", "HP"), CST(p: false, "-25%", "ATKSPD"), CST(p: false, "+0.5s", "RELOAD") } }, { "targetbounce", new CardStatTuple[3] { CST(p: true, "+1", "BULLET BOUNCE"), CST(p: false, "-20%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "tasteofblood", new CardStatTuple[1] { CST(p: true, "+30%", "LIFE STEAL") } }, { "teleport", new CardStatTuple[1] { CST(p: true, "-30%", "BLOCK CD") } }, { "thruster", new CardStatTuple[1] { CST(p: false, "+0.25s", "RELOAD") } }, { "timeddetonation", new CardStatTuple[2] { CST(p: false, "-15%", "DAMAGE"), CST(p: false, "+0.25s", "RELOAD") } }, { "toxiccloud", new CardStatTuple[2] { CST(p: false, "-20%", "ATKSPD"), CST(p: false, "+0.5s", "RELOAD") } }, { "trickster", new CardStatTuple[3] { CST(p: true, "+2", "BULLET BOUNCES"), CST(p: false, "-20%", "DAMAGE"), CST(p: false, "+0.5s", "RELOAD") } }, { "windup", new CardStatTuple[4] { CST(p: true, "+100%", "BULLET SPEED"), CST(p: true, "+60%", "DAMAGE"), CST(p: false, "-100%", "ATKSPD"), CST(p: false, "+0.5s", "RELOAD") } } }; private static GameObject cardPreviewGO; private static object txtAchCount; private static HashSet _autoEnabledRankedForMatches = new HashSet(); private static object txtShopBalance; private static object txtShopStatus; private static GameObject shopRowsContainer; private static GameObject shopTitlesHeader; private static GameObject shopTrailsHeader; private static GameObject shopColorsHeader; private static GameObject shopNametagsHeader; private static GameObject shopPColorsHeader; private static GameObject shopCursorHeader; private static GameObject shopEffectsHeader; private static GameObject shopOtherHeader; private static int shopCategoryFilter = 0; private static GameObject[] shopTabBtns; private static object[] shopTabTexts; private static object txtShopCategoryDesc; private static readonly string[] SHOP_TAB_NAMES = new string[9] { "All", "Titles", "Trails", "Maps", "Name Styles", "Body Color", "Cursor", "Effects", "Other" }; private static readonly string[] SHOP_TAB_DESCS = new string[9] { "All cosmetics - everything available, grouped by category.", "Flair text shown next to your name on the leaderboard, match history, and in chat.", "A glowing trail that follows your character body during combat. Only visible to modded players; the shop preview shows it following your cursor.", "Map color schemes. Equip as many as you like and cycle between your owned colors with Left Shift in-game.", "Bold, italic, underline, strikethrough, and color/size modifiers applied to your player nametag in lobbies and matches. Visible to every player, modded or not.", "Override the default orange/blue team color with a tint of your choice. Only visible to modded players. Premium tiers (Prismatic, Chrome) animate during combat.", "Mouse-cursor color tint (local-only). Pick the cursor SHAPE — arrow, dot, crosshair, circle — in Settings; the tint colors whichever shape you choose.", "In-combat particle aura around your character. Only visible to modded players.", "Utility unlocks (e.g. hide your gold total on the leaderboard)." }; private static List shopRowPool = new List(); private static readonly Dictionary shopPreviewOriginalMats = new Dictionary(); private static readonly Dictionary shopPreviewGlowMatCache = new Dictionary(); private static readonly Dictionary shopPreviewOriginalFonts = new Dictionary(); private static List shopRows = new List(); private static object txtConsentStatus; private static object txtDeleteStatus; private static GameObject consentToggleBtn; private static GameObject deleteBtn; private static GameObject confirmDeleteBtn; private static GameObject cancelDelBtn; private static GameObject notifToggleBtn; private static GameObject fpsToggleBtn; private static GameObject pingToggleBtn; private static GameObject ingameChatToggleBtn; private static GameObject trailToggleBtn; private static GameObject blockDbgToggleBtn; private static GameObject playerColorToggleBtn; private static GameObject inputOverlayToggleBtn; private static GameObject cursorShapeBtn; private static object consentToggleTxt; private static object notifToggleTxt; private static object fpsToggleTxt; private static object pingToggleTxt; private static object ingameChatToggleTxt; private static object trailToggleTxt; private static object blockDbgToggleTxt; private static object playerColorToggleTxt; private static object inputOverlayToggleTxt; private static object cursorShapeTxt; private static GameObject perfMasterBtn; private static GameObject perfStunBtn; private static GameObject perfBulletsBtn; private static GameObject perfHitSndBtn; private static GameObject perfColorGhBtn; private static GameObject perfEdgeBnBtn; private static GameObject perfTagBtn; private static GameObject perfMenuBtn; private static object perfMasterTxt; private static object perfStunTxt; private static object perfBulletsTxt; private static object perfHitSndTxt; private static object perfColorGhTxt; private static object perfEdgeBnTxt; private static object perfTagTxt; private static object perfMenuTxt; private static GameObject perfBulletCapBtn; private static GameObject perfPoolBtn; private static GameObject perfCardPickBtn; private static object perfBulletCapTxt; private static object perfPoolTxt; private static object perfCardPickTxt; private static bool _perfSectionOpen = false; private static object _perfSectionHeaderTxt; private static GameObject _perfSectionBody; private static bool deleteArmed = false; private static GameObject comparePickerContent; private static GameObject compareGraphPanel; private static GameObject compareCardsScroll; private static GameObject compareCardsContent; private static object txtCompareStatus; private static object compareMetricBtnTxt; private static object txtCompareCards; private static GameObject compareMetricBtn; private static int compareMetric = 0; private static readonly string[] COMPARE_METRICS = new string[10] { "Elo over games", "Top Cards", "Worst Cards", "Hit / Block %", "Avg Cards / Game", "Avg FPS", "Peak Elo", "Total XP", "Achievements", "Region Time" }; private static string compareSearch = ""; private static object compareSearchField; private const int COMPARE_MAX = 12; private static readonly List compareSelected = new List(); private static readonly List comparePickerSteamIds = new List(); private static readonly List comparePickerRows = new List(); private static readonly List comparePickerTexts = new List(); private static readonly Dictionary compareStatsCache = new Dictionary(); private static readonly Color[] COMPARE_COLORS = (Color[])(object)new Color[12] { new Color(0.4f, 0.8f, 1f), new Color(1f, 0.5f, 0.4f), new Color(0.55f, 1f, 0.55f), new Color(1f, 0.85f, 0.3f), new Color(0.8f, 0.55f, 1f), new Color(0.4f, 0.95f, 0.9f), new Color(1f, 0.65f, 0.85f), new Color(0.7f, 0.9f, 0.45f), new Color(1f, 0.78f, 0.45f), new Color(0.6f, 0.7f, 1f), new Color(0.9f, 0.55f, 0.55f), new Color(0.65f, 0.85f, 0.75f) }; private static Sprite _pieCircleSprite; private static GameObject tierExportPanel; private static HashSet _mutedCache; private static GameObject adminFlagsContainer; private static GameObject adminBansContainer; private static object txtAdminFlagsHdr; private static object txtAdminBansHdr; private static List adminFlagRowPool = new List(); private static List adminBanRowPool = new List(); private static object txtTState; private static object txtTWhen; private static object txtTInstructions; private static object txtTPenalty; private static object txtTForceCount; private static object txtTMyMatch; private static object txtTDiscordGate; private static object txtTMyHistory; private static object txtTRoomCode; private static object txtTTzNow; private static GameObject txtTSignupBtn; private static GameObject txtTUnsignupBtn; private static GameObject txtTReadyBtn; private static GameObject txtTForceBtn; private static GameObject txtTTzButton; private static GameObject txtTDateFmtButton; private static GameObject txtTReconnectBtn; private static GameObject tSubTabSyncBtn; private static GameObject tSubTabAsyncBtn; private static GameObject tTimeVoteRow; private static GameObject tSignupList; private static GameObject tBracketList; private static GameObject tMyMatchPanel; private static GameObject tHistoryList; private static GameObject tVoteBoxPanel; private static List tHistoryRowPool = new List(); private static List tHistoryRowTexts = new List(); private static HashSet _tournamentDispatchedMatches = new HashSet(); private static List tSlotToggles = new List(); private static List tSlotChecked = new List(); private static List tSlotLabels = new List(); private static List tSignupRowPool = new List(); private static List tSignupRowTexts = new List(); private static List tBracketRowPool = new List(); private static List tBracketRowTexts = new List(); private static GameObject tBracketVisual; private static GameObject tTournBetsBox; private static GameObject tTournBetsContainer; private static object tTournBetsHeader; private static List tTournBetRowPool = new List(); private static List _tBracketRowPurposes = new List(); private static Dictionary _tBracketExpanded = new Dictionary(); private static string _tBracketSeededForTid = null; private static float tTournamentRefreshAt; private static float tReadyHeartbeatAt; private static readonly (string Label, string SystemId)[] _tzPresets = new(string, string)[12] { ("Local", ""), ("UTC", "UTC"), ("PT", "Pacific Standard Time"), ("MT", "Mountain Standard Time"), ("CT", "Central Standard Time"), ("ET", "Eastern Standard Time"), ("UK/GMT", "GMT Standard Time"), ("CET", "Central European Standard Time"), ("EET", "E. Europe Standard Time"), ("MSK", "Russian Standard Time"), ("JST", "Tokyo Standard Time"), ("AEST", "AUS Eastern Standard Time") }; private static readonly string[] _dateFormats = new string[3] { "ISO", "US", "EU" }; private static readonly CultureInfo _INV = CultureInfo.InvariantCulture; private static bool _tVoteLocalEdited = false; private const string _SYNC_INSTRUCTIONS = "HOW IT WORKS (Sync)\n 1. Sign up (Discord must be linked)\n 2. Vote on start time if you want\n 3. Keep this tab open at start time\n 4. Mod auto-connects you to your opponent - no queue, no invites\n 5. Play BO3, bracket advances automatically\n\nREADY-UP\n * Press Ready Up within 5 min of your match starting or forfeit\n * Tab open = heartbeat keeps you ready; don't alt-tab for long\n * Bracket hidden until start (no scouting your first opponent)\n\nFORMAT\n * Double-elim BO3 (first to 2) - losing once drops you to the losers bracket\n * Matches run in parallel: you play your next match the moment your opponent is ready\n * Top seeds get byes when fewer than 16 sign up\n * Grand Final: WB champ vs LB champ (bracket reset if LB wins first BO3)\n * All matches count toward ranked Elo\n\nPRIZES (16-player full tier)\n * 1st - 500g / 2500 XP / Winner role\n * 2nd - 300g / 1500 XP / Runner Up role\n * 3rd - 60g / 75 XP / 3rd Place role (loser of LB final)\n * Scaled 60% at 12-15p, 30% at 8-11p, cancelled under 8\n\nPENALTY %\n * Grows when you sign up but no-show at match time\n * Lower penalty = priority if more than 16 sign up"; private const string _ASYNC_INSTRUCTIONS = "HOW IT WORKS (Async)\n 1. Sign up any time during the 7-day signup window (Discord must be linked)\n 2. On lock, bracket is built and first-round matches activate\n 3. Coordinate with your opponent via /dm-opponent on Discord\n 4. Both of you enable Ranked, join any private lobby in ROUNDS, play the BO3\n 5. Mod records the result automatically - no manual report, no room code needed\n 6. Winner advances in bracket; loser drops to LB (or is eliminated)\n\nAUTO-RECORDING REQUIREMENTS\n * Both players must have Ranked toggled ON in-game when playing\n * Any private ROUNDS lobby works - tournament doesn't force a specific room\n * Once you hit 2 BO3 wins, the mod advances the bracket and notifies you\n\nSCHEDULING\n * No fixed start time - self-paced, 7 days per match\n * Total tournament runs up to 6-9 weeks depending on how fast matches happen\n * Miss the deadline and you forfeit that match (tracked in penalty %)\n\nFORMAT\n * Double-elim BO3 - lose once, you drop to losers bracket\n * Grand Final: WB champ vs LB champ (bracket reset if LB wins first BO3)\n * All matches count toward ranked Elo\n\nPRIZES\n * Same scaled tier as sync - 1st / 2nd / 3rd get gold + XP + trophy roles\n * 3rd place = loser of LB final\n\nPENALTY %\n * Grows when you sign up but forfeit a match by missing the 7-day deadline"; private static object txtTeamHeader; private static object txtTeamStatus; private static object txtTeamMembers; private static object txtTeamLBHeader; private static GameObject teamSearchBtn; private static GameObject teamSearchCustomBtn; private static GameObject teamLeaveBtn; private static GameObject teamReadyBtn; private static GameObject teamLBContainer; private static List teamLBRows = new List(); private static readonly int[] TLB_COL_W = new int[8] { 36, 200, 70, 80, 60, 92, 76, 88 }; private static List teamLBSortBtns; private static string[] teamLBSortKeys; private static object[] teamLBHeaderTexts; private static GameObject teamHistPrevBtn; private static GameObject teamHistNextBtn; private static object txtTeamHistPageIndicator; private static object txtTeamHistHeader; private static GameObject teamHistContainer; private static object teamHistScrollRect; private static List teamHistRows = new List(); private static Dictionary _teamSeriesExpanded = new Dictionary(); private static object txtTeamQueueListHeader; private static object txtTeamQueueListBody; private static object txtTeamQueueManualHeader; private static object txtTeamQueueManualBody; private static object txtTeamDcGrace; private static GameObject teamPickT1Btn; private static GameObject teamPickT2Btn; private static object txtPickStatus; private static GameObject teamLivePanel; private static object txtTeamLiveHeader; private static object txtTeamLiveBody; public static int CurrentTab => currentTab; public static bool IsOpen => isOpen; public static string CompareSearch { get { return compareSearch; } set { compareSearch = value ?? ""; } } internal static Type TImage => UIFactory.tImage; internal static Type TButton => UIFactory.tButton; public static void MaybeRefreshLiveSeries() { if (currentTab != 1) { return; } if (Time.unscaledTime >= liveHeaderNextPulseAt) { liveHeaderNextPulseAt = Time.unscaledTime + 2.5f; liveHeaderPulseFilled = !liveHeaderPulseFilled; dirty = true; } if (!(Time.unscaledTime < liveSeriesAutoRefreshAt)) { liveSeriesAutoRefreshAt = Time.unscaledTime + 5f; ApiClient.FetchActiveSeries(); ApiClient.FetchActiveTeamSeries(); string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.FetchMyBets(localSteamId); } } } public static ChatEntry[] SnapshotChat(int tail) { lock (chatLinesLock) { int num = Math.Max(0, chatLines.Count - tail); ChatEntry[] array = new ChatEntry[chatLines.Count - num]; for (int i = 0; i < array.Length; i++) { array[i] = chatLines[num + i]; } return array; } } private static void ToggleHistoryCardMode() { _historyCardsFull = !_historyCardsFull; PlayerPrefs.SetInt("cr_history_card_names_full", _historyCardsFull ? 1 : 0); PlayerPrefs.Save(); dirty = true; } private static string HistoryCardModeLabel() { if (!_historyCardsFull) { return "Cards: chips"; } return "Cards: FULL"; } private static string CardTierKey(int filterIdx, string cardName) { return string.Format("{0}|{1}", filterIdx, (cardName ?? "").ToLower()); } public static void Toggle() { if (isOpen) { Close(); } else { Open(); } } public static void MarkDirty() { dirty = true; } public static void SetLinkCode(string code) { if (txtLinkCode != null) { UIFactory.SetText(txtLinkCode, "" + code + " - type !link " + code + " in Discord"); } } public static void Open() { if (!UIFactory.Ready) { UIFactory.InitTypes(); UIFactory.InitFont(); } if (!UIFactory.Ready) { return; } inGameMode = GameStateWatcher.IsInRoom; EnsureOverlayCanvas(); if (!pageBuilt || (Object)(object)pageGO == (Object)null || (Object)(object)pageGO.transform.parent != (Object)(object)overlayCanvasGO.transform) { if ((Object)(object)pageGO != (Object)null) { Object.Destroy((Object)(object)pageGO); } pageBuilt = false; BuildPage(overlayCanvasGO.transform); if (!pageBuilt) { return; } } pageGO.SetActive(true); try { UIFactory.tCanvas?.GetMethod("ForceUpdateCanvases", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } catch { } isOpen = true; dirty = true; RefreshData(); ApiClient.ResetQueueCountTimer(); Plugin.Log.LogInfo((object)$"[NATIVE] Opened competitive page (inGame={inGameMode})"); } public static void Close() { if ((Object)(object)pageGO != (Object)null) { pageGO.SetActive(false); } isOpen = false; try { TrailPreview.Stop(); } catch { } SetClickBlocker(on: false); Plugin.Log.LogInfo((object)"[NATIVE] Closed competitive page"); } public static void SetClickBlocker(bool on) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_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) try { if ((Object)(object)clickBlocker == (Object)null) { if ((Object)(object)overlayCanvasGO == (Object)null) { return; } clickBlocker = new GameObject("CR_ClickBlocker"); clickBlocker.transform.SetParent(overlayCanvasGO.transform, false); RectTransform obj = clickBlocker.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; Component obj2 = clickBlocker.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, (object)new Color(0f, 0f, 0f, 0.001f)); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, true); clickBlocker.SetActive(false); } if (on) { clickBlocker.transform.SetAsLastSibling(); } if (clickBlocker.activeSelf != on) { clickBlocker.SetActive(on); } } catch { } } public static void Tick() { if (!isOpen || !pageBuilt) { return; } if ((Object)(object)pageGO == (Object)null) { isOpen = false; pageBuilt = false; return; } if (Input.GetKeyDown((KeyCode)27)) { Close(); return; } dataCheckTimer += Time.deltaTime; if (dataCheckTimer >= 0.3f) { dataCheckTimer = 0f; int num = ApiClient.CachedMatchHistory?.Count ?? 0; int valueOrDefault = (ApiClient.CachedLeaderboard?.entries?.Length).GetValueOrDefault(); int num2 = ApiClient.CachedCardStats?.Count ?? 0; if (num != lastMatchCount || valueOrDefault != lastLBCount || num2 != lastCardCount) { lastMatchCount = num; lastLBCount = valueOrDefault; lastCardCount = num2; dirty = true; } } if (dirty) { dirty = false; RefreshCurrentTab(); } MaybeRefreshTournament(); MaybeRefreshTeamTab(); } public static void MaybeRefreshTeamTab() { if (currentTab == 8 && !(Time.unscaledTime < teamTabRefreshAt)) { teamTabRefreshAt = Time.unscaledTime + 2f; ApiClient.UpdateTeamQueueList(force: true); ApiClient.UpdateTeamQueueCount(); ApiClient.FetchActiveTeamSeries(); if (Time.unscaledTime >= teamSeriesRefreshAt) { teamSeriesRefreshAt = Time.unscaledTime + 10f; ApiClient.FetchAllSeriesPaged(teamSeriesPageReq, 10); } } } private static void FindMainMenuGroup() { ListMenuButton[] array = Object.FindObjectsOfType(); Type type = null; PropertyInfo propertyInfo = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("TMPro.TMP_Text"); if (type != null) { break; } } if (type != null) { propertyInfo = type.GetProperty("text", BindingFlags.Instance | BindingFlags.Public); } ListMenuButton[] array2 = array; foreach (ListMenuButton val in array2) { if (propertyInfo == null) { break; } try { Component componentInChildren = ((Component)val).GetComponentInChildren(type, true); if ((Object)(object)componentInChildren == (Object)null || !(((propertyInfo.GetValue(componentInChildren) as string) ?? "").Trim().ToUpper() == "QUIT")) { continue; } mainMenuGroup = ((Component)((Component)val).transform.parent).gameObject; Plugin.Log.LogInfo((object)("[NATIVE] Found main menu group: " + ((Object)mainMenuGroup).name)); return; } catch { } } Plugin.Log.LogWarning((object)"[NATIVE] Could not find QUIT button"); } private static Transform FindCanvasAbove(Transform from) { Transform val = from; while ((Object)(object)val != (Object)null) { if (UIFactory.tCanvas != null && (Object)(object)((Component)val).GetComponent(UIFactory.tCanvas) != (Object)null) { Plugin.Log.LogInfo((object)("[NATIVE] Found Canvas: " + ((Object)((Component)val).gameObject).name)); return val; } val = val.parent; } return from.parent ?? from; } private static void EnsureOverlayCanvas() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)overlayCanvasGO != (Object)null) { return; } overlayCanvasGO = new GameObject("CR_OverlayCanvas"); ((Object)overlayCanvasGO).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)overlayCanvasGO); if (UIFactory.tCanvas != null) { Component obj = overlayCanvasGO.AddComponent(UIFactory.tCanvas); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; UIFactory.tCanvas.GetProperty("renderMode", bindingAttr)?.SetValue(obj, Enum.ToObject(UIFactory.tCanvas.GetProperty("renderMode", bindingAttr).PropertyType, 0)); UIFactory.tCanvas.GetProperty("sortingOrder", bindingAttr)?.SetValue(obj, 30000); } if (UIFactory.tCanvasScaler != null) { Component obj2 = overlayCanvasGO.AddComponent(UIFactory.tCanvasScaler); BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public; PropertyInfo property = UIFactory.tCanvasScaler.GetProperty("uiScaleMode", bindingAttr2); if (property != null) { property.SetValue(obj2, Enum.ToObject(property.PropertyType, 1)); } UIFactory.tCanvasScaler.GetProperty("referenceResolution", bindingAttr2)?.SetValue(obj2, (object)new Vector2(1920f, 1080f)); } if (UIFactory.tGR != null) { overlayCanvasGO.AddComponent(UIFactory.tGR); } Plugin.Log.LogInfo((object)"[NATIVE] Created persistent overlay Canvas"); } private static void BuildPage(Transform canvasParent) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_005d: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Expected O, but got Unknown //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Expected O, but got Unknown //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Expected O, but got Unknown //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06c9: Unknown result type (might be due to invalid IL or missing references) //IL_06fe: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06bf: Expected O, but got Unknown //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_076b: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Unknown result type (might be due to invalid IL or missing references) //IL_0730: Unknown result type (might be due to invalid IL or missing references) //IL_0735: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Expected O, but got Unknown //IL_07b2: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Unknown result type (might be due to invalid IL or missing references) //IL_07cc: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_0809: Expected O, but got Unknown //IL_081f: Unknown result type (might be due to invalid IL or missing references) //IL_0824: Unknown result type (might be due to invalid IL or missing references) //IL_079d: Unknown result type (might be due to invalid IL or missing references) //IL_07a2: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Expected O, but got Unknown //IL_0852: Unknown result type (might be due to invalid IL or missing references) //IL_083d: Unknown result type (might be due to invalid IL or missing references) //IL_0842: Unknown result type (might be due to invalid IL or missing references) //IL_0848: Expected O, but got Unknown try { rankedRows.Clear(); casualRows.Clear(); lbRows.Clear(); cardRows.Clear(); sessionOppTexts.Clear(); pageGO = new GameObject("CompetitiveRoundsPage"); pageGO.transform.SetParent(canvasParent, false); RectTransform obj = pageGO.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; pageGO.SetActive(false); Component component = UIFactory.CreatePanel("BG", pageGO.transform, C_BG).GetComponent(UIFactory.tImage); if ((Object)(object)component != (Object)null) { UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, true); } GameObject val = new GameObject("Content"); val.transform.SetParent(pageGO.transform, false); RectTransform obj2 = val.AddComponent(); obj2.anchorMin = Vector2.zero; obj2.anchorMax = Vector2.one; obj2.offsetMin = new Vector2(30f, 10f); obj2.offsetMax = new Vector2(-30f, -10f); UIFactory.AddVLG(val, 4f, 8, 8, 8, 8); GameObject val2 = new GameObject("TitleRow"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddHLG(val2, 8f); UIFactory.AddLE(val2, -1f, 42f, -1f, 42f, -1f, 0f); UIFactory.CreateText("Title", val2.transform, "SID'S COMPETITIVE ROUNDS", 35f, C_WHITE, 514, (Vector2?)new Vector2(0f, 42f), richText: true, raycastTarget: false); GameObject gameObject = ((Component)val2.transform.GetChild(0)).gameObject; if (UIFactory.tLE != null) { Component component2 = gameObject.GetComponent(UIFactory.tLE); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } UIFactory.AddLE(gameObject, -1f, -1f, -1f, 42f, 1f); Transform transform = val2.transform; Color c_LABEL = C_LABEL; Color c_BTN = C_BTN; object obj3 = <>c.<>9__188_0; if (obj3 == null) { UnityAction val3 = delegate { Close(); }; <>c.<>9__188_0 = val3; obj3 = (object)val3; } UIFactory.CreateButton("BackBtn", transform, "< BACK", 16f, c_LABEL, c_BTN, (UnityAction)obj3, (Vector2?)new Vector2(85f, 34f)); GameObject val4 = new GameObject("SrvRow"); val4.transform.SetParent(val.transform, false); val4.AddComponent(); UIFactory.AddHLG(val4, 6f); UIFactory.AddLE(val4, -1f, 22f, -1f, 22f, -1f, 0f); txtServerStatus = UIFactory.CreateText("SrvSt", val4.transform, "", 14f, new Color(1f, 0.7f, 0.6f), 514, (Vector2?)new Vector2(0f, 22f), richText: true, raycastTarget: false); object obj4 = txtServerStatus; object obj5 = ((obj4 is Component) ? obj4 : null); GameObject val5 = ((obj5 != null) ? ((Component)obj5).gameObject : null); if ((Object)(object)val5 != (Object)null && UIFactory.tLE != null) { Component component3 = val5.GetComponent(UIFactory.tLE); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } } if ((Object)(object)val5 != (Object)null) { UIFactory.AddLE(val5, -1f, -1f, -1f, 22f, 1f); } UIFactory.SetBold(txtServerStatus, b: true); val4.SetActive(false); srvStatusRow = val4; BuildRankedRow(val.transform); GameObject val6 = new GameObject("TournIndRow"); val6.transform.SetParent(val.transform, false); val6.AddComponent(); UIFactory.AddHLG(val6, 6f, 4); UIFactory.AddLE(val6, -1f, 22f, -1f, 22f, -1f, 0f); txtTournamentGame = UIFactory.CreateText("TGame", val6.transform, "", 15f, new Color(1f, 0.85f, 0.3f), 513, (Vector2?)new Vector2(700f, 22f), richText: true, raycastTarget: false); UIFactory.SetBold(txtTournamentGame, b: true); val6.SetActive(false); tournamentIndRow = val6; BuildTabBar(val.transform); tabPanels = (GameObject[])(object)new GameObject[10]; tabPanels[0] = BuildMyStatsTab(val.transform); tabPanels[1] = BuildLeaderboardTab(val.transform); tabPanels[2] = BuildCardStatsTab(val.transform); tabPanels[3] = BuildAchievementsTab(val.transform); tabPanels[4] = BuildShopTab(val.transform); tabPanels[5] = BuildSettingsTab(val.transform); tabPanels[6] = BuildAdminTab(val.transform); tabPanels[7] = BuildTournamentsTab(val.transform); tabPanels[8] = BuildTeamTab(val.transform); tabPanels[9] = BuildCompareTab(val.transform); GameObject val7 = new GameObject("Bottom"); val7.transform.SetParent(val.transform, false); val7.AddComponent(); UIFactory.AddHLG(val7, 8f); UIFactory.AddLE(val7, -1f, 26f, -1f, 26f, -1f, 0f); UIFactory.CreateText("Ver", val7.transform, "v1.28.2", 13f, C_DIM, 513, (Vector2?)new Vector2(90f, 22f), richText: true, raycastTarget: false); txtVersionStatus = UIFactory.CreateText("VerStatus", val7.transform, "", 12f, C_DIM, 513, (Vector2?)new Vector2(130f, 22f), richText: true, raycastTarget: false); Transform transform2 = val7.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.6f, 0.4f, 0.1f, 0.9f); object obj6 = <>c.<>9__188_1; if (obj6 == null) { UnityAction val8 = delegate { ApiClient.StartAutoUpdate(); }; <>c.<>9__188_1 = val8; obj6 = (object)val8; } updateBtn = UIFactory.CreateButton("UpdateBtn", transform2, "Update", 14f, c_WHITE, bgColor, (UnityAction)obj6, (Vector2?)new Vector2(75f, 26f)); updateBtn.SetActive(false); Transform transform3 = val7.transform; Color white = Color.white; Color bgColor2 = new Color(0.345f, 0.396f, 0.949f, 0.9f); object obj7 = <>c.<>9__188_2; if (obj7 == null) { UnityAction val9 = delegate { Application.OpenURL("https://discord.gg/comp-rounds"); }; <>c.<>9__188_2 = val9; obj7 = (object)val9; } UIFactory.CreateButton("Discord", transform3, "Discord", 14f, white, bgColor2, (UnityAction)obj7, (Vector2?)new Vector2(80f, 26f)); Transform transform4 = val7.transform; Color white2 = Color.white; Color bgColor3 = new Color(0.2f, 0.2f, 0.2f, 0.9f); object obj8 = <>c.<>9__188_3; if (obj8 == null) { UnityAction val10 = delegate { Application.OpenURL("https://github.com/SidNDeed/SidsCompetitiveRounds"); }; <>c.<>9__188_3 = val10; obj8 = (object)val10; } UIFactory.CreateButton("GitHub", transform4, "GitHub", 14f, white2, bgColor3, (UnityAction)obj8, (Vector2?)new Vector2(75f, 26f)); GameObject val11 = new GameObject("S"); val11.transform.SetParent(val7.transform, false); val11.AddComponent(); UIFactory.AddLE(val11, -1f, -1f, -1f, -1f, 1f); Transform transform5 = val7.transform; Color c_WHITE2 = C_WHITE; Color c_BTN2 = C_BTN; object obj9 = <>c.<>9__188_4; if (obj9 == null) { UnityAction val12 = delegate { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= _nextManualRefreshAt) { _nextManualRefreshAt = Time.unscaledTime + 2f; RefreshData(); dirty = true; } else { CompetitiveUI.ShowNotification("Refreshing too fast - give it a sec", Color.yellow, 1.5f); } }; <>c.<>9__188_4 = val12; obj9 = (object)val12; } UIFactory.CreateButton("RefreshBtn", transform5, "Refresh", 15f, c_WHITE2, c_BTN2, (UnityAction)obj9, (Vector2?)new Vector2(85f, 26f)); SwitchTab(0); pageBuilt = true; Plugin.Log.LogInfo((object)"[NATIVE] Competitive page built"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[NATIVE] BuildPage failed: {arg}"); pageBuilt = false; } } private static void BuildRankedRow(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Expected O, but got Unknown //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Expected O, but got Unknown //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Expected O, but got Unknown GameObject val = new GameObject("RankedRow"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 10f, 4, 4); UIFactory.AddLE(val, -1f, 26f, -1f, 26f, -1f, 0f); object t = UIFactory.CreateText("PName", val.transform, ApiClient.CachedPlayerStats?.display_name ?? MatchTracker.LocalDisplayName ?? "", 20f, C_SUB, 513, (Vector2?)new Vector2(110f, 28f), richText: true, raycastTarget: false); UIFactory.SetBold(t, b: true); txtTopLeftName = t; txtRankedStatus = UIFactory.CreateText("RS", val.transform, "RANKED: OFF", 18f, Color.gray, 513, (Vector2?)new Vector2(140f, 28f), richText: true, raycastTarget: false); UIFactory.SetBold(txtRankedStatus, b: true); Transform transform = val.transform; Color c_WHITE = C_WHITE; Color c_BTN = C_BTN; object obj = <>c.<>9__189_0; if (obj == null) { UnityAction val2 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.JoinQueue(localSteamId, MatchTracker.LocalDisplayName, null, rankedOnly: false); } }; <>c.<>9__189_0 = val2; obj = (object)val2; } qSearchBtn = UIFactory.CreateButton("Search", transform, "Search Ranked", 15f, c_WHITE, c_BTN, (UnityAction)obj, (Vector2?)new Vector2(130f, 26f)); Transform transform2 = val.transform; Color c_WHITE2 = C_WHITE; Color c_BTN2 = C_BTN; object obj2 = <>c.<>9__189_1; if (obj2 == null) { UnityAction val3 = delegate { ApiClient.LeaveQueue(MatchTracker.LocalSteamId); }; <>c.<>9__189_1 = val3; obj2 = (object)val3; } qCancelBtn = UIFactory.CreateButton("Cancel", transform2, "Cancel", 15f, c_WHITE2, c_BTN2, (UnityAction)obj2, (Vector2?)new Vector2(70f, 26f)); Transform transform3 = val.transform; Color c_GREEN = C_GREEN; Color c_BTN3 = C_BTN; object obj3 = <>c.<>9__189_2; if (obj3 == null) { UnityAction val4 = delegate { Plugin.RankedEnabled.Value = true; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ToggleRanked(localSteamId, enabled: true); } dirty = true; }; <>c.<>9__189_2 = val4; obj3 = (object)val4; } rankOnBtn = UIFactory.CreateButton("RankOn", transform3, "Enable", 15f, c_GREEN, c_BTN3, (UnityAction)obj3, (Vector2?)new Vector2(70f, 26f)); Transform transform4 = val.transform; Color c_RED = C_RED; Color c_BTN4 = C_BTN; object obj4 = <>c.<>9__189_3; if (obj4 == null) { UnityAction val5 = delegate { Plugin.RankedEnabled.Value = false; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ToggleRanked(localSteamId, enabled: false); if (ApiClient.CurrentQueueState != ApiClient.QueueState.Idle) { ApiClient.LeaveQueue(localSteamId); } } dirty = true; }; <>c.<>9__189_3 = val5; obj4 = (object)val5; } rankOffBtn = UIFactory.CreateButton("RankOff", transform4, "Disable", 15f, c_RED, c_BTN4, (UnityAction)obj4, (Vector2?)new Vector2(70f, 26f)); txtQueueInfo = UIFactory.CreateText("QI", val.transform, "", 18f, C_BLUE, 513, (Vector2?)new Vector2(340f, 28f), richText: true, raycastTarget: false); UIFactory.SetBold(txtQueueInfo, b: true); GameObject val6 = new GameObject("S"); val6.transform.SetParent(val.transform, false); val6.AddComponent(); UIFactory.AddLE(val6, -1f, -1f, -1f, -1f, 1f); qMatchPanel = new GameObject("MatchPanel"); qMatchPanel.transform.SetParent(parent, false); qMatchPanel.AddComponent(); UIFactory.AddVLG(qMatchPanel, 4f, 8); UIFactory.AddLE(qMatchPanel, -1f, 50f, -1f, 50f, -1f, 0f); txtMatchFound = UIFactory.CreateText("MF", qMatchPanel.transform, "MATCH FOUND!", 18f, C_GREEN, 513, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); UIFactory.SetBold(txtMatchFound, b: true); GameObject val7 = new GameObject("MBR"); val7.transform.SetParent(qMatchPanel.transform, false); val7.AddComponent(); UIFactory.AddHLG(val7, 8f, 0, 0, 0, 0, forceExpandW: false, forceExpandH: false); UIFactory.AddLE(val7, -1f, 26f, -1f, 26f, -1f, 0f); Transform transform5 = val7.transform; Color c_WHITE3 = C_WHITE; Color bgColor = new Color(0.2f, 0.5f, 0.2f, 0.9f); object obj5 = <>c.<>9__189_4; if (obj5 == null) { UnityAction val8 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ReadyUp(localSteamId); } }; <>c.<>9__189_4 = val8; obj5 = (object)val8; } readyBtn = UIFactory.CreateButton("Ready", transform5, "Ready Up", 15f, c_WHITE3, bgColor, (UnityAction)obj5, (Vector2?)new Vector2(90f, 24f)); txtConnectLabel = UIFactory.CreateText("CT", val7.transform, "Waiting for opponent...", 15f, C_BLUE, 513, (Vector2?)new Vector2(320f, 24f), richText: true, raycastTarget: false); object obj6 = txtConnectLabel; object obj7 = ((obj6 is Component) ? obj6 : null); connectLabel = ((obj7 != null) ? ((Component)obj7).gameObject : null); if ((Object)(object)connectLabel != (Object)null) { connectLabel.SetActive(false); } Transform transform6 = val7.transform; Color c_WHITE4 = C_WHITE; Color c_BTN5 = C_BTN; object obj8 = <>c.<>9__189_5; if (obj8 == null) { UnityAction val9 = delegate { ApiClient.DeclineMatch(MatchTracker.LocalSteamId); }; <>c.<>9__189_5 = val9; obj8 = (object)val9; } declineBtn = UIFactory.CreateButton("Decline", transform6, "Decline", 15f, c_WHITE4, c_BTN5, (UnityAction)obj8, (Vector2?)new Vector2(70f, 24f)); qMatchPanel.SetActive(false); } private static void BuildTabBar(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown GameObject val = new GameObject("TabBar"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val); UIFactory.AddLE(val, -1f, 28f, -1f, 28f, -1f, 0f); tabButtons = (GameObject[])(object)new GameObject[10]; tabTexts = new object[10]; for (int i = 0; i < 10; i++) { int idx = i; GameObject val2 = UIFactory.CreateButton($"Tab{i}", val.transform, TAB_NAMES[i], 13f, C_LABEL, C_TAB, (UnityAction)delegate { SwitchTab(idx); }, (Vector2?)new Vector2(0f, 26f)); if (UIFactory.tLE != null) { Component component = val2.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } UIFactory.AddLE(val2, -1f, 26f, -1f, 26f, 1f, 0f); tabButtons[i] = val2; tabTexts[i] = UIFactory.GetButtonText(val2); } tabButtons[6].SetActive(ApiClient.IsAdmin); } private static void SwitchTab(int idx) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) currentTab = idx; CompetitiveUI.ClearCardHoverRegions(); for (int i = 0; i < 10; i++) { if ((Object)(object)tabPanels[i] != (Object)null) { tabPanels[i].SetActive(i == idx); } UIFactory.SetImageColor(tabButtons[i], (i == idx) ? C_TABACT : C_TAB); if (tabTexts[i] != null) { UIFactory.SetColor(tabTexts[i], (i == idx) ? C_WHITE : C_LABEL); UIFactory.SetBold(tabTexts[i], i == idx); } } if (idx == 1) { if (ApiClient.CachedLeaderboard == null) { ApiClient.FetchLeaderboard(); ApiClient.FetchRecentSeries(); } ApiClient.FetchActiveSeries(); string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.FetchMyBets(localSteamId); } } if (idx == 2 && ApiClient.CachedCardStats == null) { ApiClient.FetchCardStats(200, MatchTracker.LocalSteamId); } if (idx == 3 && ApiClient.CachedAchievements == null) { string localSteamId2 = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId2) && localSteamId2 != "unknown") { ApiClient.FetchAchievements(localSteamId2); } } if (idx == 4) { string localSteamId3 = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId3) && localSteamId3 != "unknown") { ApiClient.FetchShopItems(localSteamId3); ApiClient.FetchInventory(localSteamId3); } else { ApiClient.FetchShopItems(); } } if (idx == 6) { string localSteamId4 = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId4) && ApiClient.IsAdmin) { ApiClient.FetchFlaggedMatches(localSteamId4); ApiClient.FetchBannedUsers(localSteamId4); } } if (idx == 7) { ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId, force: true); ApiClient.FetchSiteTournamentHistory(); ApiClient.FetchActiveSeries(); string localSteamId5 = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId5) && localSteamId5 != "unknown") { ApiClient.FetchPlayerTournaments(localSteamId5); ApiClient.FetchMyBets(localSteamId5); } } if (idx == 8) { if (ApiClient.CachedTeamLeaderboard == null || ApiClient.CachedTeamLeaderboard.Count == 0) { ApiClient.FetchTeamLeaderboard(); } string localSteamId6 = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId6) && localSteamId6 != "unknown") { ApiClient.FetchTeamMatchHistory(localSteamId6); } } if (idx == 9 && ApiClient.CachedLeaderboard == null) { ApiClient.FetchLeaderboard(); } dirty = true; } private static GameObject BuildMyStatsTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00b8: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown //IL_03cb: 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_0415: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0542: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_05ae: Unknown result type (might be due to invalid IL or missing references) //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06c2: Unknown result type (might be due to invalid IL or missing references) //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_0702: Unknown result type (might be due to invalid IL or missing references) //IL_0723: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_07d3: Unknown result type (might be due to invalid IL or missing references) //IL_07e7: Unknown result type (might be due to invalid IL or missing references) //IL_0813: Unknown result type (might be due to invalid IL or missing references) //IL_0827: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_0867: Unknown result type (might be due to invalid IL or missing references) //IL_08a2: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08d1: Unknown result type (might be due to invalid IL or missing references) //IL_08db: Expected O, but got Unknown //IL_091d: Unknown result type (might be due to invalid IL or missing references) //IL_0991: Unknown result type (might be due to invalid IL or missing references) //IL_09a5: Unknown result type (might be due to invalid IL or missing references) //IL_09bc: Unknown result type (might be due to invalid IL or missing references) //IL_09c3: Expected O, but got Unknown //IL_0a2c: Unknown result type (might be due to invalid IL or missing references) //IL_0a31: Unknown result type (might be due to invalid IL or missing references) //IL_0a5f: Unknown result type (might be due to invalid IL or missing references) //IL_0a89: Unknown result type (might be due to invalid IL or missing references) //IL_0a9d: Unknown result type (might be due to invalid IL or missing references) //IL_0a4a: Unknown result type (might be due to invalid IL or missing references) //IL_0a4f: Unknown result type (might be due to invalid IL or missing references) //IL_0a55: Expected O, but got Unknown //IL_0b04: Unknown result type (might be due to invalid IL or missing references) //IL_0b78: Unknown result type (might be due to invalid IL or missing references) //IL_0b8c: Unknown result type (might be due to invalid IL or missing references) //IL_0c12: Unknown result type (might be due to invalid IL or missing references) //IL_0c26: Unknown result type (might be due to invalid IL or missing references) //IL_0ca0: Unknown result type (might be due to invalid IL or missing references) //IL_0ca7: Expected O, but got Unknown //IL_0d05: Unknown result type (might be due to invalid IL or missing references) //IL_0d68: Unknown result type (might be due to invalid IL or missing references) //IL_0d7c: Unknown result type (might be due to invalid IL or missing references) //IL_0db3: Unknown result type (might be due to invalid IL or missing references) //IL_0dc7: Unknown result type (might be due to invalid IL or missing references) //IL_0e67: Unknown result type (might be due to invalid IL or missing references) //IL_0e6e: Expected O, but got Unknown //IL_0ec6: Unknown result type (might be due to invalid IL or missing references) //IL_0ecb: Unknown result type (might be due to invalid IL or missing references) //IL_0ede: Unknown result type (might be due to invalid IL or missing references) //IL_0f08: Expected O, but got Unknown //IL_0f1e: Unknown result type (might be due to invalid IL or missing references) //IL_0f23: Unknown result type (might be due to invalid IL or missing references) //IL_0f51: Unknown result type (might be due to invalid IL or missing references) //IL_0f7b: Unknown result type (might be due to invalid IL or missing references) //IL_0f8f: Unknown result type (might be due to invalid IL or missing references) //IL_0fbb: Unknown result type (might be due to invalid IL or missing references) //IL_0fc0: Unknown result type (might be due to invalid IL or missing references) //IL_0f3c: Unknown result type (might be due to invalid IL or missing references) //IL_0f41: Unknown result type (might be due to invalid IL or missing references) //IL_0f47: Expected O, but got Unknown //IL_0fee: Unknown result type (might be due to invalid IL or missing references) //IL_1007: Unknown result type (might be due to invalid IL or missing references) //IL_100c: Unknown result type (might be due to invalid IL or missing references) //IL_101f: Unknown result type (might be due to invalid IL or missing references) //IL_1049: Expected O, but got Unknown //IL_105f: Unknown result type (might be due to invalid IL or missing references) //IL_1064: Unknown result type (might be due to invalid IL or missing references) //IL_0fd9: Unknown result type (might be due to invalid IL or missing references) //IL_0fde: Unknown result type (might be due to invalid IL or missing references) //IL_0fe4: Expected O, but got Unknown //IL_108e: Unknown result type (might be due to invalid IL or missing references) //IL_10bd: Unknown result type (might be due to invalid IL or missing references) //IL_1120: Unknown result type (might be due to invalid IL or missing references) //IL_1134: Unknown result type (might be due to invalid IL or missing references) //IL_1079: Unknown result type (might be due to invalid IL or missing references) //IL_107e: Unknown result type (might be due to invalid IL or missing references) //IL_1084: Expected O, but got Unknown //IL_11d0: Unknown result type (might be due to invalid IL or missing references) //IL_11d7: Expected O, but got Unknown //IL_122f: Unknown result type (might be due to invalid IL or missing references) //IL_1234: Unknown result type (might be due to invalid IL or missing references) //IL_1247: Unknown result type (might be due to invalid IL or missing references) //IL_1271: Expected O, but got Unknown //IL_1287: Unknown result type (might be due to invalid IL or missing references) //IL_128c: Unknown result type (might be due to invalid IL or missing references) //IL_12ba: Unknown result type (might be due to invalid IL or missing references) //IL_12e4: Unknown result type (might be due to invalid IL or missing references) //IL_12f8: Unknown result type (might be due to invalid IL or missing references) //IL_1324: Unknown result type (might be due to invalid IL or missing references) //IL_1329: Unknown result type (might be due to invalid IL or missing references) //IL_12a5: Unknown result type (might be due to invalid IL or missing references) //IL_12aa: Unknown result type (might be due to invalid IL or missing references) //IL_12b0: Expected O, but got Unknown //IL_1357: Unknown result type (might be due to invalid IL or missing references) //IL_1370: Unknown result type (might be due to invalid IL or missing references) //IL_1375: Unknown result type (might be due to invalid IL or missing references) //IL_1388: Unknown result type (might be due to invalid IL or missing references) //IL_13b2: Expected O, but got Unknown //IL_13c8: Unknown result type (might be due to invalid IL or missing references) //IL_13cd: Unknown result type (might be due to invalid IL or missing references) //IL_1342: Unknown result type (might be due to invalid IL or missing references) //IL_1347: Unknown result type (might be due to invalid IL or missing references) //IL_134d: Expected O, but got Unknown //IL_13f7: Unknown result type (might be due to invalid IL or missing references) //IL_13e2: Unknown result type (might be due to invalid IL or missing references) //IL_13e7: Unknown result type (might be due to invalid IL or missing references) //IL_13ed: Expected O, but got Unknown GameObject val = new GameObject("MyStats"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 8f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("Left"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddVLG(val2, 4f); UIFactory.AddLE(val2, -1f, -1f, 380f); GameObject val3 = UIFactory.CreatePanel("RB", val2.transform, C_PANEL); UIFactory.AddVLG(val3, 2f, 10, 10, 6, 6); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.SetCharSpacing(UIFactory.CreateText("RL", val3.transform, "Glicko-2 Rating", 19f, C_SUB, 257, (Vector2?)new Vector2(250f, 28f), richText: true, raycastTarget: false), 1f); GameObject val4 = new GameObject("RR"); val4.transform.SetParent(val3.transform, false); val4.AddComponent(); UIFactory.AddHLG(val4, 12f); UIFactory.AddLE(val4, -1f, -1f, -1f, 38f); txtRating = UIFactory.CreateText("Rat", val4.transform, "1500", 30f, C_WHITE, 513, (Vector2?)new Vector2(110f, 38f), richText: true, raycastTarget: false); UIFactory.SetBold(txtRating, b: true); txtRD = UIFactory.CreateText("RD", val4.transform, "RD: 350", 18f, C_LABEL, 513, (Vector2?)new Vector2(240f, 38f), richText: true, raycastTarget: false); GameObject val5 = UIFactory.CreatePanel("XB", val2.transform, C_PANEL); UIFactory.AddVLG(val5, 2f, 10, 10, 6, 6); UIFactory.AddLE(val5, -1f, -1f, -1f, -1f, -1f, 0f); GameObject val6 = new GameObject("LR"); val6.transform.SetParent(val5.transform, false); val6.AddComponent(); UIFactory.AddHLG(val6, 8f); UIFactory.AddLE(val6, -1f, -1f, -1f, 28f); txtLevel = UIFactory.CreateText("Lv", val6.transform, "Level 1", 19f, C_BLUE, 513, (Vector2?)new Vector2(100f, 28f), richText: true, raycastTarget: false); UIFactory.SetBold(txtLevel, b: true); txtXPProg = UIFactory.CreateText("XPP", val6.transform, "", 16f, C_LABEL, 513, (Vector2?)new Vector2(130f, 28f), richText: true, raycastTarget: false); GameObject val7 = new GameObject("S"); val7.transform.SetParent(val6.transform, false); val7.AddComponent(); UIFactory.AddLE(val7, -1f, -1f, -1f, -1f, 1f); txtTotalXP = UIFactory.CreateText("TXP", val6.transform, "0 XP", 16f, C_LABEL, 516, (Vector2?)new Vector2(110f, 28f), richText: true, raycastTarget: false); xpFill = UIFactory.CreateFillBar("XP", val5.transform, new Color(0.2f, 0.2f, 0.25f, 0.8f), new Color(0.3f, 0.7f, 1f, 0.9f), 10f); GameObject val8 = UIFactory.CreatePanel("RecB", val2.transform, C_PANEL); UIFactory.AddVLG(val8, 1f, 10, 10, 6, 6); UIFactory.AddLE(val8, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("RecL", val8.transform, "Record", 19f, C_SUB, 257, (Vector2?)new Vector2(340f, 28f), richText: true, raycastTarget: false); txtRankedRec = UIFactory.CreateText("RR", val8.transform, "", 16f, C_WHITE, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtRankedStrk = UIFactory.CreateText("RS", val8.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false); txtTeam2v2Rec = UIFactory.CreateText("T2", val8.transform, "", 16f, C_WHITE, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtTeam2v2Strk = UIFactory.CreateText("T2S", val8.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false); txtCasualRec = UIFactory.CreateText("CR", val8.transform, "", 16f, C_WHITE, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtCasualStrk = UIFactory.CreateText("CS", val8.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false); txtSweeps = UIFactory.CreateText("SW", val8.transform, "", 16f, C_WHITE, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtTotalRec = UIFactory.CreateText("TR", val8.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false); txtAccuracy = UIFactory.CreateText("AC", val8.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 44f), richText: true, raycastTarget: false); GameObject val9 = UIFactory.CreatePanel("SB", val2.transform, C_PANEL); UIFactory.AddVLG(val9, 3f, 10, 10, 8, 8); UIFactory.AddLE(val9, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SL", val9.transform, "Session Info", 19f, new Color(0.7f, 0.8f, 1f), 257, (Vector2?)new Vector2(340f, 28f), richText: true, raycastTarget: false); txtSessionSum = UIFactory.CreateText("SS", val9.transform, "No games this session", 17f, C_DIM, 257, (Vector2?)new Vector2(340f, 26f), richText: true, raycastTarget: false); txtSessionSplit = UIFactory.CreateText("SSp", val9.transform, "", 16f, C_LABEL, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtSessionSweeps = UIFactory.CreateText("SSw", val9.transform, "", 16f, C_WHITE, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); txtSessionOppLifetime = UIFactory.CreateText("SOL", val9.transform, "", 15f, new Color(0.6f, 0.75f, 1f), 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false); sessionOppContainer = new GameObject("SOC"); sessionOppContainer.transform.SetParent(val9.transform, false); sessionOppContainer.AddComponent(); UIFactory.AddVLG(sessionOppContainer, 1f); GameObject val10 = UIFactory.CreatePanel("LkB", val2.transform, C_PANEL); UIFactory.AddVLG(val10, 4f, 10, 10, 6, 6); UIFactory.AddLE(val10, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("LkL", val10.transform, "Discord Link", 19f, new Color(0.55f, 0.55f, 0.95f), 257, (Vector2?)new Vector2(340f, 28f), richText: true, raycastTarget: false); GameObject val11 = new GameObject("LkR"); val11.transform.SetParent(val10.transform, false); val11.AddComponent(); UIFactory.AddHLG(val11, 8f); UIFactory.AddLE(val11, -1f, -1f, -1f, 28f); Transform transform = val11.transform; Color c_WHITE = C_WHITE; Color c_BTN = C_BTN; object obj = <>c.<>9__193_0; if (obj == null) { UnityAction val12 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.GenerateLinkCode(localSteamId); } }; <>c.<>9__193_0 = val12; obj = (object)val12; } linkCodeBtn = UIFactory.CreateButton("LkBtn", transform, "Get Link Code", 15f, c_WHITE, c_BTN, (UnityAction)obj, (Vector2?)new Vector2(130f, 26f)); txtLinkCode = UIFactory.CreateText("LkC", val11.transform, "Type !link CODE in Discord", 15f, C_DIM, 257, (Vector2?)new Vector2(240f, 26f), richText: true, raycastTarget: true); object obj2 = txtLinkCode; Component val13 = (Component)((obj2 is Component) ? obj2 : null); if ((Object)(object)val13 != (Object)null) { val13.gameObject.AddComponent().onClick = delegate { if (ClickGuard.Claim()) { discordRevealed = !discordRevealed; dirty = true; } }; } GameObject val14 = UIFactory.CreatePanel("CB", val2.transform, C_PANEL); UIFactory.AddVLG(val14, 4f, 10, 10, 6, 6); UIFactory.AddLE(val14, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("CH", val14.transform, "Chat (press T to send)", 17f, new Color(0.7f, 0.85f, 1f), 257, (Vector2?)new Vector2(340f, 26f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("ChSV", val14.transform, 0f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, 160f, -1f, 160f, -1f, 0f); chatScrollRect = scrollViewRefs.scrollGO.GetComponent(UIFactory.tScrollRect); txtChatLog = UIFactory.CreateText("ChLog", scrollViewRefs.content.transform, "No messages yet. Anyone chatting here or in #scr-discussion on Discord will appear.", 14f, C_WHITE, 257, (Vector2?)new Vector2(360f, 400f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtChatLog, on: true); object obj3 = txtChatLog; object obj4 = ((obj3 is Component) ? obj3 : null); Component val15 = ((obj4 != null) ? ((Component)obj4).gameObject.GetComponent(UIFactory.tLE) : null); if ((Object)(object)val15 != (Object)null) { UIFactory.tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val15, -1f); } GameObject val16 = new GameObject("Right"); val16.transform.SetParent(val.transform, false); val16.AddComponent(); UIFactory.AddVLG(val16, 4f); UIFactory.AddLE(val16, -1f, -1f, -1f, -1f, 1f, 1f); GameObject val17 = UIFactory.CreatePanel("RkB", val16.transform, C_PANEL); UIFactory.AddVLG(val17, 1f, 8, 8, 6, 6); UIFactory.AddLE(val17, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("RkH", val17.transform, "Ranked History", 21f, C_GOLD, 257, (Vector2?)new Vector2(250f, 30f), richText: true, raycastTarget: false); txtOppSummary = UIFactory.CreateText("OS", val17.transform, "", 15f, new Color(0.7f, 0.8f, 1f), 257, (Vector2?)new Vector2(500f, 22f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("RkSV", val17.transform, 1f); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); rankedContainer = scrollViewRefs2.content; for (int num = 0; num < 15; num++) { rankedRows.Add(CreateHistoryRow(rankedContainer.transform, $"rr{num}")); } GameObject val18 = new GameObject("RPg"); val18.transform.SetParent(val17.transform, false); val18.AddComponent(); UIFactory.AddHLG(val18, 6f); UIFactory.AddLE(val18, -1f, -1f, -1f, 20f, -1f, 0f); GameObject val19 = new GameObject("S"); val19.transform.SetParent(val18.transform, false); val19.AddComponent(); UIFactory.AddLE(val19, -1f, -1f, -1f, -1f, 1f); Transform transform2 = val18.transform; Color c_LABEL = C_LABEL; Color c_BTN2 = C_BTN; object obj5 = <>c.<>9__193_1; if (obj5 == null) { UnityAction val20 = delegate { if (rankedPage > 0) { rankedPage--; dirty = true; } }; <>c.<>9__193_1 = val20; obj5 = (object)val20; } rPrev = UIFactory.CreateButton("rP", transform2, "< Prev", 10f, c_LABEL, c_BTN2, (UnityAction)obj5, (Vector2?)new Vector2(50f, 18f)); txtRankedPage = UIFactory.CreateText("rPI", val18.transform, "", 10f, C_LABEL, 514, (Vector2?)new Vector2(35f, 18f), richText: true, raycastTarget: false); Transform transform3 = val18.transform; Color c_LABEL2 = C_LABEL; Color c_BTN3 = C_BTN; object obj6 = <>c.<>9__193_2; if (obj6 == null) { UnityAction val21 = delegate { rankedPage++; dirty = true; }; <>c.<>9__193_2 = val21; obj6 = (object)val21; } rNext = UIFactory.CreateButton("rN", transform3, "Next >", 10f, c_LABEL2, c_BTN3, (UnityAction)obj6, (Vector2?)new Vector2(50f, 18f)); GameObject val22 = new GameObject("S"); val22.transform.SetParent(val18.transform, false); val22.AddComponent(); UIFactory.AddLE(val22, -1f, -1f, -1f, -1f, 1f); Transform transform4 = val18.transform; Color c_LABEL3 = C_LABEL; Color c_BTN4 = C_BTN; object obj7 = <>O.<0>__ToggleHistoryCardMode; if (obj7 == null) { UnityAction val23 = ToggleHistoryCardMode; <>O.<0>__ToggleHistoryCardMode = val23; obj7 = (object)val23; } rCardModeBtn = UIFactory.CreateButton("rCm", transform4, "", 10f, c_LABEL3, c_BTN4, (UnityAction)obj7, (Vector2?)new Vector2(100f, 18f)); rCardModeTxt = UIFactory.GetButtonText(rCardModeBtn); GameObject val24 = UIFactory.CreatePanel("CsB", val16.transform, C_PANEL); UIFactory.AddVLG(val24, 1f, 8, 8, 6, 6); UIFactory.AddLE(val24, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("CsH", val24.transform, "Casual History", 21f, C_SUB, 257, (Vector2?)new Vector2(250f, 30f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs3 = UIFactory.CreateScrollView("CsSV", val24.transform, 1f); UIFactory.AddLE(scrollViewRefs3.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); casualContainer = scrollViewRefs3.content; for (int num2 = 0; num2 < 12; num2++) { casualRows.Add(CreateHistoryRow(casualContainer.transform, $"cr{num2}")); } GameObject val25 = new GameObject("CPg"); val25.transform.SetParent(val24.transform, false); val25.AddComponent(); UIFactory.AddHLG(val25, 6f); UIFactory.AddLE(val25, -1f, -1f, -1f, 20f, -1f, 0f); GameObject val26 = new GameObject("S"); val26.transform.SetParent(val25.transform, false); val26.AddComponent(); UIFactory.AddLE(val26, -1f, -1f, -1f, -1f, 1f); Transform transform5 = val25.transform; Color c_LABEL4 = C_LABEL; Color c_BTN5 = C_BTN; object obj8 = <>c.<>9__193_3; if (obj8 == null) { UnityAction val27 = delegate { if (casualPage > 0) { casualPage--; dirty = true; } }; <>c.<>9__193_3 = val27; obj8 = (object)val27; } cPrev = UIFactory.CreateButton("cP", transform5, "< Prev", 10f, c_LABEL4, c_BTN5, (UnityAction)obj8, (Vector2?)new Vector2(50f, 18f)); txtCasualPage = UIFactory.CreateText("cPI", val25.transform, "", 10f, C_LABEL, 514, (Vector2?)new Vector2(35f, 18f), richText: true, raycastTarget: false); Transform transform6 = val25.transform; Color c_LABEL5 = C_LABEL; Color c_BTN6 = C_BTN; object obj9 = <>c.<>9__193_4; if (obj9 == null) { UnityAction val28 = delegate { casualPage++; dirty = true; }; <>c.<>9__193_4 = val28; obj9 = (object)val28; } cNext = UIFactory.CreateButton("cN", transform6, "Next >", 10f, c_LABEL5, c_BTN6, (UnityAction)obj9, (Vector2?)new Vector2(50f, 18f)); GameObject val29 = new GameObject("S"); val29.transform.SetParent(val25.transform, false); val29.AddComponent(); UIFactory.AddLE(val29, -1f, -1f, -1f, -1f, 1f); Transform transform7 = val25.transform; Color c_LABEL6 = C_LABEL; Color c_BTN7 = C_BTN; object obj10 = <>O.<0>__ToggleHistoryCardMode; if (obj10 == null) { UnityAction val30 = ToggleHistoryCardMode; <>O.<0>__ToggleHistoryCardMode = val30; obj10 = (object)val30; } cCardModeBtn = UIFactory.CreateButton("cCm", transform7, "", 10f, c_LABEL6, c_BTN7, (UnityAction)obj10, (Vector2?)new Vector2(100f, 18f)); cCardModeTxt = UIFactory.GetButtonText(cCardModeBtn); return val; } private static HistoryRow CreateHistoryRow(Transform parent, string name) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_011b: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Expected O, but got Unknown //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) HistoryRow historyRow = new HistoryRow(); historyRow.seriesGO = new GameObject(name + "s"); historyRow.seriesGO.transform.SetParent(parent, false); historyRow.seriesGO.AddComponent(); UIFactory.AddHLG(historyRow.seriesGO, 4f, 4); UIFactory.AddLE(historyRow.seriesGO, -1f, -1f, -1f, 25f); historyRow.txtSeriesHead = UIFactory.CreateText("sh", historyRow.seriesGO.transform, "", 19f, C_GREEN, 257, (Vector2?)new Vector2(500f, 25f), richText: true, raycastTarget: false); historyRow.txtSeriesElo = UIFactory.CreateText("se", historyRow.seriesGO.transform, "", 19f, C_GREEN, 516, (Vector2?)new Vector2(160f, 25f), richText: true, raycastTarget: false); historyRow.seriesGO.SetActive(false); historyRow.root = new GameObject(name); historyRow.root.transform.SetParent(parent, false); historyRow.root.AddComponent(); UIFactory.AddVLG(historyRow.root, 0f, 4); GameObject val = new GameObject("m"); val.transform.SetParent(historyRow.root.transform, false); val.AddComponent(); UIFactory.AddHLG(val); UIFactory.AddLE(val, -1f, -1f, -1f, 25f); historyRow.txtResult = UIFactory.CreateText("r", val.transform, "", 19f, C_GREEN, 513, (Vector2?)new Vector2(200f, 25f), richText: true, raycastTarget: false); historyRow.txtOpp = UIFactory.CreateText("o", val.transform, "", 18f, C_WHITE, 513, (Vector2?)new Vector2(240f, 25f), richText: true, raycastTarget: false); historyRow.txtFps = UIFactory.CreateText("fp", val.transform, "", 14f, C_LABEL, 513, (Vector2?)new Vector2(140f, 25f), richText: true, raycastTarget: false); GameObject val2 = new GameObject("S"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddLE(val2, -1f, -1f, -1f, -1f, 1f); historyRow.txtXP = UIFactory.CreateText("x", val.transform, "", 16f, C_BLUE, 516, (Vector2?)new Vector2(65f, 25f), richText: true, raycastTarget: false); historyRow.txtDate = UIFactory.CreateText("d", val.transform, "", 15f, C_DIM, 516, (Vector2?)new Vector2(45f, 25f), richText: true, raycastTarget: false); historyRow.txtCards = UIFactory.CreateText("c", historyRow.root.transform, "", 19f, new Color(0.6f, 0.7f, 0.9f), 257, (Vector2?)new Vector2(900f, 25f), richText: true, raycastTarget: false); UIFactory.SetCharSpacing(historyRow.txtCards, 1.5f); historyRow.txtOppCards = UIFactory.CreateText("oc", historyRow.root.transform, "", 19f, new Color(0.9f, 0.6f, 0.5f), 257, (Vector2?)new Vector2(900f, 25f), richText: true, raycastTarget: false); UIFactory.SetCharSpacing(historyRow.txtOppCards, 1.5f); historyRow.root.SetActive(false); return historyRow; } private static GameObject BuildLeaderboardTab(Transform parent) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0065: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_0d59: Unknown result type (might be due to invalid IL or missing references) //IL_0d63: Expected O, but got Unknown //IL_0ddb: Unknown result type (might be due to invalid IL or missing references) //IL_0def: Unknown result type (might be due to invalid IL or missing references) //IL_0e06: Unknown result type (might be due to invalid IL or missing references) //IL_0e0b: Unknown result type (might be due to invalid IL or missing references) //IL_0e21: Unknown result type (might be due to invalid IL or missing references) //IL_0e4b: Expected O, but got Unknown //IL_0e64: Unknown result type (might be due to invalid IL or missing references) //IL_0e69: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Expected O, but got Unknown //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Expected O, but got Unknown //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Expected O, but got Unknown //IL_0e97: Unknown result type (might be due to invalid IL or missing references) //IL_0ec4: Unknown result type (might be due to invalid IL or missing references) //IL_0ed8: Unknown result type (might be due to invalid IL or missing references) //IL_0f07: Unknown result type (might be due to invalid IL or missing references) //IL_0f0c: Unknown result type (might be due to invalid IL or missing references) //IL_0e82: Unknown result type (might be due to invalid IL or missing references) //IL_0e87: Unknown result type (might be due to invalid IL or missing references) //IL_0e8d: Expected O, but got Unknown //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Expected O, but got Unknown //IL_0f3a: Unknown result type (might be due to invalid IL or missing references) //IL_0fb7: Unknown result type (might be due to invalid IL or missing references) //IL_0fcb: Unknown result type (might be due to invalid IL or missing references) //IL_1011: Unknown result type (might be due to invalid IL or missing references) //IL_1025: Unknown result type (might be due to invalid IL or missing references) //IL_103c: Unknown result type (might be due to invalid IL or missing references) //IL_1046: Expected O, but got Unknown //IL_10be: Unknown result type (might be due to invalid IL or missing references) //IL_10d7: Unknown result type (might be due to invalid IL or missing references) //IL_0f25: Unknown result type (might be due to invalid IL or missing references) //IL_0f2a: Unknown result type (might be due to invalid IL or missing references) //IL_0f30: Expected O, but got Unknown //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Expected O, but got Unknown //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Expected O, but got Unknown //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06e1: Expected O, but got Unknown //IL_0755: Unknown result type (might be due to invalid IL or missing references) //IL_075a: Unknown result type (might be due to invalid IL or missing references) //IL_076d: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Expected O, but got Unknown //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Expected O, but got Unknown //IL_1105: Unknown result type (might be due to invalid IL or missing references) //IL_111e: Unknown result type (might be due to invalid IL or missing references) //IL_1123: Unknown result type (might be due to invalid IL or missing references) //IL_1139: Unknown result type (might be due to invalid IL or missing references) //IL_1163: Expected O, but got Unknown //IL_10f0: Unknown result type (might be due to invalid IL or missing references) //IL_10f5: Unknown result type (might be due to invalid IL or missing references) //IL_10fb: Expected O, but got Unknown //IL_0913: Unknown result type (might be due to invalid IL or missing references) //IL_0918: Unknown result type (might be due to invalid IL or missing references) //IL_092b: Unknown result type (might be due to invalid IL or missing references) //IL_0955: Expected O, but got Unknown //IL_09dc: Unknown result type (might be due to invalid IL or missing references) //IL_09e3: Expected O, but got Unknown //IL_0a4c: Unknown result type (might be due to invalid IL or missing references) //IL_0a60: Unknown result type (might be due to invalid IL or missing references) //IL_0a7b: Unknown result type (might be due to invalid IL or missing references) //IL_0a80: Unknown result type (might be due to invalid IL or missing references) //IL_0a93: Unknown result type (might be due to invalid IL or missing references) //IL_0abd: Expected O, but got Unknown //IL_0ad3: Unknown result type (might be due to invalid IL or missing references) //IL_0ad8: Unknown result type (might be due to invalid IL or missing references) //IL_0839: Unknown result type (might be due to invalid IL or missing references) //IL_0832: Unknown result type (might be due to invalid IL or missing references) //IL_0b06: Unknown result type (might be due to invalid IL or missing references) //IL_0b30: Unknown result type (might be due to invalid IL or missing references) //IL_0b44: Unknown result type (might be due to invalid IL or missing references) //IL_0b70: Unknown result type (might be due to invalid IL or missing references) //IL_0b75: Unknown result type (might be due to invalid IL or missing references) //IL_0af1: Unknown result type (might be due to invalid IL or missing references) //IL_0af6: Unknown result type (might be due to invalid IL or missing references) //IL_0afc: Expected O, but got Unknown //IL_0ba3: Unknown result type (might be due to invalid IL or missing references) //IL_0bc2: Unknown result type (might be due to invalid IL or missing references) //IL_0c27: Unknown result type (might be due to invalid IL or missing references) //IL_0c3b: Unknown result type (might be due to invalid IL or missing references) //IL_0c61: Unknown result type (might be due to invalid IL or missing references) //IL_0c6b: Expected O, but got Unknown //IL_0b8e: Unknown result type (might be due to invalid IL or missing references) //IL_0b93: Unknown result type (might be due to invalid IL or missing references) //IL_0b99: Expected O, but got Unknown //IL_0860: Unknown result type (might be due to invalid IL or missing references) //IL_0859: Unknown result type (might be due to invalid IL or missing references) //IL_0cf3: Unknown result type (might be due to invalid IL or missing references) //IL_086d: Unknown result type (might be due to invalid IL or missing references) //IL_087f: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Expected O, but got Unknown GameObject val = new GameObject("Leaderboard"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 6f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = UIFactory.CreatePanel("LBSeries", val.transform, C_PANEL); UIFactory.AddVLG(val2, 2f, 8, 8, 6, 6); UIFactory.AddLE(val2, 340f, -1f, 400f, -1f, -1f, 1f); txtLiveHeader = UIFactory.CreateText("RSL", val2.transform, "* Live Ranked Games", 17f, C_WHITE, 513, (Vector2?)new Vector2(280f, 26f), richText: true, raycastTarget: false); txtLiveSeries = UIFactory.CreateText("LIVE", val2.transform, "No live games right now.", 13f, C_WHITE, 257, (Vector2?)new Vector2(280f, 24f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtLiveSeries, on: true); liveBetsContainer = new GameObject("LiveBets"); liveBetsContainer.transform.SetParent(val2.transform, false); liveBetsContainer.AddComponent(); UIFactory.AddVLG(liveBetsContainer); liveBetsPager = new GameObject("LivePg"); liveBetsPager.transform.SetParent(val2.transform, false); liveBetsPager.AddComponent(); UIFactory.AddHLG(liveBetsPager); UIFactory.AddLE(liveBetsPager, -1f, -1f, -1f, 18f, -1f, 0f); Transform transform = liveBetsPager.transform; Color c_LABEL = C_LABEL; Color c_BTN = C_BTN; object obj = <>c.<>9__196_0; if (obj == null) { UnityAction val3 = delegate { if (liveSeriesPage > 0) { liveSeriesPage--; dirty = true; } }; <>c.<>9__196_0 = val3; obj = (object)val3; } liveBetsPrev = UIFactory.CreateButton("lvP", transform, "< Prev", 10f, c_LABEL, c_BTN, (UnityAction)obj, (Vector2?)new Vector2(50f, 18f)); txtLiveBetsPage = UIFactory.CreateText("lvPI", liveBetsPager.transform, "", 10f, C_LABEL, 514, (Vector2?)new Vector2(80f, 18f), richText: true, raycastTarget: false); Transform transform2 = liveBetsPager.transform; Color c_LABEL2 = C_LABEL; Color c_BTN2 = C_BTN; object obj2 = <>c.<>9__196_1; if (obj2 == null) { UnityAction val4 = delegate { liveSeriesPage++; dirty = true; }; <>c.<>9__196_1 = val4; obj2 = (object)val4; } liveBetsNext = UIFactory.CreateButton("lvN", transform2, "Next >", 10f, c_LABEL2, c_BTN2, (UnityAction)obj2, (Vector2?)new Vector2(50f, 18f)); liveBetsPager.SetActive(false); GameObject val5 = new GameObject("LRSp"); val5.transform.SetParent(val2.transform, false); val5.AddComponent(); UIFactory.AddLE(val5, -1f, 18f, -1f, 18f, -1f, 0f); UIFactory.CreateText("RSL", val2.transform, "Recent Ranked Series", 17f, C_WHITE, 513, (Vector2?)new Vector2(280f, 26f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("RSSV", val2.transform, 1f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); txtRecentSeries = UIFactory.CreateText("RST", scrollViewRefs.content.transform, "Loading...", 16f, C_DIM, 257, (Vector2?)new Vector2(280f, 20f), richText: true, raycastTarget: false); GameObject val6 = new GameObject("SPg"); val6.transform.SetParent(val2.transform, false); val6.AddComponent(); UIFactory.AddHLG(val6); UIFactory.AddLE(val6, -1f, -1f, -1f, 20f, -1f, 0f); GameObject val7 = new GameObject("S"); val7.transform.SetParent(val6.transform, false); val7.AddComponent(); UIFactory.AddLE(val7, -1f, -1f, -1f, -1f, 1f); Transform transform3 = val6.transform; Color c_LABEL3 = C_LABEL; Color c_BTN3 = C_BTN; object obj3 = <>c.<>9__196_2; if (obj3 == null) { UnityAction val8 = delegate { if (recentSeriesPage > 0) { recentSeriesPage--; dirty = true; } }; <>c.<>9__196_2 = val8; obj3 = (object)val8; } seriesPrev = UIFactory.CreateButton("sP", transform3, "< Prev", 10f, c_LABEL3, c_BTN3, (UnityAction)obj3, (Vector2?)new Vector2(50f, 18f)); txtSeriesPage = UIFactory.CreateText("sPI", val6.transform, "", 10f, C_LABEL, 514, (Vector2?)new Vector2(35f, 18f), richText: true, raycastTarget: false); Transform transform4 = val6.transform; Color c_LABEL4 = C_LABEL; Color c_BTN4 = C_BTN; object obj4 = <>c.<>9__196_3; if (obj4 == null) { UnityAction val9 = delegate { recentSeriesPage++; dirty = true; }; <>c.<>9__196_3 = val9; obj4 = (object)val9; } seriesNext = UIFactory.CreateButton("sN", transform4, "Next >", 10f, c_LABEL4, c_BTN4, (UnityAction)obj4, (Vector2?)new Vector2(50f, 18f)); GameObject val10 = new GameObject("S"); val10.transform.SetParent(val6.transform, false); val10.AddComponent(); UIFactory.AddLE(val10, -1f, -1f, -1f, -1f, 1f); GameObject val11 = new GameObject("LBMid"); val11.transform.SetParent(val.transform, false); val11.AddComponent(); UIFactory.AddVLG(val11); UIFactory.AddLE(val11, 500f, -1f, 560f, -1f, -1f, 1f); string[] array = new string[8] { "#", "Lv", "Player", "Rating", "W", "L", "W/L", "Gold" }; string[] hK = new string[8] { "rank", "level", "display_name", "rating", "wins", "losses", "wl_ratio", "gold" }; GameObject val12 = new GameObject("LBH"); val12.transform.SetParent(val11.transform, false); val12.AddComponent(); UIFactory.AddHLG(val12, 2f); UIFactory.AddLE(val12, -1f, 28f, -1f, 28f, -1f, 0f); lbSortTexts = new object[array.Length]; lbSortBtns = (GameObject[])(object)new GameObject[array.Length]; GameObject val13 = new GameObject("S"); val13.transform.SetParent(val12.transform, false); val13.AddComponent(); UIFactory.AddLE(val13, -1f, -1f, -1f, -1f, 1f); for (int num = 0; num < array.Length; num++) { int idx = num; string text = ((!(lbSort == hK[num])) ? "" : (lbSortDesc ? " v" : " ^")); GameObject val14 = UIFactory.CreateButton($"LH{num}", val12.transform, array[num] + text, 14f, (lbSort == hK[num]) ? C_WHITE : C_LABEL, (lbSort == hK[num]) ? C_TABACT : C_TAB, (UnityAction)delegate { if (lbSort == hK[idx]) { lbSortDesc = !lbSortDesc; } else { lbSort = hK[idx]; lbSortDesc = idx >= 3; } dirty = true; }, (Vector2?)new Vector2(LB_COL_W[num], 22f)); if (UIFactory.tLE != null) { Component component = val14.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } UIFactory.AddLE(val14, -1f, -1f, LB_COL_W[num], 22f, -1f, 0f); lbSortBtns[num] = val14; lbSortTexts[num] = UIFactory.GetButtonText(val14); } GameObject val15 = new GameObject("S"); val15.transform.SetParent(val12.transform, false); val15.AddComponent(); UIFactory.AddLE(val15, -1f, -1f, -1f, -1f, 1f); UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("LBSV", val11.transform); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); for (int num2 = 0; num2 < 100; num2++) { lbRows.Add(CreateLBRow(scrollViewRefs2.content.transform, $"lb{num2}", num2)); } GameObject val16 = new GameObject("LBPg"); val16.transform.SetParent(val11.transform, false); val16.AddComponent(); UIFactory.AddHLG(val16, 6f); UIFactory.AddLE(val16, -1f, -1f, -1f, 24f, -1f, 0f); txtLBCount = UIFactory.CreateText("LBC", val16.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(160f, 22f), richText: true, raycastTarget: false); GameObject val17 = new GameObject("S"); val17.transform.SetParent(val16.transform, false); val17.AddComponent(); UIFactory.AddLE(val17, -1f, -1f, -1f, -1f, 1f); Transform transform5 = val16.transform; Color c_LABEL5 = C_LABEL; Color c_BTN5 = C_BTN; object obj5 = <>c.<>9__196_4; if (obj5 == null) { UnityAction val18 = delegate { if (lbPage > 0) { lbPage--; dirty = true; } }; <>c.<>9__196_4 = val18; obj5 = (object)val18; } lbPrev = UIFactory.CreateButton("lbP", transform5, "< Prev", 13f, c_LABEL5, c_BTN5, (UnityAction)obj5, (Vector2?)new Vector2(60f, 22f)); txtLBPage = UIFactory.CreateText("lbPI", val16.transform, "", 13f, C_LABEL, 514, (Vector2?)new Vector2(40f, 22f), richText: true, raycastTarget: false); Transform transform6 = val16.transform; Color c_LABEL6 = C_LABEL; Color c_BTN6 = C_BTN; object obj6 = <>c.<>9__196_5; if (obj6 == null) { UnityAction val19 = delegate { lbPage++; dirty = true; }; <>c.<>9__196_5 = val19; obj6 = (object)val19; } lbNext = UIFactory.CreateButton("lbN", transform6, "Next >", 13f, c_LABEL6, c_BTN6, (UnityAction)obj6, (Vector2?)new Vector2(60f, 22f)); GameObject val20 = UIFactory.CreatePanel("LBR", val.transform, C_PANEL); UIFactory.AddVLG(val20, 4f, 12, 12, 8, 8); UIFactory.AddLE(val20, -1f, -1f, -1f, -1f, 1f, 1f); txtLBPlayerName = UIFactory.CreateText("LBName", val20.transform, "Click a player", 20f, C_WHITE, 513, (Vector2?)new Vector2(340f, 26f), richText: true, raycastTarget: false); UIFactory.SetBold(txtLBPlayerName, b: true); lbGraphPanel = new GameObject("Graph"); lbGraphPanel.transform.SetParent(val20.transform, false); lbGraphPanel.AddComponent(); UIFactory.AddLE(lbGraphPanel, -1f, 80f, -1f, 80f, -1f, 0f); Component obj7 = lbGraphPanel.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj7, (object)new Color(0f, 0f, 0f, 0.01f)); if (UIFactory.tMask != null) { Component obj8 = lbGraphPanel.AddComponent(UIFactory.tMask); try { UIFactory.tMask.GetProperty("showMaskGraphic", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj8, false); } catch { } } lbGraphPanel.SetActive(false); h2hPager = new GameObject("H2HPg"); h2hPager.transform.SetParent(val20.transform, false); h2hPager.AddComponent(); UIFactory.AddHLG(h2hPager, 6f); UIFactory.AddLE(h2hPager, -1f, -1f, -1f, 20f, -1f, 0f); UIFactory.CreateText("H2HL", h2hPager.transform, "Series vs You", 12f, C_LABEL, 513, (Vector2?)new Vector2(120f, 18f), richText: true, raycastTarget: false); GameObject val21 = new GameObject("S"); val21.transform.SetParent(h2hPager.transform, false); val21.AddComponent(); UIFactory.AddLE(val21, -1f, -1f, -1f, -1f, 1f); Transform transform7 = h2hPager.transform; Color c_LABEL7 = C_LABEL; Color c_BTN7 = C_BTN; object obj10 = <>c.<>9__196_6; if (obj10 == null) { UnityAction val22 = delegate { if (h2hSeriesPage > 0) { h2hSeriesPage--; dirty = true; } }; <>c.<>9__196_6 = val22; obj10 = (object)val22; } h2hPrev = UIFactory.CreateButton("h2hP", transform7, "< Newer", 10f, c_LABEL7, c_BTN7, (UnityAction)obj10, (Vector2?)new Vector2(58f, 18f)); txtH2hPage = UIFactory.CreateText("h2hI", h2hPager.transform, "", 10f, C_LABEL, 514, (Vector2?)new Vector2(40f, 18f), richText: true, raycastTarget: false); Transform transform8 = h2hPager.transform; Color c_LABEL8 = C_LABEL; Color c_BTN8 = C_BTN; object obj11 = <>c.<>9__196_7; if (obj11 == null) { UnityAction val23 = delegate { h2hSeriesPage++; dirty = true; }; <>c.<>9__196_7 = val23; obj11 = (object)val23; } h2hNext = UIFactory.CreateButton("h2hN", transform8, "Older >", 10f, c_LABEL8, c_BTN8, (UnityAction)obj11, (Vector2?)new Vector2(58f, 18f)); h2hPager.SetActive(false); UIFactory.ScrollViewRefs scrollViewRefs3 = UIFactory.CreateScrollView("LBDSV", val20.transform, 0f); UIFactory.AddLE(scrollViewRefs3.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); txtLBDetail = UIFactory.CreateText("LBD", scrollViewRefs3.content.transform, "", 16f, C_DIM, 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); UIFactory.SetTextAutoHeight(txtLBDetail); UIFactory.SetWordWrap(txtLBDetail, on: true); UIFactory.CreateText("LBDScrollHint", val20.transform, "scroll for full history — hover + mouse wheel", 11f, C_DIM, 514, (Vector2?)new Vector2(340f, 15f), richText: true, raycastTarget: false); lbBlockRow = new GameObject("BlockRow"); lbBlockRow.transform.SetParent(val20.transform, false); lbBlockRow.AddComponent(); UIFactory.AddHLG(lbBlockRow, 0f); UIFactory.AddLE(lbBlockRow, -1f, 28f, -1f, 28f, -1f, 0f); Transform transform9 = lbBlockRow.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.5f, 0.15f, 0.15f, 0.9f); object obj12 = <>c.<>9__196_8; if (obj12 == null) { UnityAction val24 = delegate { if (!string.IsNullOrEmpty(selectedSteamId) && !(selectedSteamId == MatchTracker.LocalSteamId)) { string localSteamId = MatchTracker.LocalSteamId; if (ApiClient.IsPlayerBlocked(selectedSteamId)) { ApiClient.UnblockPlayer(localSteamId, selectedSteamId); } else { ApiClient.BlockPlayer(localSteamId, selectedSteamId); } } }; <>c.<>9__196_8 = val24; obj12 = (object)val24; } lbBlockBtn = UIFactory.CreateButton("LBBlock", transform9, "Block from Ranked", 14f, c_WHITE, bgColor, (UnityAction)obj12, (Vector2?)new Vector2(160f, 24f)); GameObject val25 = new GameObject("S"); val25.transform.SetParent(lbBlockRow.transform, false); val25.AddComponent(); UIFactory.AddLE(val25, -1f, -1f, -1f, -1f, 1f); lbBlockBtn.SetActive(true); lbBlockRow.SetActive(false); lbBlockTxt = UIFactory.GetButtonText(lbBlockBtn); return val; } private static LBRow CreateLBRow(Transform parent, string name, int rowIndex) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_007a: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: 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_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) LBRow lBRow = new LBRow(); lBRow.root = new GameObject(name); lBRow.root.transform.SetParent(parent, false); lBRow.root.AddComponent(); UIFactory.AddHLG(lBRow.root, 0f); UIFactory.AddLE(lBRow.root, -1f, -1f, -1f, 28f); GameObject val = new GameObject("S"); val.transform.SetParent(lBRow.root.transform, false); val.AddComponent(); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, 1f); lBRow.hlWrap = new GameObject("W"); lBRow.hlWrap.transform.SetParent(lBRow.root.transform, false); lBRow.hlWrap.AddComponent(); UIFactory.AddHLG(lBRow.hlWrap, 2f); if (UIFactory.tImage != null) { Component obj = lBRow.hlWrap.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, (object)new Color(0.15f, 0.15f, 0.2f, 0.01f)); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, true); } lBRow.txtRank = UIFactory.CreateText("r", lBRow.hlWrap.transform, "", 15f, C_GOLD, 514, (Vector2?)new Vector2(LB_COL_W[0], 25f), richText: true, raycastTarget: false); lBRow.txtLv = UIFactory.CreateText("l", lBRow.hlWrap.transform, "", 15f, C_BLUE, 514, (Vector2?)new Vector2(LB_COL_W[1], 25f), richText: true, raycastTarget: false); lBRow.txtName = UIFactory.CreateText("n", lBRow.hlWrap.transform, "", 16f, C_WHITE, 513, (Vector2?)new Vector2(LB_COL_W[2], 25f), richText: true, raycastTarget: false); lBRow.txtRating = UIFactory.CreateText("rt", lBRow.hlWrap.transform, "", 16f, C_WHITE, 514, (Vector2?)new Vector2(LB_COL_W[3], 25f), richText: true, raycastTarget: false); UIFactory.SetBold(lBRow.txtRating, b: true); lBRow.txtW = UIFactory.CreateText("w", lBRow.hlWrap.transform, "", 15f, C_GREEN, 514, (Vector2?)new Vector2(LB_COL_W[4], 25f), richText: true, raycastTarget: false); lBRow.txtL = UIFactory.CreateText("ls", lBRow.hlWrap.transform, "", 15f, C_RED, 514, (Vector2?)new Vector2(LB_COL_W[5], 25f), richText: true, raycastTarget: false); lBRow.txtWL = UIFactory.CreateText("wl", lBRow.hlWrap.transform, "", 15f, C_LABEL, 514, (Vector2?)new Vector2(LB_COL_W[6], 25f), richText: true, raycastTarget: false); lBRow.txtGold = UIFactory.CreateText("gd", lBRow.hlWrap.transform, "", 15f, C_GOLD, 514, (Vector2?)new Vector2(LB_COL_W[7], 25f), richText: true, raycastTarget: false); UIFactory.SetBold(lBRow.txtGold, b: true); GameObject val2 = new GameObject("S"); val2.transform.SetParent(lBRow.root.transform, false); val2.AddComponent(); UIFactory.AddLE(val2, -1f, -1f, -1f, -1f, 1f); int idx = rowIndex; lBRow.root.AddComponent().onClick = delegate { if (ClickGuard.Claim() && idx >= 0 && idx < lbRows.Count && !string.IsNullOrEmpty(lbRows[idx].steamId)) { string sid = lbRows[idx].steamId; h2hSeriesPage = 0; if (selectedSteamId == sid) { selectedSteamId = ""; selectedStats = null; selectedViewHistory = null; } else { selectedSteamId = sid; selectedStats = null; selectedViewHistory = null; ApiClient.FetchPlayerStatsForView(sid, delegate(ApiClient.PlayerStatsData d) { selectedStats = d; dirty = true; }); ApiClient.FetchAchievementsForView(sid); ApiClient.FetchPlayerTournaments(sid); ApiClient.FetchMatchHistoryForView(sid, delegate(List h) { if (selectedSteamId == sid) { selectedViewHistory = h; dirty = true; } }); } dirty = true; } }; lBRow.root.SetActive(false); return lBRow; } private static GameObject BuildCardStatsTab(Transform parent) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_00c9: 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_0110: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Expected O, but got Unknown //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Expected O, but got Unknown //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Expected O, but got Unknown //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_06bf: Expected O, but got Unknown //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_05c0: Unknown result type (might be due to invalid IL or missing references) //IL_05b9: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_05df: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Expected O, but got Unknown GameObject val = new GameObject("CardStats"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 4f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("Filt"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddHLG(val2, 4f, 12); UIFactory.AddLE(val2, -1f, 34f, -1f, 34f, -1f, 0f); Transform transform = val2.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.2f, 0.55f, 0.3f, 0.95f); object obj = <>c.<>9__198_0; if (obj == null) { UnityAction val3 = delegate { ExportCardTierList(); }; <>c.<>9__198_0 = val3; obj = (object)val3; } GameObject val4 = UIFactory.CreateButton("ExpBtn", transform, "Export Tier List", 16f, c_WHITE, bgColor, (UnityAction)obj, (Vector2?)new Vector2(180f, 30f)); UIFactory.SetBold(UIFactory.GetButtonText(val4), b: true); if (UIFactory.tLE != null) { Component component = val4.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } UIFactory.AddLE(val4, 180f, 30f, 180f, 30f, 0f, 0f); GameObject val5 = new GameObject("S"); val5.transform.SetParent(val2.transform, false); val5.AddComponent(); UIFactory.AddLE(val5, -1f, -1f, -1f, -1f, 1f); string[] array = new string[3] { "All", "Ranked", "Casual" }; cardFilterBtns = (GameObject[])(object)new GameObject[3]; cardFilterTexts = new object[3]; float num = 0f; for (int num2 = 0; num2 < CS_COL_W.Length; num2++) { num += CS_COL_W[num2]; } float num3 = Mathf.Floor((num - 4f) / 3f); for (int num4 = 0; num4 < 3; num4++) { int idx = num4; GameObject val6 = UIFactory.CreateButton($"F{num4}", val2.transform, array[num4], 18f, C_LABEL, (num4 == 0) ? C_TABACT : C_TAB, (UnityAction)delegate { //IL_0062: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) cardFilter = idx; string isRanked = ((idx == 1) ? "true" : ((idx == 2) ? "false" : null)); ApiClient.FetchCardStats(200, MatchTracker.LocalSteamId, "times_picked", isRanked); LoadCardTiersForCurrentFilter(); for (int i = 0; i < 3; i++) { UIFactory.SetImageColor(cardFilterBtns[i], (i == idx) ? C_TABACT : C_TAB); if (cardFilterTexts[i] != null) { UIFactory.SetColor(cardFilterTexts[i], (i == idx) ? C_WHITE : C_LABEL); UIFactory.SetBold(cardFilterTexts[i], i == idx); } } dirty = true; }, (Vector2?)new Vector2(num3, 30f)); if (UIFactory.tLE != null) { Component component2 = val6.GetComponent(UIFactory.tLE); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } float prefW = num3; UIFactory.AddLE(val6, num3, 30f, prefW, 30f, 0f, 0f); UIFactory.SetBold(UIFactory.GetButtonText(val6), b: true); cardFilterBtns[num4] = val6; cardFilterTexts[num4] = UIFactory.GetButtonText(val6); } GameObject val7 = new GameObject("S"); val7.transform.SetParent(val2.transform, false); val7.AddComponent(); UIFactory.AddLE(val7, -1f, -1f, -1f, -1f, 1f); GameObject val8 = new GameObject("FBal"); val8.transform.SetParent(val2.transform, false); val8.AddComponent(); UIFactory.AddLE(val8, 180f, -1f, 180f, -1f, 0f); string[] array2 = new string[7] { "Tier", "Card", "Rarity", "Picks", "Wins", "WR%", "Pass%" }; string[] hK = new string[7] { "tier", "card_name", "card_rarity", "times_picked", "wins_with_card", "win_rate", "pass_rate" }; GameObject val9 = new GameObject("CHR"); val9.transform.SetParent(val.transform, false); val9.AddComponent(); UIFactory.AddHLG(val9, 2f); UIFactory.AddLE(val9, -1f, 32f, -1f, 32f, -1f, 0f); cardSortTexts = new object[7]; cardSortBtns = (GameObject[])(object)new GameObject[7]; GameObject val10 = new GameObject("S"); val10.transform.SetParent(val9.transform, false); val10.AddComponent(); UIFactory.AddLE(val10, -1f, -1f, -1f, -1f, 1f); for (int num5 = 0; num5 < 7; num5++) { int idx2 = num5; string text = ((!(cardSort == hK[num5])) ? "" : (cardSortDesc ? " v" : " ^")); GameObject val11 = UIFactory.CreateButton($"CS{num5}", val9.transform, array2[num5] + text, 18f, (cardSort == hK[num5]) ? C_WHITE : C_LABEL, (cardSort == hK[num5]) ? C_TABACT : C_TAB, (UnityAction)delegate { if (cardSort == hK[idx2]) { cardSortDesc = !cardSortDesc; } else { cardSort = hK[idx2]; cardSortDesc = true; } dirty = true; }, (Vector2?)new Vector2(CS_COL_W[num5], 26f)); if (UIFactory.tLE != null) { Component component3 = val11.GetComponent(UIFactory.tLE); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } } UIFactory.AddLE(val11, -1f, -1f, CS_COL_W[num5], 26f, -1f, 0f); UIFactory.SetBold(UIFactory.GetButtonText(val11), b: true); cardSortBtns[num5] = val11; cardSortTexts[num5] = UIFactory.GetButtonText(val11); } GameObject val12 = new GameObject("S"); val12.transform.SetParent(val9.transform, false); val12.AddComponent(); UIFactory.AddLE(val12, -1f, -1f, -1f, -1f, 1f); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("CSV", val.transform); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); for (int num6 = 0; num6 < 100; num6++) { cardRows.Add(CreateCardRow(scrollViewRefs.content.transform, $"cd{num6}")); } return val; } private static CardRow CreateCardRow(Transform parent, string name) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_0171: 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_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) CardRow row = new CardRow(); row.root = new GameObject(name); row.root.transform.SetParent(parent, false); row.root.AddComponent(); UIFactory.AddHLG(row.root, 0f); UIFactory.AddLE(row.root, -1f, -1f, -1f, 30f); GameObject val = new GameObject("S"); val.transform.SetParent(row.root.transform, false); val.AddComponent(); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, 1f); row.hl = new GameObject("hl"); row.hl.transform.SetParent(row.root.transform, false); row.hl.AddComponent(); Component obj = row.hl.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, (object)new Color(0f, 0f, 0f, 0f)); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, false); UIFactory.AddHLG(row.hl, 2f); UIFactory.AddLE(row.hl, -1f, 30f, -1f, 30f, -1f, 0f); row.tierBtn = UIFactory.CreateButton("tb", row.hl.transform, "-", 18f, Color.black, new Color(0.18f, 0.2f, 0.24f, 0.85f), (UnityAction)delegate { if (!string.IsNullOrEmpty(row.cardName)) { CycleCardTierInPlace(row, row.cardName); } }, (Vector2?)new Vector2(CS_COL_W[0], 30f)); row.txtTier = UIFactory.GetButtonText(row.tierBtn); UIFactory.SetBold(row.txtTier, b: true); row.txtName = UIFactory.CreateText("t", row.hl.transform, "", 19f, C_WHITE, 513, (Vector2?)new Vector2(CS_COL_W[1], 30f), richText: true, raycastTarget: true); UIFactory.SetBold(row.txtName, b: true); row.txtRarity = UIFactory.CreateText("tr", row.hl.transform, "", 18f, C_LABEL, 514, (Vector2?)new Vector2(CS_COL_W[2], 30f), richText: true, raycastTarget: false); UIFactory.SetBold(row.txtRarity, b: true); row.txtPicks = UIFactory.CreateText("tp", row.hl.transform, "", 19f, C_WHITE, 514, (Vector2?)new Vector2(CS_COL_W[3], 30f), richText: true, raycastTarget: false); UIFactory.SetBold(row.txtPicks, b: true); row.txtWins = UIFactory.CreateText("tw", row.hl.transform, "", 19f, C_WHITE, 514, (Vector2?)new Vector2(CS_COL_W[4], 30f), richText: true, raycastTarget: false); UIFactory.SetBold(row.txtWins, b: true); row.txtWR = UIFactory.CreateText("wr", row.hl.transform, "", 19f, C_WHITE, 514, (Vector2?)new Vector2(CS_COL_W[5], 30f), richText: true, raycastTarget: false); UIFactory.SetBold(row.txtWR, b: true); row.txtPass = UIFactory.CreateText("pr", row.hl.transform, "", 19f, C_LABEL, 514, (Vector2?)new Vector2(CS_COL_W[6], 30f), richText: true, raycastTarget: false); UIFactory.SetBold(row.txtPass, b: true); try { object txtName = row.txtName; Component val2 = (Component)((txtName is Component) ? txtName : null); if ((Object)(object)val2 != (Object)null) { val2.gameObject.AddComponent().onClick = delegate { if (ClickGuard.Claim() && !string.IsNullOrEmpty(row.cardName)) { ShowCardPreview(row.cardName); } }; } } catch { } GameObject val3 = new GameObject("S"); val3.transform.SetParent(row.root.transform, false); val3.AddComponent(); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, 1f); row.root.SetActive(false); return row; } private static CardStatTuple CST(bool p, string a, string s) { return new CardStatTuple { positive = p, amount = a, stat = s }; } private static string NormalizeStatLabel(string raw) { if (string.IsNullOrEmpty(raw)) { return raw; } string text = raw.Trim().ToUpperInvariant(); if (text.EndsWith(":")) { text = text.Substring(0, text.Length - 1).TrimEnd(); } switch (text) { case "DAMAGE": case "DMG": case "DAMAGE:": return "DMG"; case "ATKSPD": case "ATK SPD": case "ATTACK SPEED": case "ATK SPEED": return "ATK SPD"; case "BULLET SPEED": case "BULLET SPD": case "PROJ SPEED": case "PROJECTILE SPEED": return "BULLET SPD"; case "RELOAD": case "RELOAD SPEED": case "RELOAD SPD": case "RELOAD TIME": return "RELOAD"; case "BLOCK CD": case "BLOCK COOLDOWN": case "BLOCK COOLDOWN TIME": return "BLOCK CD"; case "HEALTH": case "HP": return "HP"; case "MAG": case "MAGAZINE": case "AMMO": return "AMMO"; case "BULLETS": case "BULLET COUNT": return "BULLETS"; case "BULLET": case "BULLET LOSS": return "BULLET"; case "LIFESTEAL": case "LIFE STEAL": return "LIFESTEAL"; case "BOUNCES": case "BULLET BOUNCES": return "BULLET BOUNCES"; case "BOUNCE": case "BULLET BOUNCE": return "BULLET BOUNCE"; case "BULLET SLOW": return "BULLET SLOW"; case "WALL DRILL": case "DRILL THROUGH WALLS": case "DRILL": return "DRILL"; case "SPLASH DMG": case "SPLASH DAMAGE": return "SPLASH DMG"; default: return text; } } private static string BuildStatBlockFromFallback(string cardName, int max) { if (string.IsNullOrEmpty(cardName)) { return ""; } string text = CardRarityLookup.GetCanonicalName(cardName) ?? cardName; string[] obj = new string[2] { (text ?? "").ToLowerInvariant().Replace(" ", ""), (cardName ?? "").ToLowerInvariant().Replace(" ", "") }; CardStatTuple[] value = null; string[] array = obj; foreach (string text2 in array) { if (!string.IsNullOrEmpty(text2) && CARD_STATS_FALLBACK.TryGetValue(text2, out value)) { break; } } if (value == null || value.Length == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); int num = 0; for (int j = 0; j < value.Length; j++) { if (num >= max) { break; } CardStatTuple cardStatTuple = value[j]; string value2 = (cardStatTuple.positive ? "#88FF88" : "#FF8888"); if (stringBuilder.Length > 0) { stringBuilder.Append("\n"); } stringBuilder.Append("") .Append(cardStatTuple.amount) .Append(" ") .Append(cardStatTuple.stat); num++; } return stringBuilder.ToString(); } public static void ShowCardPreview(string cardName) { //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Expected O, but got Unknown //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_07fb: Unknown result type (might be due to invalid IL or missing references) //IL_083c: Unknown result type (might be due to invalid IL or missing references) //IL_0850: Unknown result type (might be due to invalid IL or missing references) //IL_0863: Unknown result type (might be due to invalid IL or missing references) //IL_0868: Unknown result type (might be due to invalid IL or missing references) //IL_06b0: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f4: Unknown result type (might be due to invalid IL or missing references) //IL_0885: Unknown result type (might be due to invalid IL or missing references) //IL_0896: Unknown result type (might be due to invalid IL or missing references) //IL_08e2: Unknown result type (might be due to invalid IL or missing references) //IL_08f6: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Expected O, but got Unknown //IL_07aa: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Unknown result type (might be due to invalid IL or missing references) //IL_0942: Unknown result type (might be due to invalid IL or missing references) //IL_0956: Unknown result type (might be due to invalid IL or missing references) //IL_0b65: Unknown result type (might be due to invalid IL or missing references) //IL_0b79: Unknown result type (might be due to invalid IL or missing references) //IL_0ba1: Unknown result type (might be due to invalid IL or missing references) //IL_0bb5: Unknown result type (might be due to invalid IL or missing references) //IL_0b27: Unknown result type (might be due to invalid IL or missing references) //IL_0b3b: Unknown result type (might be due to invalid IL or missing references) //IL_0ae4: Unknown result type (might be due to invalid IL or missing references) //IL_0af8: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(cardName)) { return; } HideCardPreview(); string lcTarget; string lcCanonical; try { Component val = null; string text = cardName; string text2 = "Unknown"; string text3 = ""; Array array = null; lcTarget = (cardName ?? "").ToLowerInvariant().Replace(" ", ""); string text4 = CardRarityLookup.GetCanonicalName(cardName) ?? cardName; lcCanonical = text4.ToLowerInvariant().Replace(" ", ""); try { Type type = (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetType("CardChoice")).FirstOrDefault((Type t) => t != null); if (type != null) { object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); val = MatchInArray(type.GetField("cards", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj) as Array); } if ((Object)(object)val == (Object)null) { val = MatchInArray(Resources.FindObjectsOfTypeAll()); } if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)("[CARD-PREVIEW] CardInfo not found for '" + cardName + "' (canonical='" + text4 + "') — falling back to dict")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARD-PREVIEW] lookup: " + ex.Message)); } if ((Object)(object)val != (Object)null) { Type type2 = ((object)val).GetType(); FieldInfo? field = type2.GetField("cardName", BindingFlags.Instance | BindingFlags.Public); FieldInfo field2 = type2.GetField("rarity", BindingFlags.Instance | BindingFlags.Public); FieldInfo fieldInfo = type2.GetField("cardDestription", BindingFlags.Instance | BindingFlags.Public) ?? type2.GetField("cardDescription", BindingFlags.Instance | BindingFlags.Public) ?? type2.GetField("description", BindingFlags.Instance | BindingFlags.Public); FieldInfo fieldInfo2 = type2.GetField("cardStats", BindingFlags.Instance | BindingFlags.Public) ?? type2.GetField("stats", BindingFlags.Instance | BindingFlags.Public); text = (field?.GetValue(val) as string) ?? cardName; object obj2 = field2?.GetValue(val); text2 = ((obj2 != null) ? obj2.ToString() : "Unknown"); text3 = (fieldInfo?.GetValue(val) as string) ?? ""; array = fieldInfo2?.GetValue(val) as Array; if (string.IsNullOrEmpty(text3)) { string text5 = (text4 ?? cardName ?? "").ToLowerInvariant().Replace(" ", ""); if (!string.IsNullOrEmpty(text5) && CARD_DESC_FALLBACK.TryGetValue(text5, out var value)) { text3 = value; } } if (string.IsNullOrEmpty(text3)) { try { string text6 = (text ?? "").ToLowerInvariant().Replace(" ", ""); string text7 = (text2 ?? "").ToLowerInvariant(); StringBuilder stringBuilder = new StringBuilder(); Type type3 = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type3 = assembly.GetType("TMPro.TMP_Text") ?? assembly.GetType("TMPro.TextMeshProUGUI"); if (type3 != null) { break; } } if (type3 != null) { PropertyInfo property = type3.GetProperty("text", BindingFlags.Instance | BindingFlags.Public); Component[] componentsInChildren = val.gameObject.GetComponentsInChildren(type3, true); foreach (Component val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || property == null) { continue; } string text8 = (property.GetValue(val2) as string) ?? ""; text8 = text8.Trim(); if (string.IsNullOrEmpty(text8)) { continue; } string text9 = text8.ToLowerInvariant().Replace(" ", ""); if (!(text9 == text6) && !(text9 == text7) && text8.Length >= 4 && text8.Length <= 200) { if (stringBuilder.Length > 0) { stringBuilder.Append("\n"); } stringBuilder.Append(text8); if (stringBuilder.Length > 240) { break; } } } } if (stringBuilder.Length > 0) { text3 = stringBuilder.ToString(); } } catch { } } } if (string.IsNullOrEmpty(text3)) { string text10 = (text4 ?? cardName ?? "").ToLowerInvariant().Replace(" ", ""); if (!string.IsNullOrEmpty(text10) && CARD_DESC_FALLBACK.TryGetValue(text10, out var value2)) { text3 = value2; } } EnsureOverlayCanvas(); cardPreviewGO = new GameObject("CR_CardPreview"); ((Object)cardPreviewGO).hideFlags = (HideFlags)61; cardPreviewGO.transform.SetParent(overlayCanvasGO.transform, false); RectTransform obj4 = cardPreviewGO.AddComponent(); obj4.anchorMin = Vector2.zero; obj4.anchorMax = Vector2.one; obj4.offsetMin = Vector2.zero; obj4.offsetMax = Vector2.zero; GameObject obj5 = UIFactory.CreatePanel("BD", cardPreviewGO.transform, new Color(0f, 0f, 0f, 0.45f)); RectTransform component = obj5.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; Component component2 = obj5.GetComponent(UIFactory.tImage); if ((Object)(object)component2 != (Object)null) { UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component2, true); } obj5.AddComponent().onClick = delegate { if (ClickGuard.Claim()) { HideCardPreview(); } }; Sprite sprite = CardImageLoader.GetSprite(cardName); GameObject val3 = UIFactory.CreatePanel("Card", cardPreviewGO.transform, new Color(0.1f, 0.12f, 0.16f, 0.97f)); RectTransform component3 = val3.GetComponent(); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.pivot = new Vector2(0.5f, 0.5f); if ((Object)(object)sprite != (Object)null) { component3.sizeDelta = new Vector2(380f, 600f); UIFactory.AddVLG(val3, 6f, 10, 10, 10, 10); GameObject val4 = new GameObject("CardImg"); val4.transform.SetParent(val3.transform, false); val4.AddComponent(); Component obj6 = val4.AddComponent(UIFactory.tImage); PropertyInfo? property2 = UIFactory.tImage.GetProperty("sprite", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property3 = UIFactory.tImage.GetProperty("preserveAspect", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property4 = UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public); property2?.SetValue(obj6, sprite); property3?.SetValue(obj6, true); property4?.SetValue(obj6, Color.white); UIFactory.AddLE(val4, 360f, 545f, 360f, 545f, 0f, 0f); UIFactory.CreateText("CPHint", val3.transform, "click anywhere to close", 13f, C_DIM, 514, (Vector2?)new Vector2(360f, 20f), richText: true, raycastTarget: false); Plugin.Log.LogInfo((object)("[CARD-PREVIEW] showing image for '" + text + "'")); return; } component3.sizeDelta = new Vector2(440f, 360f); UIFactory.AddVLG(val3, 6f, 18, 18, 14, 14); UIFactory.CreateText("CPName", val3.transform, "" + text + "", 24f, C_WHITE, 514, (Vector2?)new Vector2(400f, 32f), richText: true, raycastTarget: false); Color rarityColor = GetRarityColor(text2); UIFactory.CreateText("CPRar", val3.transform, text2 ?? "Unknown", 16f, rarityColor, 514, (Vector2?)new Vector2(400f, 22f), richText: true, raycastTarget: false); if (!string.IsNullOrEmpty(text3)) { UIFactory.SetWordWrap(UIFactory.CreateText("CPDesc", val3.transform, "" + text3 + "", 15f, new Color(0.85f, 0.88f, 0.95f), 514, (Vector2?)new Vector2(400f, 60f), richText: true, raycastTarget: false), on: true); } string text11 = null; if (array == null || array.Length == 0) { text11 = BuildStatBlockFromFallback(cardName, 8); } if (!string.IsNullOrEmpty(text11)) { UIFactory.SetWordWrap(UIFactory.CreateText("CPStats", val3.transform, text11, 15f, C_LABEL, 257, (Vector2?)new Vector2(400f, 160f), richText: true, raycastTarget: false), on: true); } else if (array != null && array.Length > 0) { StringBuilder stringBuilder2 = new StringBuilder(); for (int num2 = 0; num2 < array.Length; num2++) { object value3 = array.GetValue(num2); if (value3 != null) { Type type4 = value3.GetType(); string text12 = (type4.GetField("stat", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value3) as string) ?? ""; string value4 = (type4.GetField("amount", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value3) as string) ?? ""; bool flag = !(type4.GetField("positive", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value3) is bool flag2) || flag2; if (!string.IsNullOrEmpty(text12) || !string.IsNullOrEmpty(value4)) { string value5 = (flag ? "#88FF88" : "#FF6666"); stringBuilder2.Append(" ") .Append(value4) .Append(" ") .Append(NormalizeStatLabel(text12)) .Append("\n"); } } } string text13 = stringBuilder2.ToString().TrimEnd('\n'); if (!string.IsNullOrEmpty(text13)) { UIFactory.SetWordWrap(UIFactory.CreateText("CPStats", val3.transform, text13, 15f, C_LABEL, 257, (Vector2?)new Vector2(400f, 160f), richText: true, raycastTarget: false), on: true); } else { UIFactory.CreateText("CPStatsEmpty", val3.transform, "(Mechanic isn't expressed as numerical stats — check the card description above or pick it in-game.)", 13f, C_DIM, 514, (Vector2?)new Vector2(400f, 60f), richText: true, raycastTarget: false); } } else { UIFactory.CreateText("CPNoStats", val3.transform, "No stat data available for this card.", 13f, C_DIM, 514, (Vector2?)new Vector2(400f, 28f), richText: true, raycastTarget: false); } UIFactory.CreateText("CPHint", val3.transform, "click anywhere to close", 13f, C_DIM, 514, (Vector2?)new Vector2(400f, 18f), richText: true, raycastTarget: false); Plugin.Log.LogInfo((object)("[CARD-PREVIEW] showing text fallback for '" + text + "' (rarity=" + text2 + ")")); Component MatchInArray(IEnumerable arr) { if (arr == null) { return null; } foreach (object item in arr) { Component val5 = (Component)((item is Component) ? item : null); if (!((Object)(object)val5 == (Object)null)) { string s = ((Object)val5.gameObject).name?.Replace("(Clone)", "").Trim() ?? ""; string s2 = (((object)val5).GetType().GetField("cardName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(val5) as string) ?? ""; if (Matches(s) || Matches(s2)) { return val5; } } } return null; } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[CARD-PREVIEW] failed: " + ex2.Message)); } bool Matches(string s) { if (string.IsNullOrEmpty(s)) { return false; } string text14 = s.ToLowerInvariant().Replace(" ", ""); if (!(text14 == lcTarget)) { return text14 == lcCanonical; } return true; } } public static void HideCardPreview() { try { if ((Object)(object)cardPreviewGO != (Object)null) { Object.Destroy((Object)(object)cardPreviewGO); cardPreviewGO = null; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARD-PREVIEW] destroy: " + ex.Message)); } } public static void LoadCardTiersForCurrentFilter() { string filter = ((cardFilter == 1) ? "ranked" : ((cardFilter == 2) ? "casual" : "all")); int filterIdx = cardFilter; ApiClient.FetchCardTiers(MatchTracker.LocalSteamId, filter, delegate(Dictionary loaded) { Dictionary dictionary = new Dictionary(); foreach (KeyValuePair item in cardTierMap) { if (!item.Key.StartsWith($"{filterIdx}|")) { dictionary[item.Key] = item.Value; } } cardTierMap = dictionary; foreach (KeyValuePair item2 in loaded) { cardTierMap[CardTierKey(filterIdx, item2.Key)] = item2.Value; } dirty = true; }); } private static GameObject BuildAchievementsTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Expected O, but got Unknown //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Achievements"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 6f, 20, 20, 10); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("AchH", val.transform, "Achievements", 22f, C_GOLD, 258, (Vector2?)new Vector2(600f, 30f), richText: true, raycastTarget: false); GameObject val2 = new GameObject("AchCnt"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddLE(val2, -1f, -1f, -1f, 22f); txtAchCount = UIFactory.CreateText("AC", val2.transform, "", 15f, C_DIM, 514, (Vector2?)new Vector2(400f, 22f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("AchSV", val.transform, 4f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); achRows.Clear(); foreach (KeyValuePair achievementDef in ApiClient.AchievementDefs) { AchRow achRow = new AchRow(); string key = achievementDef.Key; string[] value = achievementDef.Value; achRow.root = new GameObject("ach_" + key); achRow.root.transform.SetParent(scrollViewRefs.content.transform, false); achRow.root.AddComponent(); UIFactory.AddHLG(achRow.root, 10f, 8, 8, 6, 6); UIFactory.AddLE(achRow.root, -1f, -1f, -1f, 50f); if (UIFactory.tImage != null) { Component obj = achRow.root.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, C_PANEL); } achRow.txtIcon = UIFactory.CreateText("ic", achRow.root.transform, "", 24f, C_DIM, 514, (Vector2?)new Vector2(36f, 40f), richText: true, raycastTarget: false); GameObject val3 = new GameObject("Info"); val3.transform.SetParent(achRow.root.transform, false); val3.AddComponent(); UIFactory.AddVLG(val3, 1f); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, 1f); achRow.txtName = UIFactory.CreateText("nm", val3.transform, value[0], 17f, C_WHITE, 513, (Vector2?)new Vector2(500f, 22f), richText: true, raycastTarget: false); achRow.txtDesc = UIFactory.CreateText("ds", val3.transform, value[1], 14f, C_LABEL, 513, (Vector2?)new Vector2(500f, 20f), richText: true, raycastTarget: false); achRow.txtDate = UIFactory.CreateText("dt", achRow.root.transform, "", 13f, C_DIM, 516, (Vector2?)new Vector2(180f, 40f), richText: true, raycastTarget: false); achRow.root.SetActive(true); achRows.Add(achRow); } return val; } private static void RefreshAchievements() { //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: 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_00b5: 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) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) Dictionary cachedAchievements = ApiClient.CachedAchievements; int num = 0; int count = ApiClient.AchievementDefs.Count; int num2 = 0; foreach (KeyValuePair achievementDef in ApiClient.AchievementDefs) { if (num2 >= achRows.Count) { break; } AchRow achRow = achRows[num2]; bool flag = cachedAchievements != null && cachedAchievements.ContainsKey(achievementDef.Key) && cachedAchievements[achievementDef.Key].unlocked; if (flag) { num++; } UIFactory.SetText(achRow.txtIcon, flag ? "[X]" : "[ ]"); UIFactory.SetColor(achRow.txtIcon, (Color)(flag ? C_GOLD : new Color(0.3f, 0.3f, 0.35f))); UIFactory.SetColor(achRow.txtName, flag ? C_WHITE : C_DIM); UIFactory.SetColor(achRow.txtDesc, (Color)(flag ? C_LABEL : new Color(0.4f, 0.4f, 0.45f))); string text = ""; if (flag && cachedAchievements != null && cachedAchievements.ContainsKey(achievementDef.Key)) { string unlocked_at = cachedAchievements[achievementDef.Key].unlocked_at; if (!string.IsNullOrEmpty(unlocked_at) && unlocked_at != "null") { try { text = DateTime.Parse(unlocked_at).ToString("M/d/yyyy"); } catch { } } } if (flag && !string.IsNullOrEmpty(text)) { text += " +100g"; } UIFactory.SetText(achRow.txtDate, text); UIFactory.SetColor(achRow.txtDate, flag ? C_GREEN : C_DIM); num2++; } UIFactory.SetText(txtAchCount, $"{num} / {count} unlocked"); UIFactory.SetColor(txtAchCount, (num == count) ? C_GOLD : C_LABEL); } private static void RefreshData() { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.FetchPlayerStats(localSteamId); ApiClient.FetchMatchHistory(localSteamId); ApiClient.FetchAchievements(localSteamId); ApiClient.FetchTeamStats(localSteamId); } if (currentTab == 1) { ApiClient.FetchLeaderboard(); ApiClient.FetchRecentSeries(); } if (currentTab == 2) { ApiClient.FetchCardStats(200, MatchTracker.LocalSteamId); LoadCardTiersForCurrentFilter(); } } private static void RefreshCurrentTab() { RefreshQueueUI(); RefreshVersionStatus(); RefreshServerBanner(); RefreshTournamentGameIndicator(); if (tabButtons != null && tabButtons.Length >= 7 && (Object)(object)tabButtons[6] != (Object)null) { tabButtons[6].SetActive(ApiClient.IsAdmin); } switch (currentTab) { case 0: RefreshMyStats(); break; case 1: RefreshLeaderboard(); RefreshRecentSeries(); RefreshLiveSeries(); break; case 2: RefreshCardStats(); break; case 3: RefreshAchievements(); break; case 4: RefreshShop(); break; case 5: RefreshSettings(); break; case 6: RefreshAdmin(); break; case 7: RefreshTournaments(); break; case 8: RefreshTeamTab(); break; case 9: RefreshCompare(); break; } } private static void _EnsureRankedEnabledForTournamentMatch(ApiClient.ActiveTournamentMatch m) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (m == null || string.IsNullOrEmpty(m.match_id) || _autoEnabledRankedForMatches.Contains(m.match_id)) { return; } _autoEnabledRankedForMatches.Add(m.match_id); if (Plugin.RankedEnabled == null || !Plugin.RankedEnabled.Value) { Plugin.RankedEnabled.Value = true; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.ToggleRanked(localSteamId, enabled: true); } CompetitiveUI.ShowNotification("Ranked auto-enabled for your tournament match - results will auto-record", new Color(1f, 0.85f, 0.3f)); Plugin.Log.LogInfo((object)("[TOURNAMENT] Auto-enabled Ranked for match " + m.match_id)); } } private static void RefreshTournamentGameIndicator() { if ((Object)(object)tournamentIndRow == (Object)null || txtTournamentGame == null) { return; } ApiClient.FetchMyActiveTournamentMatches(MatchTracker.LocalSteamId); List cachedMyActiveTournamentMatches = ApiClient.CachedMyActiveTournamentMatches; if (cachedMyActiveTournamentMatches != null) { foreach (ApiClient.ActiveTournamentMatch item in cachedMyActiveTournamentMatches) { _EnsureRankedEnabledForTournamentMatch(item); } } List cachedMyActiveTournamentMatches2 = ApiClient.CachedMyActiveTournamentMatches; if (cachedMyActiveTournamentMatches2 == null || cachedMyActiveTournamentMatches2.Count == 0 || !GameStateWatcher.IsInRoom) { tournamentIndRow.SetActive(false); return; } string opponentSteamId = GameStateWatcher.OpponentSteamId; if (string.IsNullOrEmpty(opponentSteamId) || opponentSteamId.StartsWith("photon_")) { tournamentIndRow.SetActive(false); return; } foreach (ApiClient.ActiveTournamentMatch item2 in cachedMyActiveTournamentMatches2) { if (item2.opponent_steam_id == opponentSteamId) { string text = (item2.kind ?? "").ToUpper(); UIFactory.SetText(txtTournamentGame, "* " + text + " TOURNAMENT GAME - vs " + (item2.opponent_display_name ?? "opponent") + " (results auto-recorded)"); tournamentIndRow.SetActive(true); return; } } tournamentIndRow.SetActive(false); } private static void RefreshServerBanner() { if (!((Object)(object)srvStatusRow == (Object)null)) { bool apiLooksDown = ApiClient.ApiLooksDown; srvStatusRow.SetActive(apiLooksDown); if (apiLooksDown) { string s = (ApiClient.LastResponseWasMaintenance ? "* Server in maintenance - back in a moment" : "* Server reconnecting..."); UIFactory.SetText(txtServerStatus, s); } } } private static void RefreshLiveSeries() { if (txtLiveSeries == null) { return; } if (txtLiveHeader != null) { string text = (liveHeaderPulseFilled ? "#FF6688" : "#552233"); UIFactory.SetText(txtLiveHeader, "* Live Ranked Games"); } List cachedActiveSeries = ApiClient.CachedActiveSeries; List list = new List(); if (cachedActiveSeries != null) { foreach (ApiClient.ActiveSeriesEntry item in cachedActiveSeries) { if (!item.is_tournament || !(item.phase == "pre_match")) { list.Add(item); } } } List cachedActiveTeamSeries = ApiClient.CachedActiveTeamSeries; int count = list.Count; int num = cachedActiveTeamSeries?.Count ?? 0; foreach (GameObject item2 in liveBetRowPool) { item2.SetActive(false); } if (count == 0 && num == 0) { UIFactory.SetText(txtLiveSeries, "No live games right now."); if ((Object)(object)liveBetsPager != (Object)null) { liveBetsPager.SetActive(false); } return; } UIFactory.SetText(txtLiveSeries, ""); int num2 = Math.Max(1, (count + 5 - 1) / 5); liveSeriesPage = Math.Max(0, Math.Min(liveSeriesPage, num2 - 1)); int num3 = liveSeriesPage * 5; int num4 = Math.Min(num3 + 5, count); int num5 = 0; for (int i = num3; i < num4; i++) { ApiClient.ActiveSeriesEntry s = list[i]; ApplyHeaderRow(GetOrCreateLiveRow(num5++), s); ApplyBetRow(GetOrCreateLiveRow(num5++), s, betOnP1: true); ApplyBetRow(GetOrCreateLiveRow(num5++), s, betOnP1: false); } if (cachedActiveTeamSeries != null) { foreach (ApiClient.ActiveTeamSeriesEntry item3 in cachedActiveTeamSeries) { ApplyTeamHeaderRow(GetOrCreateLiveRow(num5++), item3); ApplyTeamBetRow(GetOrCreateLiveRow(num5++), item3, 1); ApplyTeamBetRow(GetOrCreateLiveRow(num5++), item3, 2); } } if ((Object)(object)liveBetsPager != (Object)null) { bool flag = num2 > 1; liveBetsPager.SetActive(flag); if (flag) { UIFactory.SetText(txtLiveBetsPage, $"{count} live - {liveSeriesPage + 1}/{num2}"); liveBetsPrev.SetActive(liveSeriesPage > 0); liveBetsNext.SetActive(liveSeriesPage < num2 - 1); } } } private static GameObject GetOrCreateLiveRow(int idx) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown while (liveBetRowPool.Count <= idx) { GameObject val = new GameObject($"lb{liveBetRowPool.Count}"); val.transform.SetParent(liveBetsContainer.transform, false); val.AddComponent(); UIFactory.AddHLG(val); UIFactory.AddLE(val, -1f, -1f, -1f, 26f, -1f, 0f); liveBetRowPool.Add(val); } GameObject val2 = liveBetRowPool[idx]; for (int num = val2.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val2.transform.GetChild(num)).gameObject); } val2.SetActive(true); return val2; } private static void ApplyHeaderRow(GameObject row, ApiClient.ActiveSeriesEntry s) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) string text = ""; if (s.is_tournament) { string text2 = (string.IsNullOrEmpty(s.tournament_kind) ? "" : (" " + char.ToUpper(s.tournament_kind[0]) + s.tournament_kind.Substring(1))); text = "[TOURNAMENT" + text2 + "] "; } else if (s.is_private) { text = "[PRIVATE] "; } string text3 = text + $"{Trunc(s.p1_name, 12)} ({s.p1_rating}) " + $"{s.p1_wins}-{s.p2_wins} " + $"{Trunc(s.p2_name, 12)} ({s.p2_rating})"; object t = UIFactory.CreateText("h", row.transform, text3, 15f, C_WHITE, 513, (Vector2?)new Vector2(384f, 24f), richText: true, raycastTarget: false); UIFactory.SetBold(t, b: true); UIFactory.SetWordWrap(t, on: false); } private static void ApplyBetRow(GameObject row, ApiClient.ActiveSeriesEntry s, bool betOnP1) { //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) string s2 = (betOnP1 ? s.p1_name : s.p2_name); string text = (betOnP1 ? s.p1_steam_id : s.p2_steam_id); float num = (betOnP1 ? s.p1_odds : s.p2_odds); string localSteamId = MatchTracker.LocalSteamId; bool flag = !string.IsNullOrEmpty(localSteamId) && (localSteamId == s.p1_steam_id || localSteamId == s.p2_steam_id); ApiClient.MyBetEntry myBetForSeries = ApiClient.GetMyBetForSeries(s.series_id); if (myBetForSeries != null) { string arg = ((myBetForSeries.bet_on_steam_id == text) ? $" You bet {myBetForSeries.amount}g" : ""); UIFactory.SetWordWrap(UIFactory.CreateText("bl", row.transform, $"{Trunc(s2, 10)} @{num:F1}x{arg}", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false), on: false); return; } if (s.bets_locked) { string arg2 = ((s.lock_reason == "no_meaningful_odds") ? "odds too uncertain" : "betting period over"); UIFactory.SetWordWrap(UIFactory.CreateText("bl", row.transform, $"{Trunc(s2, 10)} @{num:F1}x {arg2}", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false), on: false); return; } if (flag) { UIFactory.SetWordWrap(UIFactory.CreateText("bl", row.transform, $"{Trunc(s2, 10)} @{num:F1}x your match", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false), on: false); return; } UIFactory.SetWordWrap(UIFactory.CreateText("bl", row.transform, $"Bet on {Trunc(s2, 10)} @{num:F1}x:", 13f, C_LABEL, 513, (Vector2?)new Vector2(240f, 22f), richText: true, raycastTarget: false), on: false); AddBetButton(row.transform, s.series_id, text, 100); AddBetButton(row.transform, s.series_id, text, 500); AddBetButton(row.transform, s.series_id, text, 2000); } private static void ApplyTeamHeaderRow(GameObject row, ApiClient.ActiveTeamSeriesEntry s) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) string text = "2v2 " + $"{Trunc(s.t1a_name, 7)}({s.t1a_rating})+{Trunc(s.t1b_name, 7)}({s.t1b_rating}) " + $"{s.t1_wins}-{s.t2_wins} " + $"{Trunc(s.t2a_name, 7)}({s.t2a_rating})+{Trunc(s.t2b_name, 7)}({s.t2b_rating})"; object t = UIFactory.CreateText("hdr", row.transform, text, 14f, C_WHITE, 513, (Vector2?)new Vector2(560f, 24f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(t, on: false); UIFactory.SetBold(t, b: true); } private static void ApplyTeamBetRow(GameObject row, ApiClient.ActiveTeamSeriesEntry s, int team) { //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) float num = ((team == 1) ? s.t1_odds : s.t2_odds); string arg = ((team == 1) ? ("Team 1 (" + Trunc(s.t1a_name, 6) + "+" + Trunc(s.t1b_name, 6) + ")") : ("Team 2 (" + Trunc(s.t2a_name, 6) + "+" + Trunc(s.t2b_name, 6) + ")")); string localSteamId = MatchTracker.LocalSteamId; bool flag = !string.IsNullOrEmpty(localSteamId) && (localSteamId == s.t1a_steam || localSteamId == s.t1b_steam || localSteamId == s.t2a_steam || localSteamId == s.t2b_steam); if (s.bets_locked) { string arg2 = ((s.lock_reason == "no_meaningful_odds") ? "odds too uncertain" : "betting period over"); UIFactory.SetWordWrap(UIFactory.CreateText("tbl", row.transform, $"{arg} @{num:F1}x {arg2}", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false), on: false); return; } if (flag) { UIFactory.SetWordWrap(UIFactory.CreateText("tbl", row.transform, $"{arg} @{num:F1}x your match", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false), on: false); return; } UIFactory.SetWordWrap(UIFactory.CreateText("tbl", row.transform, $"Bet on {arg} @{num:F1}x:", 13f, C_LABEL, 513, (Vector2?)new Vector2(240f, 22f), richText: true, raycastTarget: false), on: false); AddTeamBetButton(row.transform, s.series_id, team, 100); AddTeamBetButton(row.transform, s.series_id, team, 500); AddTeamBetButton(row.transform, s.series_id, team, 2000); } private static void AddTeamBetButton(Transform parent, string seriesId, int team, int amount) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown UIFactory.AddLE(UIFactory.CreateButton($"tb{team}_{amount}", parent, $"{amount}g", 11f, C_WHITE, new Color(0.35f, 0.28f, 0.1f, 0.9f), (UnityAction)delegate { string id = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(id) && !(id == "unknown")) { Plugin.Log.LogInfo((object)$"[TEAM-BET] Placing {amount}g on team {team} (series {seriesId})"); ApiClient.PlaceTeamBet(id, seriesId, team, amount, delegate(bool ok, string resp) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0068: Unknown result type (might be due to invalid IL or missing references) Color color = (ok ? new Color(0.4f, 1f, 0.4f) : new Color(1f, 0.5f, 0.5f)); CompetitiveUI.ShowNotification(ok ? $"Bet placed: {amount}g on Team {team}" : ("Bet failed: " + resp), color); if (ok) { ApiClient.FetchActiveTeamSeries(); ApiClient.FetchPlayerStats(id); } }); } }, (Vector2?)new Vector2(44f, 22f)), -1f, -1f, 44f, 22f, 0f, 0f); } private static void AddBetButton(Transform parent, string seriesId, string betOnSteamId, int amount) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown UIFactory.AddLE(UIFactory.CreateButton($"b{amount}", parent, $"{amount}g", 11f, C_WHITE, new Color(0.35f, 0.28f, 0.1f, 0.9f), (UnityAction)delegate { string id = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(id) && !(id == "unknown")) { Plugin.Log.LogInfo((object)$"[BET] Placing {amount}g on {betOnSteamId} (series {seriesId})"); ApiClient.PlaceBet(id, seriesId, betOnSteamId, amount, delegate(bool ok, string resp) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_0058: Unknown result type (might be due to invalid IL or missing references) Color color = (ok ? new Color(0.4f, 1f, 0.4f) : new Color(1f, 0.5f, 0.5f)); CompetitiveUI.ShowNotification(ok ? $"Bet placed: {amount}g" : ("Bet failed: " + resp), color); if (ok) { ApiClient.FetchActiveSeries(); ApiClient.FetchPlayerStats(id); ApiClient.FetchMyBets(id); } }); } }, (Vector2?)new Vector2(44f, 22f)), -1f, -1f, 44f, 22f, 0f, 0f); } private static GameObject BuildShopTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Shop"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 6f, 20, 20, 10, 10); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("SHHdr"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddHLG(val2, 14f); UIFactory.AddLE(val2, -1f, -1f, -1f, 32f, -1f, 0f); UIFactory.CreateText("SHTitle", val2.transform, "Shop", 22f, C_GOLD, 513, (Vector2?)new Vector2(300f, 30f), richText: true, raycastTarget: false); GameObject val3 = new GameObject("SHSp"); val3.transform.SetParent(val2.transform, false); val3.AddComponent(); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, 1f); txtShopBalance = UIFactory.CreateText("SHBal", val2.transform, "Balance: -", 18f, C_GOLD, 516, (Vector2?)new Vector2(320f, 30f), richText: true, raycastTarget: false); UIFactory.SetBold(txtShopBalance, b: true); txtShopStatus = UIFactory.CreateText("SHStatus", val.transform, "", 14f, C_LABEL, 257, (Vector2?)new Vector2(900f, 22f), richText: true, raycastTarget: false); GameObject val4 = new GameObject("SHTabs"); val4.transform.SetParent(val.transform, false); val4.AddComponent(); UIFactory.AddHLG(val4, 6f); UIFactory.AddLE(val4, -1f, 30f, -1f, 30f, -1f, 0f); shopTabBtns = (GameObject[])(object)new GameObject[SHOP_TAB_NAMES.Length]; shopTabTexts = new object[SHOP_TAB_NAMES.Length]; for (int i = 0; i < SHOP_TAB_NAMES.Length; i++) { int idx = i; GameObject val5 = UIFactory.CreateButton($"ShTab{i}", val4.transform, SHOP_TAB_NAMES[i], 14f, C_LABEL, C_TAB, (UnityAction)delegate { shopCategoryFilter = idx; dirty = true; }, (Vector2?)new Vector2(0f, 26f)); if (UIFactory.tLE != null) { Component component = val5.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } UIFactory.AddLE(val5, -1f, 26f, -1f, 26f, 1f, 0f); shopTabBtns[i] = val5; shopTabTexts[i] = UIFactory.GetButtonText(val5); } txtShopCategoryDesc = UIFactory.CreateText("SHDesc", val.transform, SHOP_TAB_DESCS[0], 13f, C_LABEL, 513, (Vector2?)new Vector2(900f, 22f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("SHSV", val.transform, 4f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); shopRowsContainer = scrollViewRefs.content; shopTitlesHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHT", "= TITLES ="); shopTrailsHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHTr", "= TRAILS ="); shopColorsHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHC", "= MAP COLORS ="); shopNametagsHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHN", "= NAME STYLES ="); shopPColorsHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHPC", "= BODY COLORS ="); shopCursorHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHCur", "= CURSOR COLORS ="); shopEffectsHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHEf", "= PLAYER EFFECTS ="); shopOtherHeader = CreateSectionHeader(shopRowsContainer.transform, "SHHOt", "= OTHER ="); for (int num = 0; num < 200; num++) { shopRows.Add(CreateShopRow(shopRowsContainer.transform, num)); } return val; } private static GameObject CreateSectionHeader(Transform parent, string name, string label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 0f, 4, 4, 6, 2); UIFactory.AddLE(val, -1f, -1f, -1f, 30f, -1f, 0f); UIFactory.CreateText(name + "_txt", val.transform, label, 18f, C_WHITE, 513, (Vector2?)new Vector2(600f, 28f), richText: true, raycastTarget: false); return val; } private static ShopRow CreateShopRow(Transform parent, int idx) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Expected O, but got Unknown //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Expected O, but got Unknown //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Expected O, but got Unknown ShopRow shopRow = new ShopRow(); shopRow.root = UIFactory.CreatePanel($"sr{idx}", parent, C_PANEL); UIFactory.AddHLG(shopRow.root, 10f, 10, 10, 6, 6); UIFactory.AddLE(shopRow.root, -1f, -1f, -1f, 44f, -1f, 0f); GameObject val = new GameObject("info"); val.transform.SetParent(shopRow.root.transform, false); val.AddComponent(); UIFactory.AddVLG(val, 0f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, 1f); shopRow.txtName = UIFactory.CreateText($"sn{idx}", val.transform, "", 17f, C_WHITE, 513, (Vector2?)new Vector2(500f, 22f), richText: true, raycastTarget: false); UIFactory.SetBold(shopRow.txtName, b: true); shopRow.txtDesc = UIFactory.CreateText($"sd{idx}", val.transform, "", 13f, C_DIM, 513, (Vector2?)new Vector2(500f, 18f), richText: true, raycastTarget: false); shopRow.txtPrice = UIFactory.CreateText($"sp{idx}", shopRow.root.transform, "", 17f, C_GOLD, 516, (Vector2?)new Vector2(120f, 30f), richText: true, raycastTarget: false); UIFactory.SetBold(shopRow.txtPrice, b: true); int captured = idx; shopRow.buyBtn = UIFactory.CreateButton($"sb{idx}", shopRow.root.transform, "Buy", 14f, C_WHITE, new Color(0.25f, 0.45f, 0.18f, 0.9f), (UnityAction)delegate { try { Plugin.Log.LogInfo((object)$"[SHOP] onClick ENTRY captured={captured}"); ShopRow shopRow2 = shopRows[captured]; if (shopRow2 == null) { Plugin.Log.LogWarning((object)"[SHOP] row is null"); } else { Plugin.Log.LogInfo((object)("[SHOP] row got sku=" + shopRow2.sku)); if (string.IsNullOrEmpty(shopRow2.sku)) { Plugin.Log.LogWarning((object)"[SHOP] empty sku - abort"); } else { string localSteamId = MatchTracker.LocalSteamId; Plugin.Log.LogInfo((object)("[SHOP] steam id=" + localSteamId)); if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { Plugin.Log.LogWarning((object)"[SHOP] no steam id yet - abort"); } else { Plugin.Log.LogInfo((object)"[SHOP] setting status"); UIFactory.SetText(txtShopStatus, "Buying " + shopRow2.sku + "..."); Plugin.Log.LogInfo((object)"[SHOP] calling PurchaseItem"); ApiClient.PurchaseItem(localSteamId, shopRow2.sku, delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)$"[SHOP] purchase complete ok={ok}"); UIFactory.SetText(txtShopStatus, ok ? "Purchased!" : ("Purchase failed: " + resp + "")); dirty = true; }); Plugin.Log.LogInfo((object)"[SHOP] onClick EXIT normally"); } } } } catch (Exception arg) { Plugin.Log.LogError((object)$"[SHOP] onClick threw: {arg}"); } }, (Vector2?)new Vector2(80f, 28f)); UIFactory.AddLE(shopRow.buyBtn, -1f, -1f, 80f, 28f, 0f, 0f); shopRow.buyBtnTxt = UIFactory.GetButtonText(shopRow.buyBtn); shopRow.previewBtn = UIFactory.CreateButton($"spv{idx}", shopRow.root.transform, "Preview", 13f, C_WHITE, new Color(0.25f, 0.4f, 0.55f, 0.9f), (UnityAction)delegate { try { ShopRow shopRow2 = shopRows[captured]; if (shopRow2 != null && !string.IsNullOrEmpty(shopRow2.sku)) { TrailPreview.Toggle(shopRow2.sku, shopRow2.previewColor, shopRow2.previewPrice); dirty = true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[SHOP-PREVIEW] " + ex.Message)); } }, (Vector2?)new Vector2(80f, 28f)); UIFactory.AddLE(shopRow.previewBtn, -1f, -1f, 80f, 28f, 0f, 0f); shopRow.previewBtnTxt = UIFactory.GetButtonText(shopRow.previewBtn); shopRow.setActiveBtn = UIFactory.CreateButton($"sa{idx}", shopRow.root.transform, "Set Active", 13f, C_WHITE, new Color(0.3f, 0.3f, 0.5f, 0.9f), (UnityAction)delegate { try { ShopRow shopRow2 = shopRows[captured]; string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && !(localSteamId == "unknown")) { List cachedShopItems = ApiClient.CachedShopItems; string kind = ""; string text = ""; string sku = shopRow2.sku; string text2 = ""; if (cachedShopItems != null) { foreach (ApiClient.ShopItemData item in cachedShopItems) { if (item.id == shopRow2.itemId) { kind = item.kind; text = item.name; text2 = item.preview_color; break; } } } Plugin.Log.LogInfo((object)("[SHOP] Set Active clicked sku=" + shopRow2.sku + " kind=" + kind)); ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; bool flag = kind == "title" && cachedPlayerStats != null && cachedPlayerStats.active_title == text; bool flag2 = kind == "trail" && cachedPlayerStats != null && cachedPlayerStats.active_trail_sku == sku; long itemId = ((flag || flag2) ? 0 : shopRow2.itemId); if (cachedPlayerStats != null) { if (kind == "title") { if (flag) { cachedPlayerStats.active_title = null; cachedPlayerStats.active_title_color = null; } else { cachedPlayerStats.active_title = text; cachedPlayerStats.active_title_color = text2; } } else if (kind == "trail") { if (flag2) { cachedPlayerStats.active_trail_sku = null; cachedPlayerStats.active_trail_color = null; } else { cachedPlayerStats.active_trail_sku = sku; cachedPlayerStats.active_trail_color = text2; } } else if (kind == "color") { if (cachedPlayerStats.active_color_skus == null) { cachedPlayerStats.active_color_skus = new List(); } if (cachedPlayerStats.active_color_skus.Contains(sku)) { cachedPlayerStats.active_color_skus.Remove(sku); } else { cachedPlayerStats.active_color_skus.Add(sku); } cachedPlayerStats.active_color_sku = ((cachedPlayerStats.active_color_skus.Count > 0) ? cachedPlayerStats.active_color_skus[0] : null); } else if (kind == "nametag") { if (cachedPlayerStats.active_nametag_skus == null) { cachedPlayerStats.active_nametag_skus = new List(); } if (cachedPlayerStats.active_nametag_skus.Contains(sku)) { cachedPlayerStats.active_nametag_skus.Remove(sku); } else { string sub = NametagStyler.GetSubgroup(sku); if (sub != null) { cachedPlayerStats.active_nametag_skus.RemoveAll((string s) => NametagStyler.GetSubgroup(s) == sub); } cachedPlayerStats.active_nametag_skus.Add(sku); } } else if (kind == "player_color") { bool flag3 = cachedPlayerStats.active_player_color_sku == sku; cachedPlayerStats.active_player_color_sku = (flag3 ? null : sku); cachedPlayerStats.active_player_color_hex = (flag3 ? null : text2); cachedPlayerStats.active_player_color_name = (flag3 ? null : text); } else if (kind == "cursor_color") { bool flag4 = cachedPlayerStats.active_cursor_color_sku == sku; cachedPlayerStats.active_cursor_color_sku = (flag4 ? null : sku); cachedPlayerStats.active_cursor_color_hex = (flag4 ? null : text2); } else if (kind == "player_effect") { bool flag5 = cachedPlayerStats.active_player_effect_sku == sku; cachedPlayerStats.active_player_effect_sku = (flag5 ? null : sku); } else if (kind == "utility") { cachedPlayerStats.hide_gold = !cachedPlayerStats.hide_gold; } dirty = true; } Action callback = delegate(bool ok, string resp) { UIFactory.SetText(txtShopStatus, ok ? "Equipped." : ("Failed: " + resp + "")); dirty = true; if (ok && kind == "nametag") { NametagStyler.PublishToPhoton(); } if (ok && kind == "player_color") { try { PlayerColorCosmetic.PublishLocalProps(); } catch { } if (GameStateWatcher.IsInMatch) { try { PlayerColorCosmetic.OnMatchEnd(); PlayerColorCosmetic.OnMatchStart(); } catch { } } } if (ok && kind == "player_effect") { try { PlayerEffectCosmetic.PublishLocalProps(); } catch { } if (GameStateWatcher.IsInMatch) { try { PlayerEffectCosmetic.OnMatchEnd(); PlayerEffectCosmetic.OnMatchStart(); } catch { } } } if (ok && kind == "cursor_color") { try { CursorColorCosmetic.ApplyFromStats(); } catch { } } }; if (kind == "trail") { ApiClient.SetActiveTrail(localSteamId, itemId, callback); } else if (kind == "color") { ApiClient.ToggleMapColor(localSteamId, shopRow2.itemId, callback); } else if (kind == "nametag") { ApiClient.ToggleNametagStyle(localSteamId, shopRow2.itemId, callback); } else if (kind == "player_color") { ApiClient.SetActivePlayerColor(localSteamId, (cachedPlayerStats != null && cachedPlayerStats.active_player_color_sku == sku) ? shopRow2.itemId : 0, callback); } else if (kind == "cursor_color") { ApiClient.SetActiveCursorColor(localSteamId, (cachedPlayerStats != null && cachedPlayerStats.active_cursor_color_sku == sku) ? shopRow2.itemId : 0, callback); } else if (kind == "player_effect") { ApiClient.SetActivePlayerEffect(localSteamId, (cachedPlayerStats != null && cachedPlayerStats.active_player_effect_sku == sku) ? shopRow2.itemId : 0, callback); } else if (kind == "utility") { ApiClient.SetHideGold(localSteamId, cachedPlayerStats?.hide_gold ?? false, callback); } else { ApiClient.SetActiveTitle(localSteamId, itemId, callback); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"[SHOP] setActive threw: {arg}"); } }, (Vector2?)new Vector2(100f, 28f)); UIFactory.AddLE(shopRow.setActiveBtn, -1f, -1f, 100f, 28f, 0f, 0f); shopRow.root.SetActive(false); return shopRow; } private static void RefreshShop() { //IL_007b: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; int num = ((cachedPlayerStats != null) ? (cachedPlayerStats.gold_earned - cachedPlayerStats.gold_spent) : 0); if (txtShopBalance != null) { UIFactory.SetText(txtShopBalance, $"Balance: {num} gold"); } if (shopTabBtns != null) { for (int i = 0; i < shopTabBtns.Length; i++) { if (!((Object)(object)shopTabBtns[i] == (Object)null)) { bool flag = i == shopCategoryFilter; UIFactory.SetImageColor(shopTabBtns[i], flag ? C_TABACT : C_TAB); if (shopTabTexts != null && i < shopTabTexts.Length && shopTabTexts[i] != null) { UIFactory.SetColor(shopTabTexts[i], flag ? C_WHITE : C_LABEL); UIFactory.SetBold(shopTabTexts[i], flag); } } } } if (txtShopCategoryDesc != null) { int num2 = Math.Max(0, Math.Min(shopCategoryFilter, SHOP_TAB_DESCS.Length - 1)); UIFactory.SetText(txtShopCategoryDesc, SHOP_TAB_DESCS[num2]); } List cachedShopItems = ApiClient.CachedShopItems; List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); List list5 = new List(); List list6 = new List(); List list7 = new List(); List list8 = new List(); if (cachedShopItems != null) { foreach (ApiClient.ShopItemData item in cachedShopItems) { if (item.kind == "trail") { list2.Add(item); } else if (item.kind == "color") { list3.Add(item); } else if (item.kind == "nametag") { list4.Add(item); } else if (item.kind == "player_color") { list5.Add(item); } else if (item.kind == "cursor_color") { list6.Add(item); } else if (item.kind == "player_effect") { list7.Add(item); } else if (item.kind == "utility") { list8.Add(item); } else { list.Add(item); } } list.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); list2.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); list3.Sort(delegate(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { int num14 = a.price.CompareTo(b.price); return (num14 != 0) ? num14 : string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase); }); list4.Sort(delegate(ApiClient.ShopItemData a, ApiClient.ShopItemData b) { int num14 = rank(a.sku).CompareTo(rank(b.sku)); if (num14 != 0) { return num14; } int num15 = a.price.CompareTo(b.price); return (num15 != 0) ? num15 : string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase); }); list5.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); list6.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); list7.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); list8.Sort((ApiClient.ShopItemData a, ApiClient.ShopItemData b) => a.price.CompareTo(b.price)); } List list9 = new List(); if (shopCategoryFilter != 0) { if (shopCategoryFilter != 1) { list.Clear(); } if (shopCategoryFilter != 2) { list2.Clear(); } if (shopCategoryFilter != 3) { list3.Clear(); } if (shopCategoryFilter != 4) { list4.Clear(); } if (shopCategoryFilter != 5) { list5.Clear(); } if (shopCategoryFilter != 6) { list6.Clear(); } if (shopCategoryFilter != 7) { list7.Clear(); } if (shopCategoryFilter != 8) { list8.Clear(); } } list9.AddRange(list); list9.AddRange(list2); list9.AddRange(list3); list9.AddRange(list4); list9.AddRange(list5); list9.AddRange(list6); list9.AddRange(list7); list9.AddRange(list8); int num3 = 0; if (list.Count > 0 && (Object)(object)shopTitlesHeader != (Object)null) { shopTitlesHeader.SetActive(true); shopTitlesHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopTitlesHeader != (Object)null) { shopTitlesHeader.SetActive(false); } int num4 = 0; int num5 = 0; while (num5 < list.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list[num5], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num5++; num4++; } if (list2.Count > 0 && (Object)(object)shopTrailsHeader != (Object)null) { shopTrailsHeader.SetActive(true); shopTrailsHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopTrailsHeader != (Object)null) { shopTrailsHeader.SetActive(false); } int num6 = 0; while (num6 < list2.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list2[num6], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num6++; num4++; } if (list3.Count > 0 && (Object)(object)shopColorsHeader != (Object)null) { shopColorsHeader.SetActive(true); shopColorsHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopColorsHeader != (Object)null) { shopColorsHeader.SetActive(false); } int num7 = 0; while (num7 < list3.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list3[num7], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num7++; num4++; } if (list4.Count > 0 && (Object)(object)shopNametagsHeader != (Object)null) { shopNametagsHeader.SetActive(true); shopNametagsHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopNametagsHeader != (Object)null) { shopNametagsHeader.SetActive(false); } int num8 = 0; while (num8 < list4.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list4[num8], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num8++; num4++; } if (list5.Count > 0 && (Object)(object)shopPColorsHeader != (Object)null) { shopPColorsHeader.SetActive(true); shopPColorsHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopPColorsHeader != (Object)null) { shopPColorsHeader.SetActive(false); } int num9 = 0; while (num9 < list5.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list5[num9], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num9++; num4++; } if (list6.Count > 0 && (Object)(object)shopCursorHeader != (Object)null) { shopCursorHeader.SetActive(true); shopCursorHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopCursorHeader != (Object)null) { shopCursorHeader.SetActive(false); } int num10 = 0; while (num10 < list6.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list6[num10], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num10++; num4++; } if (list7.Count > 0 && (Object)(object)shopEffectsHeader != (Object)null) { shopEffectsHeader.SetActive(true); shopEffectsHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopEffectsHeader != (Object)null) { shopEffectsHeader.SetActive(false); } int num11 = 0; while (num11 < list7.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list7[num11], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num11++; num4++; } if (list8.Count > 0 && (Object)(object)shopOtherHeader != (Object)null) { shopOtherHeader.SetActive(true); shopOtherHeader.transform.SetSiblingIndex(num3++); } else if ((Object)(object)shopOtherHeader != (Object)null) { shopOtherHeader.SetActive(false); } int num12 = 0; while (num12 < list8.Count && num4 < shopRows.Count) { ApplyShopRow(shopRows[num4], list8[num12], num, cachedPlayerStats); shopRows[num4].root.transform.SetSiblingIndex(num3++); num12++; num4++; } for (int num13 = list9.Count; num13 < shopRows.Count; num13++) { shopRows[num13].root.SetActive(false); } static int rank(string sku) { if (sku.StartsWith("nametag_neon_", StringComparison.OrdinalIgnoreCase)) { return 2; } string subgroup = NametagStyler.GetSubgroup(sku); if (subgroup == null) { return 0; } return subgroup switch { "color" => 1, "glow" => 3, "size" => 4, _ => 5, }; } } private static void ApplyShopRow(ShopRow r, ApiClient.ShopItemData it, int balance, ApiClient.PlayerStatsData s) { //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_074d: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) r.itemId = it.id; r.sku = it.sku; string text = (string.IsNullOrEmpty(it.preview_color) ? "#FFFFFF" : it.preview_color); UIFactory.SetText(r.txtName, "" + it.name + " (" + it.rarity + ")"); UIFactory.SetBold(r.txtDesc, b: true); if (it.kind == "nametag") { string text2 = s?.display_name; if (string.IsNullOrEmpty(text2)) { text2 = MatchTracker.LocalDisplayName; } if (string.IsNullOrEmpty(text2)) { text2 = "Sid"; } string text3 = NametagStyler.WrapForSku(text2, it.sku); string text4 = ((it.sku == "nametag_bold") ? ("" + text3 + "") : ("" + text3 + "")); string subgroup = NametagStyler.GetSubgroup(it.sku); string text5 = subgroup switch { "typeface" => "one typeface at a time - modded players only", "size" => "one size at a time", "glow" => "one glow at a time - modded players only", "color" => "one color at a time", null => "stackable", _ => "one font at a time", }; UIFactory.SetText(r.txtDesc, "Preview: " + text4 + " (" + text5 + ")"); string sku = ((subgroup == "typeface") ? it.sku : ""); NametagFontRenderer.ApplyFontToLabel(r.txtDesc, sku, shopPreviewOriginalFonts); string sku2 = ((subgroup == "glow") ? it.sku : ""); NametagGlowRenderer.ApplyGlowToLabel(r.txtDesc, sku2, shopPreviewOriginalMats, shopPreviewGlowMatCache); } else { UIFactory.SetText(r.txtDesc, it.description ?? ""); NametagFontRenderer.ApplyFontToLabel(r.txtDesc, "", shopPreviewOriginalFonts); NametagGlowRenderer.ApplyGlowToLabel(r.txtDesc, "", shopPreviewOriginalMats, shopPreviewGlowMatCache); } UIFactory.SetText(r.txtPrice, $"{it.price}g"); bool owned = it.owned; bool flag = balance >= it.price; if (owned) { UIFactory.SetColor(r.txtPrice, C_GREEN); } else if (flag) { UIFactory.SetColor(r.txtPrice, C_GOLD); } else { UIFactory.SetColor(r.txtPrice, C_DIM); } r.buyBtn.SetActive(!owned); if (r.buyBtnTxt != null) { UIFactory.SetText(r.buyBtnTxt, "Buy"); UIFactory.SetColor(r.buyBtnTxt, (Color)(flag ? C_WHITE : new Color(0.55f, 0.55f, 0.6f))); UIFactory.SetImageColor(r.buyBtn, flag ? new Color(0.25f, 0.45f, 0.18f, 0.9f) : new Color(0.25f, 0.25f, 0.28f, 0.8f)); } r.setActiveBtn.SetActive(owned && (it.kind == "title" || it.kind == "trail" || it.kind == "color" || it.kind == "nametag" || it.kind == "player_color" || it.kind == "cursor_color" || it.kind == "player_effect" || it.kind == "utility")); bool num = s != null && it.kind == "title" && s.active_title == it.name; bool flag2 = s != null && it.kind == "trail" && s.active_trail_sku == it.sku; bool flag3 = s != null && it.kind == "color" && s.active_color_skus != null && s.active_color_skus.Contains(it.sku); bool flag4 = s != null && it.kind == "nametag" && s.active_nametag_skus != null && s.active_nametag_skus.Contains(it.sku); bool flag5 = s != null && it.kind == "player_color" && s.active_player_color_sku == it.sku; bool flag6 = s != null && it.kind == "cursor_color" && s.active_cursor_color_sku == it.sku; bool flag7 = s != null && it.kind == "player_effect" && s.active_player_effect_sku == it.sku; bool flag8 = s != null && it.kind == "utility" && it.sku == "util_hide_gold" && s.hide_gold; bool flag9 = num || flag2 || flag3 || flag4 || flag5 || flag6 || flag7 || flag8; if ((Object)(object)r.setActiveBtn != (Object)null) { UIFactory.SetImageColor(r.setActiveBtn, flag9 ? new Color(0.2f, 0.55f, 0.2f, 0.95f) : new Color(0.3f, 0.3f, 0.5f, 0.9f)); object buttonText = UIFactory.GetButtonText(r.setActiveBtn); bool flag10 = it.kind == "nametag" || it.kind == "color"; if (buttonText != null) { if (it.kind == "utility") { UIFactory.SetText(buttonText, flag8 ? "Show Gold" : "Hide Gold"); } else { UIFactory.SetText(buttonText, (!flag9) ? (flag10 ? "Equip" : "Set Active") : (flag10 ? "Remove" : "Unequip")); } } } if ((Object)(object)r.previewBtn != (Object)null) { bool flag11 = it.kind == "trail"; r.previewBtn.SetActive(flag11); if (flag11) { r.previewColor = it.preview_color ?? ""; r.previewPrice = it.price; bool flag12 = TrailPreview.IsActive && TrailPreview.ActiveSku == it.sku; if (r.previewBtnTxt != null) { UIFactory.SetText(r.previewBtnTxt, flag12 ? "Stop" : "Preview"); } UIFactory.SetImageColor(r.previewBtn, flag12 ? new Color(0.5f, 0.3f, 0.25f, 0.9f) : new Color(0.25f, 0.4f, 0.55f, 0.9f)); } } r.root.SetActive(true); } private static GameObject SettingsButton(Transform parent, string name, string label, Color textColor, Color bgColor, Vector2 size, UnityAction onClick) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown GameObject val = new GameObject(name + "_row"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 6f); UIFactory.AddLE(val, -1f, -1f, -1f, size.y + 2f, -1f, 0f); GameObject obj = UIFactory.CreateButton(name, val.transform, label, 14f, textColor, bgColor, onClick, size); UIFactory.AddLE(obj, -1f, -1f, size.x, size.y, 0f, 0f); GameObject val2 = new GameObject("S"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddLE(val2, -1f, -1f, -1f, -1f, 1f); return obj; } private static GameObject BuildSettingsTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Expected O, but got Unknown //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Expected O, but got Unknown //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Expected O, but got Unknown //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Expected O, but got Unknown //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Expected O, but got Unknown //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_068a: Unknown result type (might be due to invalid IL or missing references) //IL_068f: Unknown result type (might be due to invalid IL or missing references) //IL_069e: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0624: Expected O, but got Unknown //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_0754: Unknown result type (might be due to invalid IL or missing references) //IL_0759: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_06b7: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_06c2: Expected O, but got Unknown //IL_07a0: Unknown result type (might be due to invalid IL or missing references) //IL_07aa: Expected O, but got Unknown //IL_0781: Unknown result type (might be due to invalid IL or missing references) //IL_0786: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Expected O, but got Unknown //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Unknown result type (might be due to invalid IL or missing references) //IL_0841: Expected O, but got Unknown //IL_086e: Unknown result type (might be due to invalid IL or missing references) //IL_0873: Unknown result type (might be due to invalid IL or missing references) //IL_0879: Expected O, but got Unknown //IL_08a6: Unknown result type (might be due to invalid IL or missing references) //IL_08ab: Unknown result type (might be due to invalid IL or missing references) //IL_08b1: Expected O, but got Unknown //IL_08de: Unknown result type (might be due to invalid IL or missing references) //IL_08e3: Unknown result type (might be due to invalid IL or missing references) //IL_08e9: Expected O, but got Unknown //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_091b: Unknown result type (might be due to invalid IL or missing references) //IL_0921: Expected O, but got Unknown //IL_094e: Unknown result type (might be due to invalid IL or missing references) //IL_0953: Unknown result type (might be due to invalid IL or missing references) //IL_0959: Expected O, but got Unknown //IL_0986: Unknown result type (might be due to invalid IL or missing references) //IL_098b: Unknown result type (might be due to invalid IL or missing references) //IL_0991: Expected O, but got Unknown //IL_09be: Unknown result type (might be due to invalid IL or missing references) //IL_09c3: Unknown result type (might be due to invalid IL or missing references) //IL_09c9: Expected O, but got Unknown //IL_0a1b: Unknown result type (might be due to invalid IL or missing references) //IL_0a8f: Unknown result type (might be due to invalid IL or missing references) //IL_0aa3: Unknown result type (might be due to invalid IL or missing references) //IL_0acb: Unknown result type (might be due to invalid IL or missing references) //IL_0adf: Unknown result type (might be due to invalid IL or missing references) //IL_0b02: Unknown result type (might be due to invalid IL or missing references) //IL_0b07: Unknown result type (might be due to invalid IL or missing references) //IL_0b16: Unknown result type (might be due to invalid IL or missing references) //IL_09f6: Unknown result type (might be due to invalid IL or missing references) //IL_09fb: Unknown result type (might be due to invalid IL or missing references) //IL_0a01: Expected O, but got Unknown //IL_0b5e: Unknown result type (might be due to invalid IL or missing references) //IL_0bd2: Unknown result type (might be due to invalid IL or missing references) //IL_0be6: Unknown result type (might be due to invalid IL or missing references) //IL_0c0e: Unknown result type (might be due to invalid IL or missing references) //IL_0c22: Unknown result type (might be due to invalid IL or missing references) //IL_0c45: Unknown result type (might be due to invalid IL or missing references) //IL_0c5e: Unknown result type (might be due to invalid IL or missing references) //IL_0c6d: Unknown result type (might be due to invalid IL or missing references) //IL_0b2f: Unknown result type (might be due to invalid IL or missing references) //IL_0b34: Unknown result type (might be due to invalid IL or missing references) //IL_0b3a: Expected O, but got Unknown //IL_0ca2: Unknown result type (might be due to invalid IL or missing references) //IL_0d16: Unknown result type (might be due to invalid IL or missing references) //IL_0d2a: Unknown result type (might be due to invalid IL or missing references) //IL_0d52: Unknown result type (might be due to invalid IL or missing references) //IL_0d66: Unknown result type (might be due to invalid IL or missing references) //IL_0d7d: Unknown result type (might be due to invalid IL or missing references) //IL_0d84: Expected O, but got Unknown //IL_0ded: Unknown result type (might be due to invalid IL or missing references) //IL_0e06: Unknown result type (might be due to invalid IL or missing references) //IL_0c86: Unknown result type (might be due to invalid IL or missing references) //IL_0c8b: Unknown result type (might be due to invalid IL or missing references) //IL_0c91: Expected O, but got Unknown //IL_0e34: Unknown result type (might be due to invalid IL or missing references) //IL_0e86: Unknown result type (might be due to invalid IL or missing references) //IL_0e9f: Unknown result type (might be due to invalid IL or missing references) //IL_0e1f: Unknown result type (might be due to invalid IL or missing references) //IL_0e24: Unknown result type (might be due to invalid IL or missing references) //IL_0e2a: Expected O, but got Unknown //IL_0ecd: Unknown result type (might be due to invalid IL or missing references) //IL_0f2a: Unknown result type (might be due to invalid IL or missing references) //IL_0f2f: Unknown result type (might be due to invalid IL or missing references) //IL_0eb8: Unknown result type (might be due to invalid IL or missing references) //IL_0ebd: Unknown result type (might be due to invalid IL or missing references) //IL_0ec3: Expected O, but got Unknown //IL_0f5d: Unknown result type (might be due to invalid IL or missing references) //IL_0fa9: Unknown result type (might be due to invalid IL or missing references) //IL_0fae: Unknown result type (might be due to invalid IL or missing references) //IL_0fc1: Unknown result type (might be due to invalid IL or missing references) //IL_0feb: Expected O, but got Unknown //IL_1001: Unknown result type (might be due to invalid IL or missing references) //IL_1015: Unknown result type (might be due to invalid IL or missing references) //IL_0f48: Unknown result type (might be due to invalid IL or missing references) //IL_0f4d: Unknown result type (might be due to invalid IL or missing references) //IL_0f53: Expected O, but got Unknown GameObject val = new GameObject("SettingsOuter"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 0f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("SettingsScroll", val.transform, 0f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("Settings"); val2.transform.SetParent(scrollViewRefs.content.transform, false); val2.AddComponent(); UIFactory.AddVLG(val2, 10f, 20, 20, 10, 10); UIFactory.AddLE(val2, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SH", val2.transform, "Settings", 22f, C_GOLD, 258, (Vector2?)new Vector2(600f, 30f), richText: true, raycastTarget: false); GameObject val3 = UIFactory.CreatePanel("SCB", val2.transform, C_PANEL); UIFactory.AddVLG(val3, 4f, 12, 12, 8, 8); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SCL", val3.transform, "Data Consent", 17f, new Color(0.7f, 0.85f, 1f), 257, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); txtConsentStatus = UIFactory.CreateText("SCS", val3.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(700f, 22f), richText: true, raycastTarget: false); Transform transform = val3.transform; Color c_WHITE = C_WHITE; Color c_BTN = C_BTN; Vector2 size = new Vector2(220f, 28f); object obj = <>c.<>9__307_0; if (obj == null) { UnityAction val4 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Consent toggle clicked"); if (Plugin.DataConsentGranted) { Plugin.DataConsent.Value = "denied"; } else { Plugin.DataConsent.Value = "granted"; } ApiClient.OnConsentChanged(); dirty = true; }; <>c.<>9__307_0 = val4; obj = (object)val4; } consentToggleBtn = SettingsButton(transform, "SCT", "Revoke consent", c_WHITE, c_BTN, size, (UnityAction)obj); consentToggleTxt = UIFactory.GetButtonText(consentToggleBtn); GameObject val5 = UIFactory.CreatePanel("SDispB", val2.transform, C_PANEL); UIFactory.AddVLG(val5, 4f, 12, 12, 8, 8); UIFactory.AddLE(val5, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SDispL", val5.transform, "Display", 17f, new Color(0.7f, 0.85f, 1f), 257, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); Transform transform2 = val5.transform; Color c_WHITE2 = C_WHITE; Color c_BTN2 = C_BTN; Vector2 size2 = new Vector2(260f, 28f); object obj2 = <>c.<>9__307_1; if (obj2 == null) { UnityAction val6 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] FPS toggled"); Plugin.ShowFps.Value = !Plugin.ShowFps.Value; dirty = true; }; <>c.<>9__307_1 = val6; obj2 = (object)val6; } fpsToggleBtn = SettingsButton(transform2, "SFPS", "", c_WHITE2, c_BTN2, size2, (UnityAction)obj2); fpsToggleTxt = UIFactory.GetButtonText(fpsToggleBtn); Transform transform3 = val5.transform; Color c_WHITE3 = C_WHITE; Color c_BTN3 = C_BTN; Vector2 size3 = new Vector2(260f, 28f); object obj3 = <>c.<>9__307_2; if (obj3 == null) { UnityAction val7 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Ping/region toggled"); Plugin.ShowRegionPing.Value = !Plugin.ShowRegionPing.Value; dirty = true; }; <>c.<>9__307_2 = val7; obj3 = (object)val7; } pingToggleBtn = SettingsButton(transform3, "SPing", "", c_WHITE3, c_BTN3, size3, (UnityAction)obj3); pingToggleTxt = UIFactory.GetButtonText(pingToggleBtn); Transform transform4 = val5.transform; Color c_WHITE4 = C_WHITE; Color c_BTN4 = C_BTN; Vector2 size4 = new Vector2(260f, 28f); object obj4 = <>c.<>9__307_3; if (obj4 == null) { UnityAction val8 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] In-game chat overlay toggled"); Plugin.ShowIngameChat.Value = !Plugin.ShowIngameChat.Value; dirty = true; }; <>c.<>9__307_3 = val8; obj4 = (object)val8; } ingameChatToggleBtn = SettingsButton(transform4, "SIgChat", "", c_WHITE4, c_BTN4, size4, (UnityAction)obj4); ingameChatToggleTxt = UIFactory.GetButtonText(ingameChatToggleBtn); Transform transform5 = val5.transform; Color c_WHITE5 = C_WHITE; Color c_BTN5 = C_BTN; Vector2 size5 = new Vector2(260f, 28f); object obj5 = <>c.<>9__307_4; if (obj5 == null) { UnityAction val9 = delegate { CursorColorCosmetic.CycleShape(); dirty = true; }; <>c.<>9__307_4 = val9; obj5 = (object)val9; } cursorShapeBtn = SettingsButton(transform5, "SCursor", "", c_WHITE5, c_BTN5, size5, (UnityAction)obj5); cursorShapeTxt = UIFactory.GetButtonText(cursorShapeBtn); Transform transform6 = val5.transform; Color c_WHITE6 = C_WHITE; Color c_BTN6 = C_BTN; Vector2 size6 = new Vector2(260f, 28f); object obj6 = <>c.<>9__307_5; if (obj6 == null) { UnityAction val10 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Trails toggled"); Plugin.ShowTrails.Value = !Plugin.ShowTrails.Value; if (Plugin.ShowTrails.Value) { if (GameStateWatcher.IsInMatch) { TrailCosmetic.OnMatchStart(); } } else { TrailCosmetic.OnMatchEnd(); } dirty = true; }; <>c.<>9__307_5 = val10; obj6 = (object)val10; } trailToggleBtn = SettingsButton(transform6, "STrail", "", c_WHITE6, c_BTN6, size6, (UnityAction)obj6); trailToggleTxt = UIFactory.GetButtonText(trailToggleBtn); UIFactory.CreateText("SBlkDbgL", val5.transform, "Block debug overlay (corner): live act/succ counters + per-hit timing (too early / too slow / unblockable).", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 34f), richText: true, raycastTarget: false); Transform transform7 = val5.transform; Color c_WHITE7 = C_WHITE; Color c_BTN7 = C_BTN; Vector2 size7 = new Vector2(260f, 28f); object obj7 = <>c.<>9__307_6; if (obj7 == null) { UnityAction val11 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Block debug overlay toggled"); Plugin.ShowBlockDebug.Value = !Plugin.ShowBlockDebug.Value; dirty = true; }; <>c.<>9__307_6 = val11; obj7 = (object)val11; } blockDbgToggleBtn = SettingsButton(transform7, "SBlkDbg", "", c_WHITE7, c_BTN7, size7, (UnityAction)obj7); blockDbgToggleTxt = UIFactory.GetButtonText(blockDbgToggleBtn); UIFactory.CreateText("SPColorL", val5.transform, "Custom player body colors: render shop-purchased Body Colors on yourself + other modded players. Off = everyone falls back to default orange/blue.", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 34f), richText: true, raycastTarget: false); Transform transform8 = val5.transform; Color c_WHITE8 = C_WHITE; Color c_BTN8 = C_BTN; Vector2 size8 = new Vector2(260f, 28f); object obj8 = <>c.<>9__307_7; if (obj8 == null) { UnityAction val12 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Custom player colors toggled"); Plugin.ShowPlayerColors.Value = !Plugin.ShowPlayerColors.Value; try { PlayerColorCosmetic.OnShowPlayerColorsToggled(); } catch { } try { PlayerEffectCosmetic.OnShowPlayerColorsToggled(); } catch { } dirty = true; }; <>c.<>9__307_7 = val12; obj8 = (object)val12; } playerColorToggleBtn = SettingsButton(transform8, "SPColor", "", c_WHITE8, c_BTN8, size8, (UnityAction)obj8); playerColorToggleTxt = UIFactory.GetButtonText(playerColorToggleBtn); UIFactory.CreateText("SInpOvL", val5.transform, "Input overlay (bottom-left): shows W/A/S/D/Space and L/R click. Keys glow red when pressed. Useful for streams or diagnosing missed inputs.", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 34f), richText: true, raycastTarget: false); Transform transform9 = val5.transform; Color c_WHITE9 = C_WHITE; Color c_BTN9 = C_BTN; Vector2 size9 = new Vector2(260f, 28f); object obj9 = <>c.<>9__307_8; if (obj9 == null) { UnityAction val13 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Input overlay toggled"); Plugin.ShowInputOverlay.Value = !Plugin.ShowInputOverlay.Value; dirty = true; }; <>c.<>9__307_8 = val13; obj9 = (object)val13; } inputOverlayToggleBtn = SettingsButton(transform9, "SInpOv", "", c_WHITE9, c_BTN9, size9, (UnityAction)obj9); inputOverlayToggleTxt = UIFactory.GetButtonText(inputOverlayToggleBtn); GameObject val14 = UIFactory.CreatePanel("SPerfB", val5.transform, C_PANEL); UIFactory.AddVLG(val14, 2f, 8, 8, 6, 6); UIFactory.AddLE(val14, -1f, -1f, -1f, -1f, -1f, 0f); Transform transform10 = val14.transform; Color textColor = new Color(1f, 0.85f, 0.4f); Color c_BTN10 = C_BTN; Vector2 size10 = new Vector2(700f, 28f); object obj10 = <>c.<>9__307_9; if (obj10 == null) { UnityAction val15 = delegate { _perfSectionOpen = !_perfSectionOpen; if ((Object)(object)_perfSectionBody != (Object)null) { _perfSectionBody.SetActive(_perfSectionOpen); } dirty = true; }; <>c.<>9__307_9 = val15; obj10 = (object)val15; } _perfSectionHeaderTxt = UIFactory.GetButtonText(SettingsButton(transform10, "SPerfH", "", textColor, c_BTN10, size10, (UnityAction)obj10)); _perfSectionBody = new GameObject("SPerfBody"); _perfSectionBody.transform.SetParent(val14.transform, false); _perfSectionBody.AddComponent(); UIFactory.AddVLG(_perfSectionBody, 3f, 4, 4, 4, 4); UIFactory.AddLE(_perfSectionBody, -1f, -1f, -1f, -1f, -1f, 0f); _perfSectionBody.SetActive(_perfSectionOpen); object obj11 = <>c.<>9__307_11; if (obj11 == null) { UnityAction val16 = delegate { if (Plugin.PerfOptimizations != null) { Plugin.PerfOptimizations.Value = !Plugin.PerfOptimizations.Value; dirty = true; } }; <>c.<>9__307_11 = val16; obj11 = (object)val16; } AddPerfRow("Master", "Performance master switch — flips ALL the patches below at once.", (UnityAction)obj11, out perfMasterBtn, out perfMasterTxt); object obj12 = <>c.<>9__307_12; if (obj12 == null) { UnityAction val17 = delegate { if (Plugin.PerfStunPlayerNullGuard != null) { Plugin.PerfStunPlayerNullGuard.Value = !Plugin.PerfStunPlayerNullGuard.Value; dirty = true; } }; <>c.<>9__307_12 = val17; obj12 = (object)val17; } AddPerfRow("Stun", "StunPlayer null-guard — stops NRE spam when a player is destroyed mid-stun.", (UnityAction)obj12, out perfStunBtn, out perfStunTxt); object obj13 = <>c.<>9__307_13; if (obj13 == null) { UnityAction val18 = delegate { if (Plugin.PerfDespawnOffscreenBullets != null) { Plugin.PerfDespawnOffscreenBullets.Value = !Plugin.PerfDespawnOffscreenBullets.Value; dirty = true; } }; <>c.<>9__307_13 = val18; obj13 = (object)val18; } AddPerfRow("OOB", "Despawn off-screen bullets — host clears bullets that exit the camera viewport.", (UnityAction)obj13, out perfBulletsBtn, out perfBulletsTxt); object obj14 = <>c.<>9__307_14; if (obj14 == null) { UnityAction val19 = delegate { if (Plugin.PerfSwallowHitSoundNREs != null) { Plugin.PerfSwallowHitSoundNREs.Value = !Plugin.PerfSwallowHitSoundNREs.Value; dirty = true; } }; <>c.<>9__307_14 = val19; obj14 = (object)val19; } AddPerfRow("HitSnd", "Swallow RayHitBulletSound NREs from destroyed parents.", (UnityAction)obj14, out perfHitSndBtn, out perfHitSndTxt); object obj15 = <>c.<>9__307_15; if (obj15 == null) { UnityAction val20 = delegate { if (Plugin.PerfSwallowEdgeBounceNREs != null) { Plugin.PerfSwallowEdgeBounceNREs.Value = !Plugin.PerfSwallowEdgeBounceNREs.Value; dirty = true; } }; <>c.<>9__307_15 = val20; obj15 = (object)val20; } AddPerfRow("EdgeBn", "Swallow ScreenEdgeBounce NREs from destroyed bullets.", (UnityAction)obj15, out perfEdgeBnBtn, out perfEdgeBnTxt); object obj16 = <>c.<>9__307_16; if (obj16 == null) { UnityAction val21 = delegate { if (Plugin.PerfSkipMenuUpdateInMatch != null) { Plugin.PerfSkipMenuUpdateInMatch.Value = !Plugin.PerfSkipMenuUpdateInMatch.Value; dirty = true; } }; <>c.<>9__307_16 = val21; obj16 = (object)val21; } AddPerfRow("Menu", "Skip MenuControllerHandler.Update during an active match.", (UnityAction)obj16, out perfMenuBtn, out perfMenuTxt); object obj17 = <>c.<>9__307_17; if (obj17 == null) { UnityAction val22 = delegate { if (Plugin.PerfBulletHitParticleCap != null) { Plugin.PerfBulletHitParticleCap.Value = !Plugin.PerfBulletHitParticleCap.Value; dirty = true; } }; <>c.<>9__307_17 = val22; obj17 = (object)val22; } AddPerfRow("BulletCap", "Cap bullet-hit particles at 2/frame — biggest user-visible win on heavy firefights.", (UnityAction)obj17, out perfBulletCapBtn, out perfBulletCapTxt); object obj18 = <>c.<>9__307_18; if (obj18 == null) { UnityAction val23 = delegate { if (Plugin.PerfClampObjectPoolInit != null) { Plugin.PerfClampObjectPoolInit.Value = !Plugin.PerfClampObjectPoolInit.Value; dirty = true; } }; <>c.<>9__307_18 = val23; obj18 = (object)val23; } AddPerfRow("PoolInit", "Clamp ObjectPool init-spawn to 4 in-match — reduces frame stutter from new pool allocation.", (UnityAction)obj18, out perfPoolBtn, out perfPoolTxt); object obj19 = <>c.<>9__307_19; if (obj19 == null) { UnityAction val24 = delegate { if (Plugin.PerfPauseCardPickParticles != null) { Plugin.PerfPauseCardPickParticles.Value = !Plugin.PerfPauseCardPickParticles.Value; dirty = true; } }; <>c.<>9__307_19 = val24; obj19 = (object)val24; } AddPerfRow("CardPickPart", "Pause player-skin particles during the card pick UI — saves CPU on long picks.", (UnityAction)obj19, out perfCardPickBtn, out perfCardPickTxt); GameObject val25 = UIFactory.CreatePanel("SNB", val2.transform, C_PANEL); UIFactory.AddVLG(val25, 4f, 12, 12, 8, 8); UIFactory.AddLE(val25, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SNL", val25.transform, "Chat log notifications", 17f, new Color(0.7f, 0.85f, 1f), 257, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); UIFactory.CreateText("SND", val25.transform, "On-screen pop-ups for incoming chat + XP / level notifications. Chat log in My Stats still updates either way.", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 34f), richText: true, raycastTarget: false); Transform transform11 = val25.transform; Color c_WHITE10 = C_WHITE; Color c_BTN11 = C_BTN; Vector2 size11 = new Vector2(260f, 28f); object obj20 = <>c.<>9__307_20; if (obj20 == null) { UnityAction val26 = delegate { Plugin.Log.LogInfo((object)"[SETTINGS] Notifications toggled"); Plugin.ShowNotifications.Value = !Plugin.ShowNotifications.Value; dirty = true; }; <>c.<>9__307_20 = val26; obj20 = (object)val26; } notifToggleBtn = SettingsButton(transform11, "SNT", "", c_WHITE10, c_BTN11, size11, (UnityAction)obj20); notifToggleTxt = UIFactory.GetButtonText(notifToggleBtn); GameObject val27 = UIFactory.CreatePanel("SBugB", val2.transform, C_PANEL); UIFactory.AddVLG(val27, 4f, 12, 12, 8, 8); UIFactory.AddLE(val27, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SBugL", val27.transform, "Report a bug", 17f, new Color(1f, 0.9f, 0.6f), 257, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); UIFactory.CreateText("SBugD", val27.transform, "Send a bug report straight to the mod team — description, severity, and optionally your game logs. Use the Preview button to see what gets attached.", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 38f), richText: true, raycastTarget: false); Transform transform12 = val27.transform; Color c_WHITE11 = C_WHITE; Color bgColor = new Color(0.2f, 0.3f, 0.45f, 0.9f); Vector2 size12 = new Vector2(260f, 28f); object obj21 = <>c.<>9__307_21; if (obj21 == null) { UnityAction val28 = delegate { CompetitiveUI.OpenBugReportModal(); }; <>c.<>9__307_21 = val28; obj21 = (object)val28; } SettingsButton(transform12, "SBugBtn", "Open Report Form", c_WHITE11, bgColor, size12, (UnityAction)obj21); GameObject val29 = UIFactory.CreatePanel("SDB", val2.transform, C_PANEL); UIFactory.AddVLG(val29, 4f, 12, 12, 8, 8); UIFactory.AddLE(val29, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("SDL", val29.transform, "Delete My Data", 17f, new Color(1f, 0.6f, 0.6f), 257, (Vector2?)new Vector2(700f, 24f), richText: true, raycastTarget: false); UIFactory.CreateText("SDD", val29.transform, "Anonymizes your Steam ID, display name, and Discord link. Matches stay so other players' Elo and histories aren't affected. You will no longer appear on leaderboards.\nIRREVERSIBLE: this Steam ID can never re-register. Future matches from this account will show as [Deleted User] and won't count toward stats.", 13f, C_DIM, 257, (Vector2?)new Vector2(700f, 68f), richText: true, raycastTarget: false); GameObject val30 = new GameObject("SDR"); val30.transform.SetParent(val29.transform, false); val30.AddComponent(); UIFactory.AddHLG(val30, 8f); UIFactory.AddLE(val30, -1f, -1f, -1f, 30f, -1f, 0f); Transform transform13 = val30.transform; Color c_WHITE12 = C_WHITE; Color bgColor2 = new Color(0.45f, 0.18f, 0.18f, 0.9f); object obj22 = <>c.<>9__307_22; if (obj22 == null) { UnityAction val31 = delegate { if (ClickGuard.Claim()) { deleteArmed = true; dirty = true; } }; <>c.<>9__307_22 = val31; obj22 = (object)val31; } deleteBtn = UIFactory.CreateButton("SDBtn", transform13, "Delete my data...", 14f, c_WHITE12, bgColor2, (UnityAction)obj22, (Vector2?)new Vector2(200f, 28f)); UIFactory.AddLE(deleteBtn, -1f, -1f, 200f, 28f, 0f, 0f); Transform transform14 = val30.transform; Color c_WHITE13 = C_WHITE; Color bgColor3 = new Color(0.7f, 0.15f, 0.15f, 0.95f); object obj23 = <>c.<>9__307_23; if (obj23 == null) { UnityAction val32 = delegate { if (ClickGuard.Claim()) { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && !(localSteamId == "unknown")) { deleteArmed = false; ApiClient.DeletePlayerData(localSteamId, delegate(bool ok, string msg) { Plugin.Log.LogInfo((object)$"[PRIVACY] Delete result: ok={ok} msg={msg}"); if (ok) { Plugin.DataConsent.Value = "denied"; ApiClient.OnConsentChanged(); if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Your data has been anonymized. Consent is now Denied."); } } else if (txtDeleteStatus != null) { UIFactory.SetText(txtDeleteStatus, "Deletion failed: " + msg + ""); } dirty = true; }); } } }; <>c.<>9__307_23 = val32; obj23 = (object)val32; } confirmDeleteBtn = UIFactory.CreateButton("SDCBtn", transform14, "Confirm - really delete", 14f, c_WHITE13, bgColor3, (UnityAction)obj23, (Vector2?)new Vector2(220f, 28f)); UIFactory.AddLE(confirmDeleteBtn, -1f, -1f, 220f, 28f, 0f, 0f); confirmDeleteBtn.SetActive(false); Transform transform15 = val30.transform; Color c_LABEL = C_LABEL; Color c_BTN12 = C_BTN; object obj24 = <>c.<>9__307_24; if (obj24 == null) { UnityAction val33 = delegate { if (ClickGuard.Claim()) { deleteArmed = false; dirty = true; } }; <>c.<>9__307_24 = val33; obj24 = (object)val33; } cancelDelBtn = UIFactory.CreateButton("SDXBtn", transform15, "Cancel", 14f, c_LABEL, c_BTN12, (UnityAction)obj24, (Vector2?)new Vector2(90f, 28f)); UIFactory.AddLE(cancelDelBtn, -1f, -1f, 90f, 28f, 0f, 0f); cancelDelBtn.SetActive(false); GameObject val34 = new GameObject("SDSp"); val34.transform.SetParent(val30.transform, false); val34.AddComponent(); UIFactory.AddLE(val34, -1f, -1f, -1f, -1f, 1f); txtDeleteStatus = UIFactory.CreateText("SDS", val29.transform, "", 14f, C_LABEL, 257, (Vector2?)new Vector2(700f, 22f), richText: true, raycastTarget: false); return val; static void AddPerfRow(string id, string label, UnityAction onClick, out GameObject btnOut, out object txtOut) { //IL_002a: 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_006b: 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_007f: Unknown result type (might be due to invalid IL or missing references) UIFactory.CreateText("SPerfL_" + id, _perfSectionBody.transform, "" + label + "", 12f, C_DIM, 257, (Vector2?)new Vector2(700f, 18f), richText: true, raycastTarget: false); btnOut = SettingsButton(_perfSectionBody.transform, "SPerf_" + id, "", C_WHITE, C_BTN, new Vector2(280f, 22f), onClick); txtOut = UIFactory.GetButtonText(btnOut); } } private static void RefreshSettings() { if (txtConsentStatus != null) { UIFactory.SetText(s: Plugin.DataConsentGranted ? "Status: Allowed - match data and linking are active." : ((!Plugin.DataConsentAsked) ? "Status: Unset - the consent prompt will appear on next launch." : "Status: Denied - mod runs offline. No data leaves your machine."), t: txtConsentStatus); } if (consentToggleTxt != null) { UIFactory.SetText(consentToggleTxt, Plugin.DataConsentGranted ? "Revoke consent" : "Allow data reporting"); } if ((Object)(object)deleteBtn != (Object)null) { deleteBtn.SetActive(!deleteArmed); } if ((Object)(object)confirmDeleteBtn != (Object)null) { confirmDeleteBtn.SetActive(deleteArmed); } if ((Object)(object)cancelDelBtn != (Object)null) { cancelDelBtn.SetActive(deleteArmed); } if (notifToggleTxt != null) { UIFactory.SetText(notifToggleTxt, Plugin.ShowNotifications.Value ? "Chat notifications: ON" : "Chat notifications: OFF"); } if (fpsToggleTxt != null && Plugin.ShowFps != null) { UIFactory.SetText(fpsToggleTxt, Plugin.ShowFps.Value ? "FPS counter: ON" : "FPS counter: OFF"); } if (pingToggleTxt != null && Plugin.ShowRegionPing != null) { UIFactory.SetText(pingToggleTxt, Plugin.ShowRegionPing.Value ? "Ping / region display: ON" : "Ping / region display: OFF"); } if (ingameChatToggleTxt != null && Plugin.ShowIngameChat != null) { UIFactory.SetText(ingameChatToggleTxt, Plugin.ShowIngameChat.Value ? "In-game chat overlay: ON" : "In-game chat overlay: OFF"); } if (cursorShapeTxt != null) { UIFactory.SetText(cursorShapeTxt, "Cursor: " + CursorColorCosmetic.CurrentShapeLabel() + ""); } if (trailToggleTxt != null && Plugin.ShowTrails != null) { UIFactory.SetText(trailToggleTxt, Plugin.ShowTrails.Value ? "Cosmetic trails: ON" : "Cosmetic trails: OFF"); } if (blockDbgToggleTxt != null && Plugin.ShowBlockDebug != null) { UIFactory.SetText(blockDbgToggleTxt, Plugin.ShowBlockDebug.Value ? "Block debug overlay: ON" : "Block debug overlay: OFF"); } if (playerColorToggleTxt != null && Plugin.ShowPlayerColors != null) { UIFactory.SetText(playerColorToggleTxt, Plugin.ShowPlayerColors.Value ? "Custom player body colors: ON" : "Custom player body colors: OFF"); } if (inputOverlayToggleTxt != null && Plugin.ShowInputOverlay != null) { UIFactory.SetText(inputOverlayToggleTxt, Plugin.ShowInputOverlay.Value ? "Input overlay: ON" : "Input overlay: OFF"); } if (_perfSectionHeaderTxt != null) { int num = 0; int num2 = 8; ConfigEntry perfStunPlayerNullGuard = Plugin.PerfStunPlayerNullGuard; if (perfStunPlayerNullGuard != null && perfStunPlayerNullGuard.Value) { num++; } ConfigEntry perfDespawnOffscreenBullets = Plugin.PerfDespawnOffscreenBullets; if (perfDespawnOffscreenBullets != null && perfDespawnOffscreenBullets.Value) { num++; } ConfigEntry perfSwallowHitSoundNREs = Plugin.PerfSwallowHitSoundNREs; if (perfSwallowHitSoundNREs != null && perfSwallowHitSoundNREs.Value) { num++; } ConfigEntry perfSwallowEdgeBounceNREs = Plugin.PerfSwallowEdgeBounceNREs; if (perfSwallowEdgeBounceNREs != null && perfSwallowEdgeBounceNREs.Value) { num++; } ConfigEntry perfSkipMenuUpdateInMatch = Plugin.PerfSkipMenuUpdateInMatch; if (perfSkipMenuUpdateInMatch != null && perfSkipMenuUpdateInMatch.Value) { num++; } ConfigEntry perfBulletHitParticleCap = Plugin.PerfBulletHitParticleCap; if (perfBulletHitParticleCap != null && perfBulletHitParticleCap.Value) { num++; } ConfigEntry perfClampObjectPoolInit = Plugin.PerfClampObjectPoolInit; if (perfClampObjectPoolInit != null && perfClampObjectPoolInit.Value) { num++; } ConfigEntry perfPauseCardPickParticles = Plugin.PerfPauseCardPickParticles; if (perfPauseCardPickParticles != null && perfPauseCardPickParticles.Value) { num++; } ConfigEntry perfOptimizations = Plugin.PerfOptimizations; string text = ((perfOptimizations != null && perfOptimizations.Value) ? $"{num}/{num2} active" : "MASTER OFF"); string text2 = (_perfSectionOpen ? "v" : ">"); UIFactory.SetText(_perfSectionHeaderTxt, "" + text2 + " Performance patches " + text); } SetPerfRow(perfMasterTxt, Plugin.PerfOptimizations, "Master"); SetPerfRow(perfStunTxt, Plugin.PerfStunPlayerNullGuard, "Stun null-guard"); SetPerfRow(perfBulletsTxt, Plugin.PerfDespawnOffscreenBullets, "OOB bullet despawn"); SetPerfRow(perfHitSndTxt, Plugin.PerfSwallowHitSoundNREs, "Hit-sound NRE swallow"); SetPerfRow(perfEdgeBnTxt, Plugin.PerfSwallowEdgeBounceNREs, "EdgeBounce NRE swallow"); SetPerfRow(perfMenuTxt, Plugin.PerfSkipMenuUpdateInMatch, "Menu update bail"); SetPerfRow(perfBulletCapTxt, Plugin.PerfBulletHitParticleCap, "Bullet-hit particle cap (2/frame)"); SetPerfRow(perfPoolTxt, Plugin.PerfClampObjectPoolInit, "ObjectPool init clamp (in-match)"); SetPerfRow(perfCardPickTxt, Plugin.PerfPauseCardPickParticles, "Pause skin particles during card pick"); static void SetPerfRow(object txt, ConfigEntry e, string label) { if (txt != null) { if (e == null) { UIFactory.SetText(txt, label + ": (not bound)"); } else { UIFactory.SetText(txt, e.Value ? (label + ": ON") : (label + ": OFF")); } } } } private static void RefreshRecentSeries() { if (txtRecentSeries == null) { return; } List cachedRecentSeries = ApiClient.CachedRecentSeries; if (cachedRecentSeries == null || cachedRecentSeries.Count == 0) { UIFactory.SetText(txtRecentSeries, "No recent series"); if ((Object)(object)seriesPrev != (Object)null) { seriesPrev.SetActive(false); } if ((Object)(object)seriesNext != (Object)null) { seriesNext.SetActive(false); } if (txtSeriesPage != null) { UIFactory.SetText(txtSeriesPage, ""); } return; } int num = 20; int num2 = (cachedRecentSeries.Count + num - 1) / num; recentSeriesPage = Math.Max(0, Math.Min(recentSeriesPage, num2 - 1)); int num3 = recentSeriesPage * num; int num4 = Math.Min(num3 + num, cachedRecentSeries.Count); string text = ""; string text2 = ApiClient.CachedPlayerStats?.display_name ?? ""; for (int i = num3; i < num4; i++) { ApiClient.RecentSeriesEntry recentSeriesEntry = cachedRecentSeries[i]; bool num5 = recentSeriesEntry.p1_wins > recentSeriesEntry.p2_wins; string text3 = (num5 ? recentSeriesEntry.p1_name : recentSeriesEntry.p2_name); string text4 = (num5 ? recentSeriesEntry.p2_name : recentSeriesEntry.p1_name); int num6 = (num5 ? recentSeriesEntry.p1_wins : recentSeriesEntry.p2_wins); int num7 = (num5 ? recentSeriesEntry.p2_wins : recentSeriesEntry.p1_wins); int num8 = (num5 ? recentSeriesEntry.p1_rating : recentSeriesEntry.p2_rating); int num9 = (num5 ? recentSeriesEntry.p2_rating : recentSeriesEntry.p1_rating); float num10 = (num5 ? recentSeriesEntry.p1_rating_change : recentSeriesEntry.p2_rating_change); float num11 = (num5 ? recentSeriesEntry.p2_rating_change : recentSeriesEntry.p1_rating_change); bool num12 = text3 == text2; bool flag = text4 == text2; string text5 = (num12 ? "#00FF00" : "#FFFFFF"); string text6 = (flag ? "#FF6666" : "#AAAAAA"); string text7 = ((num10 != 0f) ? $" +{num10:F0}" : ""); string text8 = ((num11 != 0f) ? $" {num11:F0}" : ""); string text9 = ((num8 > 0) ? $" ({num8})" : ""); string text10 = ((num9 > 0) ? $" ({num9})" : ""); text += $"{Trunc(text3, 12)}{text9}{text7} {num6}-{num7} {Trunc(text4, 12)}{text10}{text8}\n"; if (recentSeriesEntry.bets == null || recentSeriesEntry.bets.Count <= 0) { continue; } foreach (ApiClient.SeriesBetEntry bet in recentSeriesEntry.bets) { string text11 = ((bet.bettor_name == text2) ? "You" : Trunc(bet.bettor_name ?? "?", 14)); text = ((!bet.won) ? (text + string.Format(" -> {0} bet {1}g on {2} - lost\n", text11, bet.amount, Trunc(bet.bet_on_name ?? "?", 12))) : (text + string.Format(" -> {0} bet {1}g on {2} -> +{3}g\n", text11, bet.amount, Trunc(bet.bet_on_name ?? "?", 12), bet.payout))); } } UIFactory.SetText(txtRecentSeries, text); if ((Object)(object)seriesPrev != (Object)null) { seriesPrev.SetActive(recentSeriesPage > 0); } if ((Object)(object)seriesNext != (Object)null) { seriesNext.SetActive(recentSeriesPage < num2 - 1); } if (txtSeriesPage != null) { UIFactory.SetText(txtSeriesPage, (num2 > 1) ? $"{recentSeriesPage + 1}/{num2}" : ""); } } private static void RefreshVersionStatus() { if (txtVersionStatus == null) { return; } if (ApiClient.ForceUpdateRequired) { UIFactory.SetText(txtVersionStatus, "UPDATE REQUIRED - server is rejecting this mod version"); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(true); } return; } if (ApiClient.UpdateReady) { UIFactory.SetText(txtVersionStatus, "Close ROUNDS to apply update"); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(false); } return; } if (ApiClient.IsUpdating) { UIFactory.SetText(txtVersionStatus, "Downloading..."); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(false); } return; } string latestModVersion = ApiClient.LatestModVersion; if (latestModVersion == null) { UIFactory.SetText(txtVersionStatus, ""); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(false); } } else if (latestModVersion == "1.28.2") { UIFactory.SetText(txtVersionStatus, "up to date"); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(false); } } else { UIFactory.SetText(txtVersionStatus, "v" + latestModVersion + " available!"); if ((Object)(object)updateBtn != (Object)null) { updateBtn.SetActive(true); } } } private static void RefreshMyStats() { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; if (cachedPlayerStats == null) { UIFactory.SetText(txtRating, "-"); return; } if (txtTopLeftName != null) { string s = ((!string.IsNullOrEmpty(cachedPlayerStats.display_name) && cachedPlayerStats.display_name != cachedPlayerStats.steam_id) ? cachedPlayerStats.display_name : (MatchTracker.LocalDisplayName ?? cachedPlayerStats.display_name ?? "")); UIFactory.SetText(txtTopLeftName, s); } UIFactory.SetText(txtRating, $"{cachedPlayerStats.rating:F0}"); UIFactory.SetText(txtRD, $"RD: {cachedPlayerStats.rating_deviation:F0} Peak: {cachedPlayerStats.peak_rating:F0}"); UIFactory.SetText(txtLevel, $"Level {cachedPlayerStats.level}"); if (cachedPlayerStats.level < 100 && cachedPlayerStats.xp_for_next_level > 0) { UIFactory.SetText(txtXPProg, $"{cachedPlayerStats.xp_into_level}/{cachedPlayerStats.xp_for_next_level} XP"); UIFactory.SetFill(xpFill, (float)cachedPlayerStats.xp_into_level / (float)cachedPlayerStats.xp_for_next_level); } else { UIFactory.SetText(txtXPProg, "MAX"); UIFactory.SetFill(xpFill, 1f); } UIFactory.SetText(txtTotalXP, $"{cachedPlayerStats.total_xp:N0} XP"); List cachedMatchHistory = ApiClient.CachedMatchHistory; List list = cachedMatchHistory?.FindAll((ApiClient.MatchHistoryEntry m) => m.is_ranked) ?? new List(); List list2 = cachedMatchHistory?.FindAll((ApiClient.MatchHistoryEntry m) => !m.is_ranked) ?? new List(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; foreach (ApiClient.MatchHistoryEntry item in list2) { if (item.won) { num++; } else { num2++; } } if (cachedMatchHistory != null) { foreach (ApiClient.MatchHistoryEntry item2 in cachedMatchHistory) { if (item2.won && item2.opponent_rounds_won == 0) { num3++; } if (!item2.won && item2.player_rounds_won == 0) { num4++; } } } int ranked_series_wins = cachedPlayerStats.ranked_series_wins; int ranked_series_losses = cachedPlayerStats.ranked_series_losses; UIFactory.SetText(txtRankedRec, (ranked_series_wins + ranked_series_losses > 0) ? $"Ranked: {ranked_series_wins}W / {ranked_series_losses}L ({((ranked_series_losses > 0) ? $"{(float)ranked_series_wins / (float)ranked_series_losses:F1}" : $"{ranked_series_wins}:0")})" : "Ranked: -"); if (list.Count > 0) { int num5 = CalcStreak(list); string text = ((num5 > 0) ? "#00FF00" : "#FF6666"); UIFactory.SetText(txtRankedStrk, " Streak: " + ((num5 > 0) ? $"{num5}W" : $"{-num5}L") + "" + ((cachedPlayerStats.best_ranked_streak > 0) ? $" Best: {cachedPlayerStats.best_ranked_streak}W" : "")); } else { UIFactory.SetText(txtRankedStrk, ""); } ApiClient.TeamStatsData cachedTeamStats = ApiClient.CachedTeamStats; if (cachedTeamStats != null && cachedTeamStats.series_wins + cachedTeamStats.series_losses > 0) { string text2 = ((cachedTeamStats.series_losses > 0) ? $"{(float)cachedTeamStats.series_wins / (float)cachedTeamStats.series_losses:F1}" : ((cachedTeamStats.series_wins > 0) ? $"{cachedTeamStats.series_wins}:0" : "0:0")); UIFactory.SetText(txtTeam2v2Rec, $"2v2: {cachedTeamStats.series_wins}W / {cachedTeamStats.series_losses}L ({text2}) Rating: {cachedTeamStats.rating:F0} Peak: {cachedTeamStats.peak_rating:F0}"); int current_streak = cachedTeamStats.current_streak; if (current_streak != 0) { string text3 = ((current_streak > 0) ? "#00FF00" : "#FF6666"); UIFactory.SetText(txtTeam2v2Strk, " Streak: " + ((current_streak > 0) ? $"{current_streak}W" : $"{-current_streak}L") + ""); } else { UIFactory.SetText(txtTeam2v2Strk, ""); } } else { UIFactory.SetText(txtTeam2v2Rec, "2v2: -"); UIFactory.SetText(txtTeam2v2Strk, ""); } UIFactory.SetText(txtCasualRec, (list2.Count > 0) ? string.Format("Casual: {0}W / {1}L ({2})", num, num2, (num2 > 0) ? $"{(float)num / (float)num2:F1}" : ((num > 0) ? $"{num}:0" : "")) : "Casual: -"); if (list2.Count > 0) { int num6 = CalcStreak(list2); string text4 = ((num6 > 0) ? "#00FF00" : "#FF6666"); UIFactory.SetText(txtCasualStrk, " Streak: " + ((num6 > 0) ? $"{num6}W" : $"{-num6}L") + "" + ((cachedPlayerStats.best_casual_streak > 0) ? $" Best: {cachedPlayerStats.best_casual_streak}W" : "")); } else { UIFactory.SetText(txtCasualStrk, ""); } UIFactory.SetText(txtSweeps, $"Sweeps: 5-0 x{num3} 0-5 x{num4}"); UIFactory.SetText(txtTotalRec, $"Total: {cachedPlayerStats.total_matches} ({cachedPlayerStats.wins}W / {cachedPlayerStats.losses}L) Gold: {cachedPlayerStats.gold_earned - cachedPlayerStats.gold_spent}"); string text5 = ((cachedPlayerStats.bullets_fired > 0) ? $"Hit: {(float)cachedPlayerStats.bullets_hit * 100f / (float)cachedPlayerStats.bullets_fired:F1}% ({cachedPlayerStats.bullets_hit}/{cachedPlayerStats.bullets_fired})" : "Hit: -"); string text6 = ((cachedPlayerStats.blocks_activated > 0) ? $"Block: {(float)cachedPlayerStats.blocks_successful * 100f / (float)cachedPlayerStats.blocks_activated:F1}% ({cachedPlayerStats.blocks_successful}/{cachedPlayerStats.blocks_activated})" : "Block: -"); UIFactory.SetText(txtAccuracy, text5 + "\n" + text6); RefreshHistory(list, list2); RefreshSession(); if ((Object)(object)linkCodeBtn != (Object)null && txtLinkCode != null) { bool flag = !string.IsNullOrEmpty(cachedPlayerStats.discord_id); linkCodeBtn.SetActive(!flag); if (flag) { string text7 = ((!string.IsNullOrEmpty(cachedPlayerStats.discord_username)) ? ("@" + cachedPlayerStats.discord_username) : ("ID " + cachedPlayerStats.discord_id)); string text8 = (discordRevealed ? text7 : "***** (click to show)"); UIFactory.SetText(txtLinkCode, "Linked to Discord (" + text8 + ")"); } } RefreshChatLog(); } private static void RefreshHistory(List ranked, List casual) { //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) CompetitiveUI.ClearCardHoverRegions(); foreach (HistoryRow rankedRow in rankedRows) { rankedRow.root.SetActive(false); rankedRow.seriesGO.SetActive(false); } if (ranked.Count > 0) { List list = GroupBySeries(ranked); int num = 3; int num2 = (list.Count + num - 1) / num; rankedPage = Math.Max(0, Math.Min(rankedPage, num2 - 1)); int num3 = rankedPage * num; int num4 = Math.Min(num3 + num, list.Count); int num5 = 0; for (int i = num3; i < num4; i++) { if (num5 >= rankedRows.Count) { break; } SGroup sGroup = list[i]; if (sGroup.matches.Count == 0) { continue; } ApiClient.MatchHistoryEntry matchHistoryEntry = sGroup.matches[0]; if (sGroup.series_id != null && num5 < rankedRows.Count) { HistoryRow historyRow = rankedRows[num5]; string text = matchHistoryEntry.series_score ?? "?-?"; string text2 = FormatOpponentForRow(matchHistoryEntry, 18); bool flag = false; bool flag2 = false; try { string[] array = text.Split('-'); int num6 = int.Parse(array[0]); int num7 = int.Parse(array[1]); flag = num6 >= 2 || num7 >= 2; flag2 = num6 > num7; } catch { } UIFactory.SetText(historyRow.txtSeriesHead, flag ? ("Series " + (flag2 ? "W" : "L") + " " + text + " vs " + text2) : ("Series " + text + " vs " + text2 + " (in progress)")); UIFactory.SetColor(historyRow.txtSeriesHead, (!flag) ? C_GOLD : (flag2 ? C_GREEN : C_RED)); int num8 = 0; foreach (ApiClient.MatchHistoryEntry match in sGroup.matches) { if (match.series_gold_gained > num8) { num8 = match.series_gold_gained; } } if (flag && matchHistoryEntry.series_rating_change != 0f) { float series_rating_change = matchHistoryEntry.series_rating_change; string arg = ((num8 > 0) ? $" +{num8}g" : ""); UIFactory.SetText(historyRow.txtSeriesElo, string.Format("{0}{1:F0} elo{2}", (series_rating_change > 0f) ? "+" : "", series_rating_change, arg)); UIFactory.SetColor(historyRow.txtSeriesElo, (series_rating_change > 0f) ? C_GREEN : C_RED); } else { UIFactory.SetText(historyRow.txtSeriesElo, ""); } historyRow.seriesGO.SetActive(true); foreach (ApiClient.MatchHistoryEntry match2 in sGroup.matches) { if (num5 >= rankedRows.Count) { break; } FillRow(rankedRows[num5], match2, indent: true); num5++; } } else { FillRow(rankedRows[num5], matchHistoryEntry, indent: false); num5++; } } rPrev.SetActive(rankedPage > 0); rNext.SetActive(rankedPage < num2 - 1); UIFactory.SetText(txtRankedPage, (num2 > 1) ? $"{rankedPage + 1}/{num2}" : ""); } else { rPrev.SetActive(false); rNext.SetActive(false); UIFactory.SetText(txtRankedPage, ""); } foreach (HistoryRow casualRow in casualRows) { casualRow.root.SetActive(false); } if (casual.Count > 0) { int num9 = 6; int num10 = (casual.Count + num9 - 1) / num9; casualPage = Math.Max(0, Math.Min(casualPage, num10 - 1)); int num11 = casualPage * num9; int num12 = Math.Min(num11 + num9, casual.Count); for (int j = num11; j < num12; j++) { int num13 = j - num11; if (num13 < casualRows.Count) { FillRow(casualRows[num13], casual[j], indent: false); } } cPrev.SetActive(casualPage > 0); cNext.SetActive(casualPage < num10 - 1); UIFactory.SetText(txtCasualPage, (num10 > 1) ? $"{casualPage + 1}/{num10}" : ""); } else { cPrev.SetActive(false); cNext.SetActive(false); UIFactory.SetText(txtCasualPage, ""); } } private static void FillRow(HistoryRow row, ApiClient.MatchHistoryEntry m, bool indent) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) string text = (m.won ? "W" : "L"); Color c = (m.won ? C_GREEN : C_RED); string text2 = ((m.player_points + m.opponent_points > 0) ? string.Format(" {1}-{2}p", m.won ? "88AA88" : "AA8888", m.player_points, m.opponent_points) : ""); UIFactory.SetText(row.txtResult, string.Format("{0}{1} {2}-{3}{4}", indent ? " " : " ", text, m.player_rounds_won, m.opponent_rounds_won, text2)); UIFactory.SetColor(row.txtResult, c); UIFactory.SetText(row.txtOpp, indent ? "" : ("vs " + FormatOpponentForRow(m, 20))); UIFactory.SetText(row.txtFps, BuildFpsTag(m)); UIFactory.SetText(row.txtXP, (m.xp_gained <= 0) ? "" : ((m.gold_gained > 0) ? $"+{m.xp_gained}xp +{m.gold_gained}g" : $"+{m.xp_gained}xp")); string s = ""; try { if (!string.IsNullOrEmpty(m.ended_at) && m.ended_at.Length >= 10) { s = DateTime.Parse(m.ended_at).ToString("M/d"); } } catch { } UIFactory.SetText(row.txtDate, s); UIFactory.SetText(row.txtCards, (!string.IsNullOrEmpty(m.cards_display)) ? (" Cards: " + (_historyCardsFull ? m.cards_display : FormatCardLine(m.cards_display))) : ""); UIFactory.SetText(row.txtOppCards, (!string.IsNullOrEmpty(m.opp_cards_display)) ? (" Opp: " + (_historyCardsFull ? m.opp_cards_display : FormatCardLine(m.opp_cards_display))) : ""); if (rCardModeTxt != null) { UIFactory.SetText(rCardModeTxt, HistoryCardModeLabel()); } if (cCardModeTxt != null) { UIFactory.SetText(cCardModeTxt, HistoryCardModeLabel()); } RegisterHoverRectFor(row.txtCards, m.cards_display, isOpponent: false); RegisterHoverRectFor(row.txtOppCards, m.opp_cards_display, isOpponent: true); row.root.SetActive(true); } private static void RegisterHoverRectFor(object txt, string fullLine, bool isOpponent, string titleOverride = null, string bodyOverride = null) { //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) if (txt == null || string.IsNullOrEmpty(fullLine)) { return; } try { Component val = (Component)((txt is Component) ? txt : null); if ((Object)(object)val == (Object)null) { return; } RectTransform component = val.GetComponent(); if ((Object)(object)component == (Object)null) { return; } Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); Camera val2 = null; bool flag = true; Transform val3 = (Transform)(object)component; while ((Object)(object)val3 != (Object)null) { Component component2 = ((Component)val3).GetComponent(UIFactory.tCanvas); if ((Object)(object)component2 != (Object)null) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; PropertyInfo property = UIFactory.tCanvas.GetProperty("renderMode", bindingAttr); if (property != null) { flag = (int)property.GetValue(component2) == 0; if (!flag) { object? obj = UIFactory.tCanvas.GetProperty("worldCamera", bindingAttr)?.GetValue(component2); val2 = (Camera)(((obj is Camera) ? obj : null) ?? Camera.main); } } break; } val3 = val3.parent; } Vector2 val4 = default(Vector2); Vector2 val5 = default(Vector2); if (flag) { ((Vector2)(ref val4))..ctor(array[0].x, array[0].y); ((Vector2)(ref val5))..ctor(array[2].x, array[2].y); } else { if (!((Object)(object)val2 != (Object)null)) { return; } Vector3 val6 = val2.WorldToScreenPoint(array[0]); Vector3 val7 = val2.WorldToScreenPoint(array[2]); ((Vector2)(ref val4))..ctor(val6.x, val6.y); ((Vector2)(ref val5))..ctor(val7.x, val7.y); } float num = Mathf.Max(1f, val5.x - val4.x); float num2 = Mathf.Max(1f, val5.y - val4.y); try { PropertyInfo property2 = ((object)val).GetType().GetProperty("preferredWidth", BindingFlags.Instance | BindingFlags.Public); Rect rect = component.rect; float width = ((Rect)(ref rect)).width; if (property2 != null && width > 0f) { float num3 = (float)property2.GetValue(val); if (num3 > 0f) { float num4 = Mathf.Clamp01(num3 / width); num = Mathf.Min(num, num * num4 + 12f); } } } catch { } CompetitiveUI.RegisterCardHoverRegion(new Rect(val4.x, val4.y, num, num2), fullLine, isOpponent, titleOverride, bodyOverride); } catch { } } private static string FormatCardLine(string raw) { if (string.IsNullOrEmpty(raw)) { return ""; } StringBuilder stringBuilder = new StringBuilder(); string[] array = raw.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { int num = text.IndexOf('>'); if (num >= 0 && num < text.Length - 1) { text = text.Substring(num + 1); } int num2 = text.IndexOf('<'); if (num2 > 0) { text = text.Substring(0, num2); } text = text.Trim(); if (text.Length != 0) { string value = ((text.Length >= 2) ? text.Substring(0, 2).ToUpperInvariant() : text.ToUpperInvariant()); stringBuilder.Append('[').Append(value).Append("] "); } } } return stringBuilder.ToString().TrimEnd(); } private static string BuildFpsTag(ApiClient.MatchHistoryEntry m) { if (m == null) { return ""; } int player_fps_avg = m.player_fps_avg; int opponent_fps_avg = m.opponent_fps_avg; if (player_fps_avg <= 0 && opponent_fps_avg <= 0) { return ""; } string text = ((player_fps_avg > 0) ? player_fps_avg.ToString() : "-"); string text2 = ((opponent_fps_avg > 0) ? opponent_fps_avg.ToString() : "-"); return "FPS: " + text + " / " + text2 + ""; } private static string FormatOpponentForRow(ApiClient.MatchHistoryEntry m, int nameMax) { string text = Trunc(m?.opponent_name ?? "", nameMax); if (m == null || string.IsNullOrEmpty(m.opponent_title)) { return text; } string text2 = (string.IsNullOrEmpty(m.opponent_title_color) ? "#CCCCCC" : m.opponent_title_color); return text + " [" + m.opponent_title + "]"; } private static void RefreshSession() { //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) int sessionMatchCount = GameStateWatcher.SessionMatchCount; bool isInRoom = GameStateWatcher.IsInRoom; string opponentSteamId = GameStateWatcher.OpponentSteamId; string opponentDisplayName = GameStateWatcher.OpponentDisplayName; List cachedMatchHistory = ApiClient.CachedMatchHistory; if (isInRoom && !string.IsNullOrEmpty(opponentSteamId) && !opponentSteamId.StartsWith("photon_") && cachedMatchHistory != null) { int num = 0; int num2 = 0; string text = ""; foreach (ApiClient.MatchHistoryEntry item in cachedMatchHistory) { if (!(item.opponent_steam_id == opponentSteamId)) { continue; } if (item.won) { num++; } else { num2++; } if (string.IsNullOrEmpty(text)) { try { text = DateTime.Parse(item.ended_at).ToString("M/d/yyyy"); } catch { } } } if (num + num2 > 0) { string text2 = ((num > num2) ? "#00FF00" : ((num < num2) ? "#FF6666" : "#AAAAAA")); UIFactory.SetText(txtSessionOppLifetime, $" vs {opponentDisplayName}: {num}W-{num2}L lifetime (last: {text})"); } else { UIFactory.SetText(txtSessionOppLifetime, " vs " + opponentDisplayName + ": First time playing!"); } UIFactory.SetColor(txtSessionOppLifetime, new Color(0.6f, 0.75f, 1f)); } else if (isInRoom && !string.IsNullOrEmpty(opponentDisplayName) && opponentDisplayName != "Opponent") { UIFactory.SetText(txtSessionOppLifetime, " In room with " + opponentDisplayName); UIFactory.SetColor(txtSessionOppLifetime, C_DIM); } else { UIFactory.SetText(txtSessionOppLifetime, ""); } if (sessionMatchCount <= 0) { UIFactory.SetText(txtSessionSum, isInRoom ? "In game - no results yet" : "No games this session"); UIFactory.SetColor(txtSessionSum, C_DIM); UIFactory.SetText(txtSessionSplit, ""); UIFactory.SetText(txtSessionSweeps, ""); return; } int num3 = (int)(DateTime.UtcNow - GameStateWatcher.SessionStartTime).TotalMinutes; string text3 = ((num3 >= 60) ? $"{num3 / 60}h {num3 % 60}m" : $"{num3}m"); int sessionRankedWins = GameStateWatcher.SessionRankedWins; int sessionRankedLosses = GameStateWatcher.SessionRankedLosses; int sessionCasualWins = GameStateWatcher.SessionCasualWins; int sessionCasualLosses = GameStateWatcher.SessionCasualLosses; int sessionTeamSeriesWins = GameStateWatcher.SessionTeamSeriesWins; int sessionTeamSeriesLosses = GameStateWatcher.SessionTeamSeriesLosses; int num4 = 0; int num5 = 0; if (cachedMatchHistory != null) { DateTime sessionStartTime = GameStateWatcher.SessionStartTime; foreach (ApiClient.MatchHistoryEntry item2 in cachedMatchHistory) { DateTime dateTime = DateTime.UtcNow; try { if (!string.IsNullOrEmpty(item2.ended_at)) { dateTime = DateTime.Parse(item2.ended_at).ToUniversalTime(); } } catch { } if (!(dateTime < sessionStartTime)) { if (item2.won && item2.opponent_rounds_won == 0) { num4++; } if (!item2.won && item2.player_rounds_won == 0) { num5++; } } } } UIFactory.SetText(txtSessionSum, $"{sessionMatchCount} games {sessionRankedWins + sessionCasualWins}W - {sessionRankedLosses + sessionCasualLosses}L {text3}"); UIFactory.SetColor(txtSessionSum, C_WHITE); string s = ""; List list = new List(); if (sessionRankedWins + sessionRankedLosses > 0) { list.Add($"Ranked: {sessionRankedWins}W/{sessionRankedLosses}L"); } if (sessionTeamSeriesWins + sessionTeamSeriesLosses > 0) { list.Add($"2v2: {sessionTeamSeriesWins}W/{sessionTeamSeriesLosses}L"); } if (sessionCasualWins + sessionCasualLosses > 0) { list.Add($"Casual: {sessionCasualWins}W/{sessionCasualLosses}L"); } if (list.Count > 0) { s = " " + string.Join(" ", list.ToArray()); } UIFactory.SetText(txtSessionSplit, s); if (num4 + num5 > 0) { UIFactory.SetText(txtSessionSweeps, $" Sweeps: 5-0 x{num4} 0-5 x{num5}"); } else { UIFactory.SetText(txtSessionSweeps, ""); } Dictionary sessionWLByOpponent = GameStateWatcher.SessionWLByOpponent; Dictionary sessionTimeByOpponent = GameStateWatcher.SessionTimeByOpponent; int num6 = 0; if (sessionWLByOpponent != null) { foreach (KeyValuePair item3 in sessionWLByOpponent) { int[] value = item3.Value; if (value != null && value.Length >= 4) { int num7 = value[0] + value[2]; int num8 = value[1] + value[3]; string text4 = $" vs {item3.Key}: {num7}W-{num8}L"; if (value[0] + value[1] > 0 && value[2] + value[3] > 0) { text4 += $" (R:{value[0]}-{value[1]} C:{value[2]}-{value[3]})"; } if (sessionTimeByOpponent != null && sessionTimeByOpponent.ContainsKey(item3.Key)) { int num9 = (int)sessionTimeByOpponent[item3.Key]; text4 += ((num9 >= 60) ? $" {num9 / 60}h {num9 % 60}m" : $" {num9}m"); } while (sessionOppTexts.Count <= num6) { sessionOppTexts.Add(UIFactory.CreateText($"so{sessionOppTexts.Count}", sessionOppContainer.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(340f, 22f), richText: true, raycastTarget: false)); } UIFactory.SetText(sessionOppTexts[num6], text4); UIFactory.SetColor(sessionOppTexts[num6], (num7 > num8) ? C_GREEN : ((num7 < num8) ? C_RED : C_DIM)); object obj3 = sessionOppTexts[num6]; object obj4 = ((obj3 is Component) ? obj3 : null); GameObject val = ((obj4 != null) ? ((Component)obj4).gameObject : null); if (Object.op_Implicit((Object)(object)val)) { val.SetActive(true); } num6++; } } } for (int i = num6; i < sessionOppTexts.Count; i++) { object obj5 = sessionOppTexts[i]; object obj6 = ((obj5 is Component) ? obj5 : null); GameObject val2 = ((obj6 != null) ? ((Component)obj6).gameObject : null); if (Object.op_Implicit((Object)(object)val2)) { val2.SetActive(false); } } } private static void RefreshLeaderboard() { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_1012: Unknown result type (might be due to invalid IL or missing references) //IL_0ff7: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_068e: Unknown result type (might be due to invalid IL or missing references) //IL_07b0: Unknown result type (might be due to invalid IL or missing references) //IL_0795: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[8] { "#", "Lv", "Player", "Rating", "W", "L", "W/L", "Gold" }; string[] array2 = new string[8] { "rank", "level", "display_name", "rating", "wins", "losses", "wl_ratio", "gold" }; if (lbSortTexts != null) { for (int i = 0; i < array2.Length && i < lbSortTexts.Length; i++) { if (lbSortTexts[i] != null) { string text = ((!(lbSort == array2[i])) ? "" : (lbSortDesc ? " v" : " ^")); UIFactory.SetText(lbSortTexts[i], array[i] + text); UIFactory.SetColor(lbSortTexts[i], (lbSort == array2[i]) ? C_WHITE : C_LABEL); if (lbSortBtns != null && i < lbSortBtns.Length) { UIFactory.SetImageColor(lbSortBtns[i], (lbSort == array2[i]) ? C_TABACT : C_TAB); } } } } ApiClient.LeaderboardData cachedLeaderboard = ApiClient.CachedLeaderboard; foreach (LBRow lbRow in lbRows) { lbRow.root.SetActive(false); } if (cachedLeaderboard == null || cachedLeaderboard.entries == null || cachedLeaderboard.entries.Length == 0) { UIFactory.SetText(txtLBDetail, "No leaderboard data"); UIFactory.SetText(txtLBCount, ""); return; } List list = new List(cachedLeaderboard.entries); switch (lbSort) { case "rank": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.rank.CompareTo(b.rank) : b.rank.CompareTo(a.rank)); break; case "level": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.level.CompareTo(b.level) : b.level.CompareTo(a.level)); break; case "display_name": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? string.Compare(a.display_name, b.display_name, StringComparison.OrdinalIgnoreCase) : string.Compare(b.display_name, a.display_name, StringComparison.OrdinalIgnoreCase)); break; case "rating": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.rating.CompareTo(b.rating) : b.rating.CompareTo(a.rating)); break; case "wins": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.wins.CompareTo(b.wins) : b.wins.CompareTo(a.wins)); break; case "losses": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.losses.CompareTo(b.losses) : b.losses.CompareTo(a.losses)); break; case "wl_ratio": list.Sort(delegate(ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) { float value2 = ((a.losses > 0) ? ((float)a.wins / (float)a.losses) : ((float)a.wins * 100f)); float value3 = ((b.losses > 0) ? ((float)b.wins / (float)b.losses) : ((float)b.wins * 100f)); return (!lbSortDesc) ? value2.CompareTo(value3) : value3.CompareTo(value2); }); break; case "gold": list.Sort((ApiClient.LeaderboardEntry a, ApiClient.LeaderboardEntry b) => (!lbSortDesc) ? a.gold.CompareTo(b.gold) : b.gold.CompareTo(a.gold)); break; } int num = 100; int num2 = (list.Count + num - 1) / num; lbPage = Math.Max(0, Math.Min(lbPage, num2 - 1)); int num3 = lbPage * num; int num4 = Math.Min(num3 + num, list.Count); for (int num5 = num3; num5 < num4 && num5 - num3 < lbRows.Count; num5++) { ApiClient.LeaderboardEntry leaderboardEntry = list[num5]; LBRow lBRow = lbRows[num5 - num3]; lBRow.steamId = leaderboardEntry.steam_id; bool flag = leaderboardEntry.steam_id == MatchTracker.LocalSteamId; string s = ((leaderboardEntry.losses > 0) ? $"{(float)leaderboardEntry.wins / (float)leaderboardEntry.losses:F1}" : ((leaderboardEntry.wins > 0) ? $"{leaderboardEntry.wins}:0" : "0:0")); UIFactory.SetText(lBRow.txtRank, $"{leaderboardEntry.rank}"); UIFactory.SetColor(lBRow.txtRank, (Color)((leaderboardEntry.rank == 1) ? new Color(1f, 0.84f, 0f) : ((leaderboardEntry.rank == 2) ? new Color(0.75f, 0.75f, 0.75f) : ((leaderboardEntry.rank == 3) ? new Color(0.8f, 0.5f, 0.2f) : C_GOLD)))); UIFactory.SetText(lBRow.txtLv, $"{leaderboardEntry.level}"); string text2 = Trunc(leaderboardEntry.display_name, 14); if (!string.IsNullOrEmpty(leaderboardEntry.title)) { string text3 = (string.IsNullOrEmpty(leaderboardEntry.title_color) ? "#FFFFFF" : leaderboardEntry.title_color); text2 = text2 + " [" + leaderboardEntry.title + "]"; } UIFactory.SetText(lBRow.txtName, text2); UIFactory.SetColor(lBRow.txtName, flag ? C_GREEN : C_WHITE); UIFactory.SetText(lBRow.txtRating, $"{leaderboardEntry.rating}"); UIFactory.SetText(lBRow.txtW, $"{leaderboardEntry.wins}"); UIFactory.SetText(lBRow.txtL, $"{leaderboardEntry.losses}"); UIFactory.SetText(lBRow.txtWL, s); if (leaderboardEntry.gold < 0) { UIFactory.SetText(lBRow.txtGold, "Hidden"); } else { UIFactory.SetText(lBRow.txtGold, (leaderboardEntry.gold > 0) ? $"{leaderboardEntry.gold}" : "0"); } bool flag2 = leaderboardEntry.steam_id == selectedSteamId; UIFactory.SetImageColor(lBRow.hlWrap, flag2 ? new Color(0.2f, 0.25f, 0.4f, 0.4f) : new Color(0.15f, 0.15f, 0.2f, 0.01f)); lBRow.root.SetActive(true); } UIFactory.SetText(txtLBCount, $"{cachedLeaderboard.total_players} players ranked"); lbPrev.SetActive(lbPage > 0); lbNext.SetActive(lbPage < num2 - 1); UIFactory.SetText(txtLBPage, (num2 > 1) ? $"{lbPage + 1}/{num2}" : ""); if (!string.IsNullOrEmpty(selectedSteamId) && selectedStats != null) { ApiClient.PlayerStatsData playerStatsData = selectedStats; UIFactory.SetText(txtLBPlayerName, $"{playerStatsData.display_name} Level {playerStatsData.level}"); string text4 = $"\nRating: {playerStatsData.rating:F0} RD: {playerStatsData.rating_deviation:F0} Peak: {playerStatsData.peak_rating:F0}\n{playerStatsData.total_matches} matches ({playerStatsData.wins}W / {playerStatsData.losses}L) WR: {((playerStatsData.total_matches > 0) ? ((float)playerStatsData.wins * 100f / (float)playerStatsData.total_matches) : 0f):F0}%\n"; if (playerStatsData.ranked_series_wins + playerStatsData.ranked_series_losses > 0) { text4 += $"Ranked: {playerStatsData.ranked_series_wins}W / {playerStatsData.ranked_series_losses}L\n"; } if (playerStatsData.ranked_dc_count > 0 || playerStatsData.ranked_series_wins + playerStatsData.ranked_series_losses > 0) { int num6 = playerStatsData.ranked_series_wins + playerStatsData.ranked_series_losses + playerStatsData.ranked_dc_count; int ranked_dc_count = playerStatsData.ranked_dc_count; if (num6 > 0) { float num7 = (float)ranked_dc_count / (float)num6 * 100f; string text5 = ((num7 < 5f) ? "#44AA44" : ((num7 < 15f) ? "#DDAA33" : "#FF4444")); text4 += $"Leave: {ranked_dc_count}/{num6} ({num7:F0}%)\n"; } } string text6 = ((playerStatsData.bullets_fired > 0) ? $"Hit: {(float)playerStatsData.bullets_hit * 100f / (float)playerStatsData.bullets_fired:F1}% ({playerStatsData.bullets_hit}/{playerStatsData.bullets_fired})" : "Hit: -"); string text7 = ((playerStatsData.blocks_activated > 0) ? $"Block: {(float)playerStatsData.blocks_successful * 100f / (float)playerStatsData.blocks_activated:F1}% ({playerStatsData.blocks_successful}/{playerStatsData.blocks_activated})" : "Block: -"); text4 = text4 + text6 + "\n" + text7 + "\n"; if (selectedSteamId != MatchTracker.LocalSteamId) { int h2h_ranked_wins = playerStatsData.h2h_ranked_wins; int h2h_ranked_losses = playerStatsData.h2h_ranked_losses; int h2h_casual_wins = playerStatsData.h2h_casual_wins; int h2h_casual_losses = playerStatsData.h2h_casual_losses; int h2h_series_wins = playerStatsData.h2h_series_wins; int h2h_series_losses = playerStatsData.h2h_series_losses; int num8 = h2h_ranked_wins + h2h_casual_wins; int num9 = h2h_ranked_losses + h2h_casual_losses; if (num8 + num9 > 0) { string text8 = ((num8 > num9) ? "#00FF00" : ((num8 < num9) ? "#FF6666" : "#AAAAAA")); text4 += $"\nvs You: {num8}W - {num9}L ({num8 + num9} games)\n"; if (h2h_series_wins + h2h_series_losses > 0) { text4 += $" Ranked Series: {h2h_series_wins}W / {h2h_series_losses}L\n"; } if (h2h_casual_wins + h2h_casual_losses > 0) { text4 += $" Casual: {h2h_casual_wins}W / {h2h_casual_losses}L\n"; } } } if (!string.IsNullOrEmpty(playerStatsData.mod_version)) { string text9 = ((playerStatsData.mod_version == "1.28.2") ? "#88FF88" : "#FFD94D"); text4 = text4 + "\nMod: v" + playerStatsData.mod_version + "\n"; } else { text4 += "\nMod: not detected\n"; } if (playerStatsData.top_card_names != null && playerStatsData.top_card_names.Count > 0) { text4 += "\nTop Cards:\n"; for (int num10 = 0; num10 < playerStatsData.top_card_names.Count && num10 < 8; num10++) { string text10 = ((playerStatsData.top_card_picks.Count > num10) ? $" ({playerStatsData.top_card_picks[num10]}x)" : ""); float num11 = ((playerStatsData.top_card_win_rates != null && playerStatsData.top_card_win_rates.Count > num10) ? (playerStatsData.top_card_win_rates[num10] * 100f) : 0f); string text11 = ((num11 >= 55f) ? "#00FF00" : ((num11 <= 45f) ? "#FF6666" : "#AAAAAA")); text4 += $" {playerStatsData.top_card_names[num10]}{text10} {num11:F0}%\n"; } } if (ApiClient.CachedPlayerTournaments.TryGetValue(selectedSteamId, out var value) && value != null && value.participant_count > 0) { text4 += "\nTournaments: "; text4 += $"1stx{value.winner_count} 2ndx{value.runner_up_count} 3rdx{value.third_place_count} (played {value.participant_count})\n"; if (value.recent != null && value.recent.Length != 0) { int num12 = 0; ApiClient.PlayerTournamentEntry[] recent = value.recent; foreach (ApiClient.PlayerTournamentEntry playerTournamentEntry in recent) { if (num12 >= 4) { break; } string text12 = playerTournamentEntry.ended_at; try { if (!string.IsNullOrEmpty(text12)) { text12 = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(playerTournamentEntry.ended_at, null, DateTimeStyles.RoundtripKind).ToUniversalTime(), _ResolveTz()).ToString("M/d/yy"); } } catch { } string arg = ((playerTournamentEntry.placed_rank == 1) ? "1st" : ((playerTournamentEntry.placed_rank == 2) ? "2nd" : ((playerTournamentEntry.placed_rank == 3) ? "3rd" : "-"))); text4 += $" {text12} {arg} ({playerTournamentEntry.signup_count}p)\n"; num12++; } } } UIFactory.SetText(txtLBDetail, text4 + BuildViewHistoryText() + GetAchievementText()); BuildFormGraph(playerStatsData.rating_history, playerStatsData.recent_form); if ((Object)(object)lbBlockRow != (Object)null) { lbBlockRow.SetActive(true); bool flag3 = selectedSteamId != MatchTracker.LocalSteamId; lbBlockBtn.SetActive(flag3); if (flag3 && lbBlockTxt != null) { bool flag4 = ApiClient.IsPlayerBlocked(selectedSteamId); UIFactory.SetText(lbBlockTxt, flag4 ? "Unblock from Ranked" : "Block from Ranked"); UIFactory.SetImageColor(lbBlockBtn, flag4 ? new Color(0.15f, 0.3f, 0.15f, 0.9f) : new Color(0.5f, 0.15f, 0.15f, 0.9f)); } } } else { UIFactory.SetText(txtLBPlayerName, "Click a player"); UIFactory.SetText(txtLBDetail, ""); BuildFormGraph(null, null); if ((Object)(object)lbBlockRow != (Object)null) { lbBlockRow.SetActive(false); } if ((Object)(object)h2hPager != (Object)null) { h2hPager.SetActive(false); } } } private static void BuildFormGraph(List ratingHistory, List form) { //IL_05d5: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06b3: Unknown result type (might be due to invalid IL or missing references) //IL_06d3: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_070c: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_07b1: Unknown result type (might be due to invalid IL or missing references) //IL_07b6: Unknown result type (might be due to invalid IL or missing references) //IL_07cc: Unknown result type (might be due to invalid IL or missing references) //IL_07d3: Unknown result type (might be due to invalid IL or missing references) //IL_07de: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Unknown result type (might be due to invalid IL or missing references) //IL_0802: Unknown result type (might be due to invalid IL or missing references) //IL_0811: Unknown result type (might be due to invalid IL or missing references) //IL_0827: Unknown result type (might be due to invalid IL or missing references) //IL_0856: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_08cf: Unknown result type (might be due to invalid IL or missing references) //IL_08d4: Unknown result type (might be due to invalid IL or missing references) //IL_08ea: Unknown result type (might be due to invalid IL or missing references) //IL_08f1: Unknown result type (might be due to invalid IL or missing references) //IL_08fc: Unknown result type (might be due to invalid IL or missing references) //IL_0911: Unknown result type (might be due to invalid IL or missing references) //IL_0920: Unknown result type (might be due to invalid IL or missing references) //IL_092e: Unknown result type (might be due to invalid IL or missing references) //IL_095d: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lbGraphPanel == (Object)null) { return; } for (int num = lbGraphPanel.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)lbGraphPanel.transform.GetChild(num)).gameObject); } bool flag = ratingHistory != null && ratingHistory.Count >= 2; bool flag2 = !flag && form != null && form.Count >= 2; if (!flag && !flag2) { lbGraphPanel.SetActive(false); return; } lbGraphPanel.SetActive(true); float[] array2; string text; if (flag) { float[] array = ratingHistory.ToArray(); if (array.Length > 100) { int num2 = 100; array2 = new float[num2]; for (int i = 0; i < num2; i++) { int num3 = (int)((long)i * (long)array.Length / num2); int num4 = (int)((long)(i + 1) * (long)array.Length / num2); if (num4 <= num3) { num4 = num3 + 1; } if (num4 > array.Length) { num4 = array.Length; } float num5 = 0f; int num6 = 0; for (int j = num3; j < num4; j++) { num5 += array[j]; num6++; } array2[i] = ((num6 > 0) ? (num5 / (float)num6) : array[num3]); } text = $"Rating History ({array[^1]:F0} Elo, {array.Length} games)"; } else { array2 = array; text = $"Rating History ({array2[^1]:F0} Elo)"; } } else { List list = new List(form); list.Reverse(); array2 = new float[list.Count]; int num7 = 0; int num8 = 0; int num9 = 0; for (int k = 0; k < list.Count; k++) { num7 += ((list[k] == "W") ? 1 : (-1)); array2[k] = num7; if (list[k] == "W") { num8++; } else { num9++; } } string arg = ((num8 > num9) ? "#00FF00" : ((num8 < num9) ? "#FF6666" : "#AAAAAA")); text = $"Ranked Form {num8}W-{num9}L"; } int num10 = array2.Length; float num11 = 6f; float num12 = 6f; float num13 = 18f; float num14 = 6f; float num15 = 310f - num11 - num12; float num16 = 80f - num13 - num14; RectTransform component = UIFactory.CreatePanel("GBG", lbGraphPanel.transform, new Color(0.08f, 0.09f, 0.12f, 0.8f)).GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; object obj = UIFactory.CreateText("GL", lbGraphPanel.transform, text, 11f, C_DIM, 257, (Vector2?)new Vector2(300f, 14f), richText: true, raycastTarget: false); try { object obj2 = ((obj is Component) ? obj : null); GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)val != (Object)null) { RectTransform component2 = val.GetComponent(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(1f, 1f); component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(num11, -1f); component2.sizeDelta = new Vector2(300f, 14f); Component component3 = val.GetComponent(UIFactory.tLE); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } } } catch { } float num17 = array2[0]; float num18 = array2[0]; for (int l = 1; l < num10; l++) { if (array2[l] < num17) { num17 = array2[l]; } if (array2[l] > num18) { num18 = array2[l]; } } float num19 = num18 - num17; if (num19 < 1f) { float num20 = (num17 + num18) * 0.5f; num17 = num20 - 0.5f; num18 = num20 + 0.5f; num19 = 1f; } float num21 = num19 * 0.1f; num17 -= num21; num18 += num21; num19 = num18 - num17; string text2 = (flag ? $"{num18:F0}" : $"+{num18:F0}"); string text3 = (flag ? $"{num17:F0}" : $"{num17:F0}"); object obj4 = UIFactory.CreateText("YMax", lbGraphPanel.transform, text2, 9f, new Color(0.5f, 0.7f, 0.5f, 0.7f), 260, (Vector2?)new Vector2(40f, 10f), richText: true, raycastTarget: false); try { object obj5 = ((obj4 is Component) ? obj4 : null); GameObject val2 = ((obj5 != null) ? ((Component)obj5).gameObject : null); if ((Object)(object)val2 != (Object)null) { RectTransform component4 = val2.GetComponent(); component4.anchorMin = new Vector2(1f, 1f); component4.anchorMax = new Vector2(1f, 1f); component4.pivot = new Vector2(1f, 1f); component4.anchoredPosition = new Vector2(-2f, 0f - num13 + 2f); Component component5 = val2.GetComponent(UIFactory.tLE); if ((Object)(object)component5 != (Object)null) { Object.Destroy((Object)(object)component5); } } } catch { } object obj7 = UIFactory.CreateText("YMin", lbGraphPanel.transform, text3, 9f, new Color(0.7f, 0.5f, 0.5f, 0.7f), 516, (Vector2?)new Vector2(40f, 10f), richText: true, raycastTarget: false); try { object obj8 = ((obj7 is Component) ? obj7 : null); GameObject val3 = ((obj8 != null) ? ((Component)obj8).gameObject : null); if ((Object)(object)val3 != (Object)null) { RectTransform component6 = val3.GetComponent(); component6.anchorMin = new Vector2(1f, 0f); component6.anchorMax = new Vector2(1f, 0f); component6.pivot = new Vector2(1f, 0f); component6.anchoredPosition = new Vector2(-2f, num14 - 2f); Component component7 = val3.GetComponent(UIFactory.tLE); if ((Object)(object)component7 != (Object)null) { Object.Destroy((Object)(object)component7); } } } catch { } Color val4 = (flag ? new Color(0.3f, 0.7f, 1f, 0.9f) : new Color(0.5f, 0.85f, 0.5f, 0.9f)); Color val5 = (flag ? new Color(0.4f, 0.8f, 1f, 1f) : new Color(0.6f, 1f, 0.6f, 1f)); float num22 = 2f; for (int m = 0; m < num10 - 1; m++) { float num23 = num11 + ((num10 > 1) ? ((float)m / (float)(num10 - 1) * num15) : 0f); float num24 = num14 + (array2[m] - num17) / num19 * num16; float num25 = num11 + (float)(m + 1) / (float)(num10 - 1) * num15; float num26 = num14 + (array2[m + 1] - num17) / num19 * num16; float num27 = num25 - num23; float num28 = num26 - num24; float num29 = Mathf.Sqrt(num27 * num27 + num28 * num28); float num30 = Mathf.Atan2(num28, num27) * 57.29578f; GameObject val6 = new GameObject($"L{m}"); val6.transform.SetParent(lbGraphPanel.transform, false); RectTransform obj10 = val6.AddComponent(); obj10.anchorMin = Vector2.zero; obj10.anchorMax = Vector2.zero; obj10.pivot = new Vector2(0f, 0.5f); obj10.anchoredPosition = new Vector2(num23, num24); obj10.sizeDelta = new Vector2(num29, num22); ((Transform)obj10).localRotation = Quaternion.Euler(0f, 0f, num30); Component obj11 = val6.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj11, val4); } float num31 = ((num10 > 15) ? 3f : 4f); for (int n = 0; n < num10; n++) { float num32 = num11 + ((num10 > 1) ? ((float)n / (float)(num10 - 1) * num15) : 0f); float num33 = num14 + (array2[n] - num17) / num19 * num16; GameObject val7 = new GameObject($"D{n}"); val7.transform.SetParent(lbGraphPanel.transform, false); RectTransform obj12 = val7.AddComponent(); obj12.anchorMin = Vector2.zero; obj12.anchorMax = Vector2.zero; obj12.pivot = new Vector2(0.5f, 0.5f); obj12.anchoredPosition = new Vector2(num32, num33); obj12.sizeDelta = new Vector2(num31, num31); Component obj13 = val7.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj13, val5); } _ = (array2[num10 - 1] - num17) / num19; if (!flag) { string.Format("{0}{1:F0}", (array2[num10 - 1] > 0f) ? "+" : "", array2[num10 - 1]); } else { _ = $"{array2[num10 - 1]:F0}"; } if (!flag && !(array2[num10 - 1] > 0f)) { _ = array2[num10 - 1]; _ = 0f; } } public static Rect GetCompareSearchScreenRect() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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) try { object obj = compareSearchField; object obj2 = ((obj is Component) ? obj : null); GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)val == (Object)null) { return new Rect(0f, 0f, 0f, 0f); } RectTransform component = val.GetComponent(); if ((Object)(object)component == (Object)null) { return new Rect(0f, 0f, 0f, 0f); } Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); float x = array[0].x; float num = array[2].x - array[0].x; float num2 = array[1].y - array[0].y; float num3 = (float)Screen.height - array[1].y; if (num < 1f || num2 < 1f) { return new Rect(0f, 0f, 0f, 0f); } return new Rect(x, num3, num, num2); } catch { return new Rect(0f, 0f, 0f, 0f); } } private static GameObject BuildCompareTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_020b: 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_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: 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) //IL_0248: Expected O, but got Unknown //IL_06fb: Unknown result type (might be due to invalid IL or missing references) //IL_070f: Unknown result type (might be due to invalid IL or missing references) //IL_0754: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Expected O, but got Unknown //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Expected O, but got Unknown //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Expected O, but got Unknown //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Expected O, but got Unknown //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Expected O, but got Unknown //IL_0630: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Compare"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 8f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = UIFactory.CreatePanel("CmpL", val.transform, C_PANEL); UIFactory.AddVLG(val2, 4f, 8, 8, 6, 6); UIFactory.AddLE(val2, 200f, -1f, 222f, -1f, 0f, 1f); UIFactory.CreateText("CmpLH", val2.transform, "Compare Players", 19f, C_GOLD, 513, (Vector2?)new Vector2(204f, 26f), richText: true, raycastTarget: false); txtCompareStatus = UIFactory.CreateText("CmpSt", val2.transform, "Select up to 12 players", 13f, C_LABEL, 513, (Vector2?)new Vector2(204f, 20f), richText: true, raycastTarget: false); UIFactory.CreateText("CmpSearchCap", val2.transform, "Search players", 12f, C_SUB, 513, (Vector2?)new Vector2(204f, 16f), richText: true, raycastTarget: false); compareSearchField = UIFactory.CreateText("CmpSearchLbl", val2.transform, "", 13f, C_SUB, 513, (Vector2?)new Vector2(204f, 22f), richText: true, raycastTarget: false); GameObject val3 = new GameObject("CmpBtns"); val3.transform.SetParent(val2.transform, false); val3.AddComponent(); UIFactory.AddHLG(val3); UIFactory.AddLE(val3, -1f, -1f, -1f, 24f, -1f, 0f); Transform transform = val3.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.4f, 0.2f, 0.2f, 0.9f); object obj = <>c.<>9__344_0; if (obj == null) { UnityAction val4 = delegate { compareSelected.Clear(); dirty = true; }; <>c.<>9__344_0 = val4; obj = (object)val4; } UIFactory.AddLE(UIFactory.CreateButton("CmpClr", transform, "Clear", 13f, c_WHITE, bgColor, (UnityAction)obj, (Vector2?)new Vector2(120f, 24f)), -1f, -1f, -1f, 24f, 1f, 0f); Transform transform2 = val3.transform; Color c_WHITE2 = C_WHITE; Color bgColor2 = new Color(0.25f, 0.3f, 0.4f, 0.9f); object obj2 = <>c.<>9__344_1; if (obj2 == null) { UnityAction val5 = delegate { compareSearch = ""; dirty = true; }; <>c.<>9__344_1 = val5; obj2 = (object)val5; } UIFactory.AddLE(UIFactory.CreateButton("CmpClrS", transform2, "Clear search", 13f, c_WHITE2, bgColor2, (UnityAction)obj2, (Vector2?)new Vector2(120f, 24f)), -1f, -1f, -1f, 24f, 1f, 0f); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("CmpSV", val2.transform, 2f, childForceExpandWidth: false); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); comparePickerContent = scrollViewRefs.content; GameObject val6 = UIFactory.CreatePanel("CmpR", val.transform, C_PANEL); UIFactory.AddVLG(val6, 6f, 10, 10, 8, 8); UIFactory.AddLE(val6, -1f, -1f, -1f, -1f, 1f, 1f); GameObject val7 = new GameObject("CmpMetRow"); val7.transform.SetParent(val6.transform, false); val7.AddComponent(); UIFactory.AddHLG(val7); UIFactory.AddLE(val7, -1f, -1f, -1f, 30f, -1f, 0f); Transform transform3 = val7.transform; Color c_WHITE3 = C_WHITE; Color c_TAB = C_TAB; object obj3 = <>c.<>9__344_2; if (obj3 == null) { UnityAction val8 = delegate { compareMetric = (compareMetric - 1 + COMPARE_METRICS.Length) % COMPARE_METRICS.Length; dirty = true; }; <>c.<>9__344_2 = val8; obj3 = (object)val8; } UIFactory.AddLE(UIFactory.CreateButton("CmpMetP", transform3, "<", 15f, c_WHITE3, c_TAB, (UnityAction)obj3, (Vector2?)new Vector2(30f, 30f)), -1f, -1f, 30f, 30f, 0f, 0f); Transform transform4 = val7.transform; Color c_WHITE4 = C_WHITE; Color c_TAB2 = C_TAB; object obj4 = <>c.<>9__344_3; if (obj4 == null) { UnityAction val9 = delegate { compareMetric = (compareMetric + 1) % COMPARE_METRICS.Length; dirty = true; }; <>c.<>9__344_3 = val9; obj4 = (object)val9; } compareMetricBtn = UIFactory.CreateButton("CmpMet", transform4, "Metric: Elo over games", 15f, c_WHITE4, c_TAB2, (UnityAction)obj4, (Vector2?)new Vector2(320f, 30f)); UIFactory.AddLE(compareMetricBtn, -1f, -1f, -1f, 30f, 1f, 0f); compareMetricBtnTxt = UIFactory.GetButtonText(compareMetricBtn); Transform transform5 = val7.transform; Color c_WHITE5 = C_WHITE; Color c_TAB3 = C_TAB; object obj5 = <>c.<>9__344_4; if (obj5 == null) { UnityAction val10 = delegate { compareMetric = (compareMetric + 1) % COMPARE_METRICS.Length; dirty = true; }; <>c.<>9__344_4 = val10; obj5 = (object)val10; } UIFactory.AddLE(UIFactory.CreateButton("CmpMetN", transform5, ">", 15f, c_WHITE5, c_TAB3, (UnityAction)obj5, (Vector2?)new Vector2(30f, 30f)), -1f, -1f, 30f, 30f, 0f, 0f); compareGraphPanel = new GameObject("CmpGraph"); compareGraphPanel.transform.SetParent(val6.transform, false); compareGraphPanel.AddComponent(); UIFactory.AddLE(compareGraphPanel, -1f, -1f, -1f, -1f, 1f, 1f); Component obj6 = compareGraphPanel.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj6, (object)new Color(0.08f, 0.09f, 0.12f, 0.7f)); if (UIFactory.tMask != null) { Component obj7 = compareGraphPanel.AddComponent(UIFactory.tMask); try { UIFactory.tMask.GetProperty("showMaskGraphic", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj7, true); } catch { } } UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("CmpCardsSV", val6.transform, 0f); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); compareCardsScroll = scrollViewRefs2.scrollGO; compareCardsContent = scrollViewRefs2.content; txtCompareCards = UIFactory.CreateText("CmpCards", scrollViewRefs2.content.transform, "", 15f, C_DIM, 257, (Vector2?)new Vector2(820f, 24f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtCompareCards, on: true); UIFactory.SetTextAutoHeight(txtCompareCards); UIFactory.CreateText("CmpScrollHint", val6.transform, "scroll for more — hover the panel + mouse wheel", 12f, C_DIM, 514, (Vector2?)new Vector2(820f, 16f), richText: true, raycastTarget: false); return val; } private static void ToggleCompareSelect(int rowIdx) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (rowIdx < 0 || rowIdx >= comparePickerSteamIds.Count) { return; } string sid = comparePickerSteamIds[rowIdx]; if (string.IsNullOrEmpty(sid)) { return; } if (compareSelected.Contains(sid)) { compareSelected.Remove(sid); } else { if (compareSelected.Count >= 12) { CompetitiveUI.ShowNotification($"Max {12} players", new Color(1f, 0.6f, 0.3f)); return; } compareSelected.Add(sid); if (!compareStatsCache.ContainsKey(sid)) { ApiClient.FetchPlayerStatsForView(sid, delegate(ApiClient.PlayerStatsData d) { if (d != null) { compareStatsCache[sid] = d; } dirty = true; }); } } dirty = true; } private static void RefreshCompare() { //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) if (ApiClient.CachedLeaderboard == null) { ApiClient.FetchLeaderboard(); } string text = COMPARE_METRICS[Math.Max(0, Math.Min(compareMetric, COMPARE_METRICS.Length - 1))]; if (compareMetricBtnTxt != null) { UIFactory.SetText(compareMetricBtnTxt, "Metric: " + text + " (click / use < >)"); } if (txtCompareStatus != null) { UIFactory.SetText(txtCompareStatus, $"Selected {compareSelected.Count}/{12} - click a player to add/remove"); } if (compareSearchField != null) { UIFactory.SetText(compareSearchField, ""); } ApiClient.LeaderboardData cachedLeaderboard = ApiClient.CachedLeaderboard; ApiClient.LeaderboardEntry[] obj = ((cachedLeaderboard != null && cachedLeaderboard.entries != null) ? cachedLeaderboard.entries : new ApiClient.LeaderboardEntry[0]); string value = (compareSearch ?? "").Trim(); List list = new List(); ApiClient.LeaderboardEntry[] array = obj; foreach (ApiClient.LeaderboardEntry leaderboardEntry in array) { if (string.IsNullOrEmpty(value) || (leaderboardEntry.display_name != null && leaderboardEntry.display_name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)) { list.Add(leaderboardEntry); } } int count = list.Count; while (comparePickerSteamIds.Count < count) { comparePickerSteamIds.Add(""); } for (int j = 0; j < count; j++) { ApiClient.LeaderboardEntry leaderboardEntry2 = list[j]; comparePickerSteamIds[j] = leaderboardEntry2.steam_id; while (comparePickerRows.Count <= j) { int idx = comparePickerRows.Count; GameObject val = UIFactory.CreateButton($"cmpP{idx}", comparePickerContent.transform, "", 13f, C_WHITE, C_TAB, (UnityAction)delegate { ToggleCompareSelect(idx); }, (Vector2?)new Vector2(168f, 24f)); UIFactory.AddLE(val, -1f, -1f, 168f, 24f, 0f, 0f); comparePickerRows.Add(val); comparePickerTexts.Add(UIFactory.GetButtonText(val)); } GameObject obj2 = comparePickerRows[j]; obj2.SetActive(true); bool flag = compareSelected.Contains(leaderboardEntry2.steam_id); int num = compareSelected.IndexOf(leaderboardEntry2.steam_id); Color c = ((flag && num >= 0) ? COMPARE_COLORS[num % COMPARE_COLORS.Length] : C_LABEL); UIFactory.SetText(s: string.Format("{0}{1} {2}", flag ? ("[X] ") : "[ ] ", Trunc(leaderboardEntry2.display_name, 16), leaderboardEntry2.rating), t: comparePickerTexts[j]); UIFactory.SetImageColor(obj2, (Color)(flag ? new Color(0.2f, 0.3f, 0.25f, 0.9f) : C_TAB)); } for (int num2 = count; num2 < comparePickerRows.Count; num2++) { comparePickerRows[num2].SetActive(false); } bool flag2 = text == "Top Cards" || text == "Worst Cards"; bool active = !flag2; if ((Object)(object)compareGraphPanel != (Object)null) { compareGraphPanel.SetActive(active); } if ((Object)(object)compareCardsScroll != (Object)null) { compareCardsScroll.SetActive(flag2); } if (text == "Elo over games") { BuildCompareGraph(); } else if (flag2) { BuildCompareCardGrid(text); } else { BuildCompareBarChart(text); } } private static string ColorToHex(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp((int)(c.r * 255f), 0, 255); int num2 = Mathf.Clamp((int)(c.g * 255f), 0, 255); int num3 = Mathf.Clamp((int)(c.b * 255f), 0, 255); return $"{num:X2}{num2:X2}{num3:X2}"; } private static void BuildCompareGraph() { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)compareGraphPanel == (Object)null) { return; } for (int num = compareGraphPanel.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)compareGraphPanel.transform.GetChild(num)).gameObject); } List list = new List(); List list2 = new List(); List list3 = new List(); for (int i = 0; i < compareSelected.Count; i++) { string key = compareSelected[i]; if (compareStatsCache.TryGetValue(key, out var value) && value != null && value.rating_history != null && value.rating_history.Count >= 2) { list.Add(Trunc(value.display_name ?? "?", 14)); list2.Add(COMPARE_COLORS[i % COMPARE_COLORS.Length]); list3.Add(value.rating_history.ToArray()); } } CompareChartSize(out var W, out var H); float num2 = 56f; float num3 = 16f; float num4 = 30f; float num5 = 26f; float num6 = W - num2 - num3; float num7 = H - num4 - num5; if (list3.Count == 0) { object obj = UIFactory.CreateText("CmpNone", compareGraphPanel.transform, "Select 2+ players with ranked history to compare Elo.", 15f, C_DIM, 514, (Vector2?)new Vector2(W - 20f, 40f), richText: true, raycastTarget: false); object obj2 = ((obj is Component) ? obj : null); RectTransform val = ((obj2 != null) ? ((Component)obj2).gameObject.GetComponent() : null); if ((Object)(object)val != (Object)null) { val.anchorMin = new Vector2(0.5f, 0.5f); val.anchorMax = new Vector2(0.5f, 0.5f); val.anchoredPosition = Vector2.zero; } object obj3 = ((obj is Component) ? obj : null); Component val2 = ((obj3 != null) ? ((Component)obj3).gameObject.GetComponent(UIFactory.tLE) : null); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } return; } float num8 = float.MaxValue; float num9 = float.MinValue; int num10 = 0; foreach (float[] item in list3) { if (item.Length > num10) { num10 = item.Length; } float[] array = item; foreach (float num11 in array) { if (num11 < num8) { num8 = num11; } if (num11 > num9) { num9 = num11; } } } if (num10 < 2) { num10 = 2; } float num12 = NiceStep(Mathf.Max(1f, num9 - num8) / 4f); float num13 = Mathf.Floor(num8 / num12) * num12; float num14 = Mathf.Ceil(num9 / num12) * num12; if (num14 - num13 < num12) { num14 = num13 + num12; } num8 = num13; num9 = num14; float num15 = num9 - num8; int num16 = Mathf.Clamp(Mathf.RoundToInt(num15 / num12), 2, 8); for (int k = 0; k <= num16; k++) { float num17 = num13 + (float)k * num12; if (num17 > num14 + 0.5f) { break; } float num18 = num5 + (num17 - num13) / num15 * num7; DrawBar($"CmpYGrid{k}", num2, num18, num6, 1f, new Color(1f, 1f, 1f, 0.1f)); MakeGraphLabel($"CmpYLbl{k}", "" + FullNum(num17) + "", new Vector2(0f, 0f), new Vector2(num2 - 4f, num18 - 6f), new Vector2(50f, 12f), 516); } MakeGraphLabel("CmpXLbl", "games ->", new Vector2(1f, 0f), new Vector2(0f - num3, num5 - 14f), new Vector2(90f, 12f), 516); for (int l = 0; l < list3.Count; l++) { float[] array2 = list3[l]; Color col = list2[l]; for (int m = 0; m < array2.Length - 1; m++) { float x = num2 + (float)m / (float)(num10 - 1) * num6; float y = num5 + (array2[m] - num8) / num15 * num7; float x2 = num2 + (float)(m + 1) / (float)(num10 - 1) * num6; float y2 = num5 + (array2[m + 1] - num8) / num15 * num7; DrawGraphSegment($"CmpL{l}_{m}", x, y, x2, y2, col, 2f); } int num19 = 3; float num20 = num6 / (float)num19; float num21 = num2 + (float)(l % num19) * num20; float num22 = -2f - (float)(l / num19) * 16f; float num23 = H + num22 - 7f; DrawGraphSegment($"CmpLegSw{l}", num21 + 2f, num23, num21 + 24f, num23, col, 4f); MakeGraphLabel($"CmpLeg{l}", "" + list[l] + "", new Vector2(0f, 1f), new Vector2(num21 + 30f, num22), new Vector2(num20 - 30f, 16f), 513, 13f); } } private static void DrawGraphSegment(string name, float x1, float y1, float x2, float y2, Color col, float thick) { //IL_0025: 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_0040: 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_0052: 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_0074: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) float num = x2 - x1; float num2 = y2 - y1; float num3 = Mathf.Sqrt(num * num + num2 * num2); float num4 = Mathf.Atan2(num2, num) * 57.29578f; GameObject val = new GameObject(name); val.transform.SetParent(compareGraphPanel.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.zero; obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(x1, y1); obj.sizeDelta = new Vector2(num3, thick); ((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, num4); Component obj2 = val.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, col); } private static void MakeGraphLabel(string name, string text, Vector2 anchor, Vector2 pos, Vector2 size, int align, float fontSize = 11f) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_004d: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) object obj = UIFactory.CreateText(name, compareGraphPanel.transform, text, fontSize, C_DIM, align, size); object obj2 = ((obj is Component) ? obj : null); GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null); if (!((Object)(object)val == (Object)null)) { RectTransform component = val.GetComponent(); component.anchorMin = anchor; component.anchorMax = anchor; component.pivot = anchor; component.anchoredPosition = pos; component.sizeDelta = size; Component component2 = val.GetComponent(UIFactory.tLE); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } } private static void DrawBar(string name, float x, float y, float w, float h, Color col) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (h < 0f) { h = 0f; } GameObject val = new GameObject(name); val.transform.SetParent(compareGraphPanel.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.zero; obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(x, y); obj.sizeDelta = new Vector2(w, h); Component obj2 = val.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, col); } private static Color RegionColor(string region) { //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0305: 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_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) switch ((region ?? "").ToLowerInvariant()) { case "us": return new Color(0.25f, 0.55f, 1f); case "usw": return new Color(0.15f, 0.85f, 0.85f); case "ussc": return new Color(0.35f, 0.8f, 0.35f); case "eu": return new Color(1f, 0.62f, 0.18f); case "asia": return new Color(0.95f, 0.32f, 0.32f); case "jp": return new Color(1f, 0.42f, 0.8f); case "au": return new Color(0.68f, 0.42f, 1f); case "sa": return new Color(0.8f, 0.85f, 0.2f); case "kr": return new Color(1f, 0.82f, 0.28f); case "in": return new Color(0.45f, 0.4f, 0.92f); case "cae": return new Color(0.5f, 0.78f, 0.62f); case "za": return new Color(0.9f, 0.55f, 0.35f); case "ru": case "rue": return new Color(0.8f, 0.5f, 0.55f); default: return new Color(0.7f, 0.7f, 0.74f); } } private static void CompareChartSize(out float W, out float H) { //IL_0033: 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_0058: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) W = 900f; H = 460f; try { RectTransform val = (((Object)(object)compareGraphPanel != (Object)null) ? compareGraphPanel.GetComponent() : null); if ((Object)(object)val != (Object)null) { Rect rect = val.rect; if (((Rect)(ref rect)).width > 50f) { rect = val.rect; W = ((Rect)(ref rect)).width; } rect = val.rect; if (((Rect)(ref rect)).height > 50f) { rect = val.rect; H = ((Rect)(ref rect)).height; } } } catch { } } private static float NiceStep(float roughStep) { if (roughStep <= 0f) { return 1f; } float num = Mathf.Pow(10f, Mathf.Floor(Mathf.Log10(roughStep))); float num2 = roughStep / num; return ((num2 <= 1f) ? 1f : ((num2 <= 2f) ? 2f : ((num2 <= 2.5f) ? 2.5f : ((num2 <= 5f) ? 5f : 10f)))) * num; } private static string FullNum(float v) { return Mathf.RoundToInt(v).ToString("N0"); } private static long TotalXpForLevel(int level) { long num = 0L; for (int i = 1; i <= level && i <= 100; i++) { num += (long)(100.0 * Math.Pow(i, 1.5)); } return num; } private static int LevelForXp(float xp) { long num = (long)Math.Max(0f, xp); int result = 0; for (int i = 1; i <= 100; i++) { long num2 = (long)(100.0 * Math.Pow(i, 1.5)); if (num < num2) { return result; } num -= num2; result = i; } return 100; } private static Color GradeColor(float t) { //IL_0067: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) t = Mathf.Clamp01(t); Color val = default(Color); ((Color)(ref val))..ctor(0.35f, 0.85f, 0.4f); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.95f, 0.82f, 0.3f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.95f, 0.4f, 0.4f); if (!(t < 0.5f)) { return Color.Lerp(val2, val3, (t - 0.5f) * 2f); } return Color.Lerp(val, val2, t * 2f); } private static Sprite GetCircleSprite() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pieCircleSprite != (Object)null) { return _pieCircleSprite; } try { int num = 128; float num2 = (float)num * 0.5f; float num3 = num2; float num4 = num2; Texture2D val = new Texture2D(num, num, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; Color32[] array = (Color32[])(object)new Color32[num * num]; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { float num5 = (float)j + 0.5f - num3; float num6 = (float)i + 0.5f - num4; bool flag = num5 * num5 + num6 * num6 <= (num2 - 1f) * (num2 - 1f); array[i * num + j] = (flag ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0)); } } val.SetPixels32(array); val.Apply(); _pieCircleSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f); ((Object)_pieCircleSprite).hideFlags = (HideFlags)61; } catch { _pieCircleSprite = null; } return _pieCircleSprite; } private static void DrawPieSlice(string name, float cx, float cy, float radius, float startFrac, float sweepFrac, Color col) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Sprite circleSprite = GetCircleSprite(); if ((Object)(object)circleSprite == (Object)null) { return; } GameObject val = new GameObject(name); val.transform.SetParent(compareGraphPanel.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.zero; obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = new Vector2(cx, cy); obj.sizeDelta = new Vector2(radius * 2f, radius * 2f); ((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, (0f - startFrac) * 360f); Component obj2 = val.AddComponent(UIFactory.tImage); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; UIFactory.tImage.GetProperty("sprite", bindingAttr)?.SetValue(obj2, circleSprite); UIFactory.tImage.GetProperty("color", bindingAttr)?.SetValue(obj2, col); try { UIFactory.tImage.GetProperty("type", bindingAttr)?.SetValue(obj2, Enum.ToObject(UIFactory.tImage.GetProperty("type", bindingAttr).PropertyType, 3)); } catch { } try { UIFactory.tImage.GetProperty("fillMethod", bindingAttr)?.SetValue(obj2, Enum.ToObject(UIFactory.tImage.GetProperty("fillMethod", bindingAttr).PropertyType, 4)); } catch { } try { UIFactory.tImage.GetProperty("fillOrigin", bindingAttr)?.SetValue(obj2, 2); } catch { } try { UIFactory.tImage.GetProperty("fillClockwise", bindingAttr)?.SetValue(obj2, true); } catch { } try { UIFactory.tImage.GetProperty("fillAmount", bindingAttr)?.SetValue(obj2, Mathf.Clamp01(sweepFrac)); } catch { } } private static void BuildCompareBarChart(string metricName) { //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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_06d7: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_06f3: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Unknown result type (might be due to invalid IL or missing references) //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_0994: Unknown result type (might be due to invalid IL or missing references) //IL_07e5: Unknown result type (might be due to invalid IL or missing references) //IL_07ec: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Unknown result type (might be due to invalid IL or missing references) //IL_07ff: Unknown result type (might be due to invalid IL or missing references) //IL_082e: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Unknown result type (might be due to invalid IL or missing references) //IL_0848: Unknown result type (might be due to invalid IL or missing references) //IL_085a: Unknown result type (might be due to invalid IL or missing references) //IL_0897: Unknown result type (might be due to invalid IL or missing references) //IL_08b5: Unknown result type (might be due to invalid IL or missing references) //IL_08c7: Unknown result type (might be due to invalid IL or missing references) //IL_090e: Unknown result type (might be due to invalid IL or missing references) //IL_0932: Unknown result type (might be due to invalid IL or missing references) //IL_0944: Unknown result type (might be due to invalid IL or missing references) //IL_09d7: Unknown result type (might be due to invalid IL or missing references) //IL_0aaf: Unknown result type (might be due to invalid IL or missing references) //IL_0ae7: Unknown result type (might be due to invalid IL or missing references) //IL_0afc: Unknown result type (might be due to invalid IL or missing references) //IL_0b0e: Unknown result type (might be due to invalid IL or missing references) //IL_09b1: Unknown result type (might be due to invalid IL or missing references) //IL_09b6: Unknown result type (might be due to invalid IL or missing references) //IL_0a4a: Unknown result type (might be due to invalid IL or missing references) //IL_0a68: Unknown result type (might be due to invalid IL or missing references) //IL_0a7a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)compareGraphPanel == (Object)null) { return; } for (int num = compareGraphPanel.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)compareGraphPanel.transform.GetChild(num)).gameObject); } List list = new List(); for (int i = 0; i < compareSelected.Count; i++) { if (compareStatsCache.TryGetValue(compareSelected[i], out var value) && value != null) { list.Add(i); } } CompareChartSize(out var W, out var H); if (list.Count == 0) { MakeGraphLabel("CmpBarNone", "Select players (left) to chart " + metricName + ".", new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(W - 40f, 40f), 514); return; } if (metricName == "Region Time") { BuildComparePieChart(list, W, H); return; } float num2 = 60f; float num3 = 16f; float num4 = 34f; float num5 = 48f; float num6 = W - num2 - num3; float num7 = H - num4 - num5; int count = list.Count; float num8 = num6 / (float)count; bool flag = false; bool flag2 = false; string text = ""; string text2; switch (metricName) { case "Hit / Block %": text2 = "Hit % vs Block %"; flag = true; text = "%"; break; case "Avg Cards / Game": text2 = "Avg Cards per Game (lower = stronger)"; flag2 = true; break; case "Avg FPS": text2 = "Average FPS"; break; case "Peak Elo": text2 = "Peak Elo"; break; case "Total XP": text2 = "Total XP"; break; case "Achievements": text2 = "Achievements unlocked"; break; default: text2 = metricName; break; } MakeGraphLabel("CmpBarTitle", "" + text2 + "", new Vector2(0f, 1f), new Vector2(num2, -4f), new Vector2(W - num2, 18f), 513); Func func = null; Func func2 = null; switch (metricName) { case "Hit / Block %": func = (ApiClient.PlayerStatsData ps) => (ps.bullets_fired <= 0) ? 0f : ((float)ps.bullets_hit * 100f / (float)ps.bullets_fired); func2 = (ApiClient.PlayerStatsData ps) => (ps.blocks_activated <= 0) ? 0f : ((float)ps.blocks_successful * 100f / (float)ps.blocks_activated); break; case "Avg Cards / Game": func = (ApiClient.PlayerStatsData ps) => ps.avg_cards_per_game; break; case "Avg FPS": func = (ApiClient.PlayerStatsData ps) => ps.avg_fps; break; case "Peak Elo": func = (ApiClient.PlayerStatsData ps) => ps.peak_rating; break; case "Total XP": func = (ApiClient.PlayerStatsData ps) => ps.total_xp; break; case "Achievements": func = (ApiClient.PlayerStatsData ps) => ps.achievements_unlocked; break; default: func = (ApiClient.PlayerStatsData ps) => 0f; break; } float num9; float num10; if (flag) { num9 = 100f; num10 = 25f; } else if (flag2) { num9 = 5f; num10 = 1f; } else { float num11 = 0.0001f; foreach (int item in list) { float num12 = func(compareStatsCache[compareSelected[item]]); if (num12 > num11) { num11 = num12; } } num10 = NiceStep(num11 / 4f); num9 = Mathf.Ceil(num11 * 1.08f / num10) * num10; if (num9 < num10) { num9 = num10; } } if (metricName == "Total XP") { int num13 = LevelForXp(num9); int num14 = Mathf.Max(1, Mathf.CeilToInt((float)num13 / 6f)); MakeGraphLabel("CmpBarY0", "Lv 0", new Vector2(0f, 0f), new Vector2(num2 - 4f, num5 - 6f), new Vector2(52f, 12f), 516); for (int num15 = num14; num15 <= num13; num15 += num14) { float num16 = TotalXpForLevel(num15); if (num16 > num9) { break; } float num17 = num5 + num16 / num9 * num7; DrawBar($"CmpBarGridL{num15}", num2, num17, num6, 1f, new Color(1f, 1f, 1f, 0.1f)); MakeGraphLabel($"CmpBarYL{num15}", $"Lv {num15}", new Vector2(0f, 0f), new Vector2(num2 - 4f, num17 - 6f), new Vector2(52f, 12f), 516); } } else { int num18 = Mathf.Clamp(Mathf.RoundToInt(num9 / num10), 2, 10); for (int num19 = 0; num19 <= num18; num19++) { float num20 = (float)num19 * num10; if (num20 > num9 + 0.001f) { break; } float num21 = num5 + num20 / num9 * num7; DrawBar($"CmpBarGrid{num19}", num2, num21, num6, 1f, new Color(1f, 1f, 1f, 0.1f)); MakeGraphLabel($"CmpBarYLbl{num19}", "" + (flag2 ? num20.ToString("0") : FullNum(num20)) + text + "", new Vector2(0f, 0f), new Vector2(num2 - 4f, num21 - 6f), new Vector2(52f, 12f), 516); } } if (flag) { MakeGraphLabel("CmpHBLeg", "solid = Hit dim = Block", new Vector2(1f, 1f), new Vector2(0f - num3, -4f), new Vector2(260f, 14f), 516); } int max = Mathf.Clamp((int)(num8 / 8f), 5, 18); for (int num22 = 0; num22 < count; num22++) { int num23 = list[num22]; ApiClient.PlayerStatsData playerStatsData = compareStatsCache[compareSelected[num23]]; Color val = COMPARE_COLORS[num23 % COMPARE_COLORS.Length]; float num24 = num2 + (float)num22 * num8; if (flag) { float num25 = num8 * 0.32f; float num26 = num8 * 0.06f; float num27 = num24 + (num8 - (num25 * 2f + num26)) * 0.5f; float num28 = Mathf.Clamp(func(playerStatsData), 0f, num9); float num29 = Mathf.Clamp(func2(playerStatsData), 0f, num9); DrawBar($"CmpGrpA{num22}", num27, num5, num25, num28 / num9 * num7, new Color(val.r, val.g, val.b, 1f)); DrawBar($"CmpGrpB{num22}", num27 + num25 + num26, num5, num25, num29 / num9 * num7, new Color(val.r * 0.5f, val.g * 0.5f, val.b * 0.5f, 1f)); MakeGraphLabel($"CmpGrpVA{num22}", $"{func(playerStatsData):F1}", new Vector2(0f, 0f), new Vector2(num27 - 8f, num5 + num28 / num9 * num7 + 1f), new Vector2(num25 + 16f, 11f), 514); MakeGraphLabel($"CmpGrpVB{num22}", $"{func2(playerStatsData):F1}", new Vector2(0f, 0f), new Vector2(num27 + num25 + num26 - 8f, num5 + num29 / num9 * num7 + 1f), new Vector2(num25 + 16f, 11f), 514); } else { float num30 = num8 * 0.58f; float num31 = num24 + (num8 - num30) * 0.5f; float num32 = func(playerStatsData); float num33 = Mathf.Clamp(num32, 0f, num9); Color col = val; if (flag2 && num32 > 0f) { col = GradeColor((num32 - 1f) / 4f); } DrawBar($"CmpBar{num22}", num31, num5, num30, num33 / num9 * num7, col); string text3 = (flag2 ? num32.ToString("F2") : ((metricName == "Total XP") ? $"Lv {playerStatsData.level}" : FullNum(num32))); MakeGraphLabel($"CmpBarV{num22}", "" + text3 + "", new Vector2(0f, 0f), new Vector2(num31 - 6f, num5 + num33 / num9 * num7 + 1f), new Vector2(num30 + 12f, 12f), 514); } MakeGraphLabel($"CmpBarName{num22}", "" + Trunc(playerStatsData.display_name, max) + "", new Vector2(0f, 0f), new Vector2(num24 - 4f, num5 - 18f), new Vector2(num8 + 8f, 16f), 514, 13f); } } private static void BuildComparePieChart(List idxs, float W, float H) { //IL_0014: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Unknown result type (might be due to invalid IL or missing references) try { MakeGraphLabel("CmpPieTitle", "Region distribution", new Vector2(0f, 1f), new Vector2(16f, -4f), new Vector2(W - 20f, 18f), 513); List list = new List(); foreach (int idx in idxs) { ApiClient.PlayerStatsData playerStatsData = compareStatsCache[compareSelected[idx]]; if (playerStatsData.region_names == null) { continue; } foreach (string region_name in playerStatsData.region_names) { if (!list.Contains(region_name)) { list.Add(region_name); } } } for (int i = 0; i < list.Count; i++) { float num = -14f - (float)(i % 4) * 104f; float num2 = -4f - (float)(i / 4) * 17f; string text = ColorToHex(RegionColor(list[i])); MakeGraphLabel($"CmpPieLeg{i}", " " + list[i].ToUpperInvariant() + "", new Vector2(1f, 1f), new Vector2(num, num2), new Vector2(96f, 14f), 513, 13f); } int count = idxs.Count; int num3 = ((count <= 1) ? 1 : ((count <= 2) ? 2 : ((count <= 6) ? 3 : 4))); int num4 = (count + num3 - 1) / num3; float num5 = 30f + Mathf.Ceil((float)list.Count / 4f) * 17f; float num6 = 8f; float num7 = (W - 20f) / (float)num3; float num8 = (H - num5 - num6) / (float)Mathf.Max(1, num4); float num9 = Mathf.Max(26f, Mathf.Min(num7, num8) * 0.36f); bool flag = num3 <= 3; for (int j = 0; j < count; j++) { int num10 = idxs[j]; ApiClient.PlayerStatsData playerStatsData2 = compareStatsCache[compareSelected[num10]]; int num11 = j % num3; int num12 = j / num3; float num13 = 10f + (float)num11 * num7 + num7 * 0.5f; float num14 = H - num5 - (float)num12 * num8 - num8 * 0.5f; MakeGraphLabel($"CmpPieName{j}", "" + Trunc(playerStatsData2.display_name, 14) + "", new Vector2(0f, 0f), new Vector2(num13 - num7 * 0.5f, num14 + num9 + 4f), new Vector2(num7, 16f), 514, 14f); int num15 = 0; if (playerStatsData2.region_matches != null) { foreach (int region_match in playerStatsData2.region_matches) { num15 += region_match; } } if (playerStatsData2.region_names == null || num15 <= 0) { MakeGraphLabel($"CmpPieNo{j}", "no data", new Vector2(0f, 0f), new Vector2(num13 - 40f, num14 - 6f), new Vector2(80f, 12f), 514); continue; } DrawPieSlice($"CmpPieBdr{j}", num13, num14, num9 + 2.5f, 0f, 1f, new Color(0.1f, 0.11f, 0.14f, 1f)); float num16 = 0f; for (int k = 0; k < playerStatsData2.region_names.Count; k++) { int num17 = ((playerStatsData2.region_matches.Count > k) ? playerStatsData2.region_matches[k] : 0); if (num17 > 0) { float num18 = (float)num17 / (float)num15; DrawPieSlice($"CmpPie{j}_{k}", num13, num14, num9, num16, num18, RegionColor(playerStatsData2.region_names[k])); if (flag && num18 >= 0.07f) { float num19 = num16 + num18 * 0.5f; float num20 = MathF.PI / 2f - num19 * 2f * MathF.PI; float x = num13 + Mathf.Cos(num20) * num9; float y = num14 + Mathf.Sin(num20) * num9; float num21 = num13 + Mathf.Cos(num20) * (num9 + 20f); float num22 = num14 + Mathf.Sin(num20) * (num9 + 20f); DrawGraphSegment($"CmpPieLn{j}_{k}", x, y, num21, num22, new Color(0.8f, 0.8f, 0.8f, 0.7f), 1.5f); bool num23 = Mathf.Cos(num20) >= 0f; int align = (num23 ? 513 : 516); float num24 = (num23 ? (num21 + 2f) : (num21 - 66f)); MakeGraphLabel($"CmpPieLbl{j}_{k}", $"{playerStatsData2.region_names[k].ToUpperInvariant()} {num18 * 100f:F0}%", new Vector2(0f, 0f), new Vector2(num24, num22 - 6f), new Vector2(64f, 12f), align); } num16 += num18; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[COMPARE] pie chart failed: " + ex.Message)); } } private static void BuildCompareCardGrid(string metricName) { //IL_007f: 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) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)compareCardsContent == (Object)null || txtCompareCards == null) { return; } Transform val = compareCardsContent.transform.Find("CmpCardCols"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } if (compareSelected.Count == 0) { UIFactory.SetText(txtCompareCards, "Select players (left) to compare " + metricName + "."); ((Component)txtCompareCards).gameObject.SetActive(true); return; } ((Component)txtCompareCards).gameObject.SetActive(false); int num = ((compareSelected.Count <= 3) ? compareSelected.Count : ((compareSelected.Count <= 8) ? 2 : 3)); if (num < 1) { num = 1; } int num2 = (compareSelected.Count + num - 1) / num; GameObject val2 = new GameObject("CmpCardCols"); val2.transform.SetParent(compareCardsContent.transform, false); val2.AddComponent(); UIFactory.AddHLG(val2, 10f, 0, 0, 0, 0, forceExpandW: false, forceExpandH: false); GameObject[] array = (GameObject[])(object)new GameObject[num]; for (int i = 0; i < num; i++) { GameObject val3 = new GameObject($"CmpCol{i}"); val3.transform.SetParent(val2.transform, false); val3.AddComponent(); UIFactory.AddVLG(val3, 8f); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, 1f); array[i] = val3; } for (int j = 0; j < compareSelected.Count; j++) { int num3 = Math.Min(j / num2, num - 1); string key = compareSelected[j]; Color c = COMPARE_COLORS[j % COMPARE_COLORS.Length]; StringBuilder stringBuilder = new StringBuilder(); if (!compareStatsCache.TryGetValue(key, out var value) || value == null) { stringBuilder.Append("(loading...)"); } else { stringBuilder.Append("" + value.display_name + "\n"); if (metricName == "Worst Cards") { AppendCardList(stringBuilder, value.worst_card_names, value.worst_card_picks, value.worst_card_win_rates, "not enough data (4+ picks)"); } else { AppendCardList(stringBuilder, value.top_card_names, value.top_card_picks, value.top_card_win_rates, "no card data"); } } object obj = UIFactory.CreateText($"CmpCell{j}", array[num3].transform, stringBuilder.ToString(), 14f, C_DIM, 257, (Vector2?)new Vector2(250f, 24f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(obj, on: true); UIFactory.SetTextAutoHeight(obj); } } private static void BuildCompareMetricTable() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (txtCompareCards == null) { return; } string text = COMPARE_METRICS[Math.Max(0, Math.Min(compareMetric, COMPARE_METRICS.Length - 1))]; if (compareSelected.Count == 0) { UIFactory.SetText(txtCompareCards, "Select players (left) to compare " + text + "."); return; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < compareSelected.Count; i++) { string key = compareSelected[i]; Color c = COMPARE_COLORS[i % COMPARE_COLORS.Length]; if (!compareStatsCache.TryGetValue(key, out var value) || value == null) { stringBuilder.Append("(loading...)\n\n"); continue; } stringBuilder.Append("" + value.display_name + " "); switch (text) { case "Top Cards": stringBuilder.Append("\n"); AppendCardList(stringBuilder, value.top_card_names, value.top_card_picks, value.top_card_win_rates, "no card data"); break; case "Worst Cards": stringBuilder.Append("\n"); AppendCardList(stringBuilder, value.worst_card_names, value.worst_card_picks, value.worst_card_win_rates, "not enough card data (need 4+ picks)"); break; case "Hit / Block %": { string text2 = ((value.bullets_fired > 0) ? $"Hit {(float)value.bullets_hit * 100f / (float)value.bullets_fired:F1}% ({value.bullets_hit}/{value.bullets_fired})" : "Hit —"); string text3 = ((value.blocks_activated > 0) ? $"Block {(float)value.blocks_successful * 100f / (float)value.blocks_activated:F1}% ({value.blocks_successful}/{value.blocks_activated})" : "Block —"); stringBuilder.Append(text2 + " " + text3 + "\n"); break; } case "Avg Cards / Game": { float avg_cards_per_game = value.avg_cards_per_game; string arg = ((avg_cards_per_game > 0f && avg_cards_per_game <= 2f) ? "#00FF00" : ((avg_cards_per_game <= 3f) ? "#AAAAAA" : "#FF6666")); stringBuilder.Append((avg_cards_per_game > 0f) ? $"{avg_cards_per_game:F2} cards/game (lower = stronger)\n" : "no data\n"); break; } case "Avg FPS": stringBuilder.Append((value.avg_fps > 0) ? $"{value.avg_fps} avg fps\n" : "no fps data\n"); break; case "Peak Elo": stringBuilder.Append($"{value.peak_rating:F0} peak (now {value.rating:F0})\n"); break; case "Total XP": stringBuilder.Append($"{value.total_xp:N0} XP (Lv {value.level})\n"); break; case "Achievements": { int num4 = ((ApiClient.AchievementDefs != null) ? ApiClient.AchievementDefs.Count : 0); stringBuilder.Append((num4 > 0) ? $"{value.achievements_unlocked}/{num4} unlocked ({value.achievements_unlocked * 100 / Math.Max(1, num4)}%)\n" : $"{value.achievements_unlocked} unlocked\n"); break; } case "Region Time": stringBuilder.Append("\n"); if (value.region_names != null && value.region_names.Count > 0) { int num = 0; foreach (int region_match in value.region_matches) { num += region_match; } for (int j = 0; j < value.region_names.Count && j < 8; j++) { int num2 = ((value.region_matches.Count > j) ? value.region_matches[j] : 0); int num3 = ((num > 0) ? (num2 * 100 / num) : 0); stringBuilder.Append($" {value.region_names[j].ToUpperInvariant()} {num3}% ({num2})\n"); } } else { stringBuilder.Append(" no region data\n"); } break; default: stringBuilder.Append("\n"); break; } stringBuilder.Append("\n"); } UIFactory.SetText(txtCompareCards, stringBuilder.ToString()); } private static void AppendCardList(StringBuilder sb, List names, List picks, List wrs, string emptyMsg) { if (names != null && names.Count > 0) { for (int i = 0; i < names.Count && i < 8; i++) { string text = ((picks != null && picks.Count > i) ? $" ({picks[i]}x)" : ""); float num = ((wrs != null && wrs.Count > i) ? (wrs[i] * 100f) : 0f); string text2 = ((num >= 55f) ? "#00FF00" : ((num <= 45f) ? "#FF6666" : "#AAAAAA")); sb.Append($" {names[i]}{text} {num:F0}%\n"); } } else { sb.Append(" " + emptyMsg + "\n"); } } private static string GetAchievementText() { Dictionary selectedPlayerAchievements = ApiClient.SelectedPlayerAchievements; if (selectedPlayerAchievements == null) { return ""; } int num = 0; string text = "\nAchievements:\n"; foreach (KeyValuePair achievementDef in ApiClient.AchievementDefs) { int num2; if (selectedPlayerAchievements.ContainsKey(achievementDef.Key)) { num2 = (selectedPlayerAchievements[achievementDef.Key].unlocked ? 1 : 0); if (num2 != 0) { num++; } } else { num2 = 0; } string text2 = ((num2 != 0) ? "[X]" : "[ ]"); string text3 = ((num2 != 0) ? "#FFFFFF" : "#666666"); text = text + " " + text2 + " " + achievementDef.Value[0] + "\n"; } return text + $"\n {num} / {ApiClient.AchievementDefs.Count} unlocked"; } private static string BuildViewHistoryText() { if (string.IsNullOrEmpty(selectedSteamId)) { return ""; } List list = selectedViewHistory; if (list == null) { return "\nLoading match history...\n"; } StringBuilder stringBuilder = new StringBuilder(); string myId = MatchTracker.LocalSteamId; bool num = selectedSteamId == myId; string text = Trunc(selectedStats?.display_name ?? "Them", 12); int num2 = 0; if (!num && !string.IsNullOrEmpty(myId) && myId != "unknown") { List list2 = list.FindAll((ApiClient.MatchHistoryEntry m) => m.opponent_steam_id == myId && !string.IsNullOrEmpty(m.series_id) && m.series_id != "null" && m.is_ranked); if (list2.Count > 0) { List list3 = GroupBySeries(list2); list3.RemoveAll((SGroup g) => g.matches == null || g.matches.Count == 0); num2 = list3.Count; if (num2 > 0) { int num3 = (h2hSeriesTotalPages = (num2 + 2 - 1) / 2); if (h2hSeriesPage < 0) { h2hSeriesPage = 0; } if (h2hSeriesPage > num3 - 1) { h2hSeriesPage = num3 - 1; } int num4 = h2hSeriesPage * 2; int num5 = Math.Min(num4 + 2, num2); string text2 = ((num3 > 1) ? $" (page {h2hSeriesPage + 1}/{num3}, {num2} total)" : ""); stringBuilder.Append("\nRanked Series vs You" + text2 + "\n"); for (int num6 = num4; num6 < num5; num6++) { SGroup sGroup = list3[num6]; ApiClient.MatchHistoryEntry matchHistoryEntry = sGroup.matches[0]; string text3 = matchHistoryEntry.series_score ?? "?-?"; string text4 = ""; try { if (!string.IsNullOrEmpty(matchHistoryEntry.ended_at) && matchHistoryEntry.ended_at.Length >= 10) { text4 = DateTime.Parse(matchHistoryEntry.ended_at).ToString("M/d/yy"); } } catch { } bool flag = false; bool flag2 = false; try { string[] array = text3.Split('-'); int num7 = int.Parse(array[0]); int num8 = int.Parse(array[1]); flag = num7 >= 2 || num8 >= 2; flag2 = num8 > num7; } catch { } string text5 = ((!flag) ? "in progress" : (flag2 ? "WON" : "LOST")); stringBuilder.Append(" " + text5 + " " + text3 + " their side " + text4 + "\n"); foreach (ApiClient.MatchHistoryEntry match in sGroup.matches) { string text6 = ((!match.won) ? "W" : "L"); string text7 = ""; try { if (!string.IsNullOrEmpty(match.ended_at) && match.ended_at.Length >= 10) { text7 = DateTime.Parse(match.ended_at).ToString("M/d"); } } catch { } stringBuilder.Append($" {text6} {match.opponent_rounds_won}-{match.player_rounds_won} {text7}\n"); if (!string.IsNullOrEmpty(match.opp_cards_display)) { stringBuilder.Append(" You: " + FormatCardLine(match.opp_cards_display) + "\n"); } if (!string.IsNullOrEmpty(match.cards_display)) { stringBuilder.Append(" " + text + ": " + FormatCardLine(match.cards_display) + "\n"); } } } } } } if ((Object)(object)h2hPager != (Object)null) { bool flag3 = num2 > 2; h2hPager.SetActive(flag3); if (flag3) { if (txtH2hPage != null) { UIFactory.SetText(txtH2hPage, $"{h2hSeriesPage + 1}/{h2hSeriesTotalPages}"); } if ((Object)(object)h2hPrev != (Object)null) { h2hPrev.SetActive(h2hSeriesPage > 0); } if ((Object)(object)h2hNext != (Object)null) { h2hNext.SetActive(h2hSeriesPage < h2hSeriesTotalPages - 1); } } } List list4 = list.FindAll((ApiClient.MatchHistoryEntry m) => m.is_ranked && !string.IsNullOrEmpty(m.series_id) && m.series_id != "null"); if (list4.Count > 0) { List list5 = GroupBySeries(list4); stringBuilder.Append("\nRanked History (recent series)\n"); int num9 = 0; foreach (SGroup item in list5) { if (num9 >= 12) { break; } if (item.matches == null || item.matches.Count == 0) { continue; } ApiClient.MatchHistoryEntry matchHistoryEntry2 = item.matches[0]; string text8 = matchHistoryEntry2.series_score ?? "?-?"; bool flag4 = false; bool flag5 = false; try { string[] array2 = text8.Split('-'); int num10 = int.Parse(array2[0]); int num11 = int.Parse(array2[1]); flag4 = num10 >= 2 || num11 >= 2; flag5 = num10 > num11; } catch { } string text9 = Trunc(matchHistoryEntry2.opponent_name ?? "?", 14); string text10 = ""; try { if (!string.IsNullOrEmpty(matchHistoryEntry2.ended_at) && matchHistoryEntry2.ended_at.Length >= 10) { text10 = DateTime.Parse(matchHistoryEntry2.ended_at).ToString("M/d"); } } catch { } string text11 = ((!flag4) ? "-" : (flag5 ? "W" : "L")); string text12 = ((flag4 && matchHistoryEntry2.series_rating_change != 0f) ? string.Format(" {1}{2:F0}", (matchHistoryEntry2.series_rating_change > 0f) ? "#00FF00" : "#FF6666", (matchHistoryEntry2.series_rating_change > 0f) ? "+" : "", matchHistoryEntry2.series_rating_change) : ""); stringBuilder.Append(" " + text11 + " " + text8 + " vs " + text9 + text12 + " " + text10 + "\n"); num9++; } } else { stringBuilder.Append("\nRanked History: no ranked series yet\n"); } return stringBuilder.ToString(); } private static void RefreshCardStats() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_06e0: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Unknown result type (might be due to invalid IL or missing references) //IL_0736: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[7] { "Tier", "Card", "Rarity", "Picks", "Wins", "WR%", "Pass%" }; string[] array2 = new string[7] { "tier", "card_name", "card_rarity", "times_picked", "wins_with_card", "win_rate", "pass_rate" }; if (cardSortTexts != null) { for (int i = 0; i < 7 && i < cardSortTexts.Length; i++) { if (cardSortTexts[i] != null) { string text = ((!(cardSort == array2[i])) ? "" : (cardSortDesc ? " v" : " ^")); UIFactory.SetText(cardSortTexts[i], array[i] + text); UIFactory.SetColor(cardSortTexts[i], (cardSort == array2[i]) ? C_WHITE : C_LABEL); if (cardSortBtns != null && i < cardSortBtns.Length) { UIFactory.SetImageColor(cardSortBtns[i], (cardSort == array2[i]) ? C_TABACT : C_TAB); } } } } List cachedCardStats = ApiClient.CachedCardStats; foreach (CardRow cardRow2 in cardRows) { cardRow2.root.SetActive(false); } if (cachedCardStats == null || cachedCardStats.Count == 0) { return; } List list = new List(); Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (ApiClient.CardStatData item in cachedCardStats) { string key = (item.card_name ?? "?").ToLower().Replace(" ", ""); if (dictionary.ContainsKey(key)) { ApiClient.CardStatData cardStatData = list[dictionary[key]]; cardStatData.times_picked += item.times_picked; cardStatData.wins_with_card += item.wins_with_card; cardStatData.win_rate = ((cardStatData.times_picked > 0) ? ((float)cardStatData.wins_with_card / (float)cardStatData.times_picked) : 0f); cardStatData.times_offered = Math.Max(cardStatData.times_offered, item.times_offered); if (item.times_offered > 0) { cardStatData.pass_rate = item.pass_rate; } if ((cardStatData.card_rarity == null || cardStatData.card_rarity == "Unknown") && item.card_rarity != null && item.card_rarity != "Unknown") { cardStatData.card_rarity = item.card_rarity; } } else { dictionary[key] = list.Count; list.Add(new ApiClient.CardStatData { card_name = item.card_name, card_rarity = item.card_rarity, times_picked = item.times_picked, wins_with_card = item.wins_with_card, win_rate = item.win_rate, times_offered = item.times_offered, pass_rate = item.pass_rate }); } } switch (cardSort) { case "tier": list.Sort(delegate(ApiClient.CardStatData a, ApiClient.CardStatData b) { string value3; int value2 = TierRank(cardTierMap.TryGetValue(CardTierKey(cardFilter, a.card_name), out value3) ? value3 : ""); string value5; int value4 = TierRank(cardTierMap.TryGetValue(CardTierKey(cardFilter, b.card_name), out value5) ? value5 : ""); return (!cardSortDesc) ? value4.CompareTo(value2) : value2.CompareTo(value4); }); break; case "card_name": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? string.Compare(a.card_name, b.card_name, StringComparison.OrdinalIgnoreCase) : string.Compare(b.card_name, a.card_name, StringComparison.OrdinalIgnoreCase)); break; case "card_rarity": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? string.Compare(a.card_rarity, b.card_rarity, StringComparison.OrdinalIgnoreCase) : string.Compare(b.card_rarity, a.card_rarity, StringComparison.OrdinalIgnoreCase)); break; case "times_picked": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? a.times_picked.CompareTo(b.times_picked) : b.times_picked.CompareTo(a.times_picked)); break; case "wins_with_card": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? a.wins_with_card.CompareTo(b.wins_with_card) : b.wins_with_card.CompareTo(a.wins_with_card)); break; case "win_rate": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? a.win_rate.CompareTo(b.win_rate) : b.win_rate.CompareTo(a.win_rate)); break; case "pass_rate": list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? a.pass_rate.CompareTo(b.pass_rate) : b.pass_rate.CompareTo(a.pass_rate)); break; default: list.Sort((ApiClient.CardStatData a, ApiClient.CardStatData b) => (!cardSortDesc) ? a.times_picked.CompareTo(b.times_picked) : b.times_picked.CompareTo(a.times_picked)); break; } for (int num = 0; num < list.Count && num < cardRows.Count; num++) { ApiClient.CardStatData cardStatData2 = list[num]; CardRow cardRow = cardRows[num]; float num2 = cardStatData2.win_rate * 100f; Color c = ((num2 >= 55f) ? C_GREEN : ((num2 <= 45f) ? C_RED : C_WHITE)); cardRow.cardName = cardStatData2.card_name; UIFactory.SetText(cardRow.txtName, cardStatData2.card_name ?? "?"); string text2 = cardStatData2.card_rarity ?? "Unknown"; UIFactory.SetText(cardRow.txtRarity, text2); UIFactory.SetColor(cardRow.txtRarity, GetRarityColor(text2)); UIFactory.SetText(cardRow.txtPicks, $"{cardStatData2.times_picked}"); UIFactory.SetText(cardRow.txtWins, $"{cardStatData2.wins_with_card}"); UIFactory.SetText(cardRow.txtWR, $"{num2:F0}%"); UIFactory.SetColor(cardRow.txtWR, c); if (cardStatData2.times_offered > 0) { float num3 = cardStatData2.pass_rate * 100f; UIFactory.SetText(cardRow.txtPass, $"{num3:F0}%"); UIFactory.SetColor(cardRow.txtPass, (num3 >= 70f) ? C_RED : ((num3 <= 30f) ? C_GREEN : C_LABEL)); } else { UIFactory.SetText(cardRow.txtPass, "-"); UIFactory.SetColor(cardRow.txtPass, C_DIM); } string key2 = CardTierKey(cardFilter, cardStatData2.card_name); string value; string tierLetter = (cardTierMap.TryGetValue(key2, out value) ? value : ""); ApplyRowTierVisuals(cardRow, tierLetter); cardRow.root.SetActive(true); } static int TierRank(string tier) { if (string.IsNullOrEmpty(tier)) { return 99; } return tier switch { "S" => 0, "A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5, "F" => 6, _ => 99, }; } } private static void ApplyRowTierVisuals(CardRow row, string tierLetter) { //IL_007d: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(tierLetter)) { UIFactory.SetText(row.txtTier, "-"); UIFactory.SetImageColor(row.tierBtn, new Color(0.18f, 0.2f, 0.24f, 0.85f)); UIFactory.SetImageColor(row.hl, new Color(0f, 0f, 0f, 0f)); } else { UIFactory.SetText(row.txtTier, "" + tierLetter + ""); Color tierColor = GetTierColor(tierLetter); UIFactory.SetImageColor(row.tierBtn, tierColor); UIFactory.SetImageColor(row.hl, new Color(tierColor.r, tierColor.g, tierColor.b, 0.25f)); } } private static void CycleCardTierInPlace(CardRow row, string cardName) { if (!string.IsNullOrEmpty(cardName)) { string filter = ((cardFilter == 1) ? "ranked" : ((cardFilter == 2) ? "casual" : "all")); string key = CardTierKey(cardFilter, cardName); string value2; string value = (cardTierMap.TryGetValue(key, out value2) ? value2 : ""); int num = Array.IndexOf(TIER_CYCLE, value); if (num < 0) { num = 0; } string text = TIER_CYCLE[(num + 1) % TIER_CYCLE.Length]; cardTierMap[key] = text; ApiClient.SetCardTier(MatchTracker.LocalSteamId, cardName, filter, text); ApplyRowTierVisuals(row, text); } } private static Color GetTierColor(string t) { //IL_010f: 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) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) return (Color)(t switch { "S" => new Color(0.95f, 0.3f, 0.3f, 0.9f), "A" => new Color(1f, 0.55f, 0.22f, 0.9f), "B" => new Color(0.95f, 0.85f, 0.3f, 0.9f), "C" => new Color(0.45f, 0.85f, 0.45f, 0.9f), "D" => new Color(0.45f, 0.7f, 0.95f, 0.9f), "E" => new Color(0.65f, 0.55f, 0.95f, 0.9f), "F" => new Color(0.55f, 0.55f, 0.55f, 0.9f), _ => new Color(0.18f, 0.2f, 0.24f, 0.85f), }); } private static string BuildCellStatLine(string cardName) { try { if (string.IsNullOrEmpty(cardName)) { return ""; } string text = CardRarityLookup.GetCanonicalName(cardName) ?? cardName; string lcA = (cardName ?? "").ToLowerInvariant().Replace(" ", ""); string lcB = text.ToLowerInvariant().Replace(" ", ""); Component val = null; Type type = (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetType("CardChoice")).FirstOrDefault((Type t) => t != null); if (type != null) { object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); val = MatchOne(type.GetField("cards", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj) as Array); } if ((Object)(object)val == (Object)null) { val = MatchOne(Resources.FindObjectsOfTypeAll()); } if ((Object)(object)val == (Object)null) { return BuildStatBlockFromFallback(cardName, 8); } if (!((((object)val).GetType().GetField("cardStats", BindingFlags.Instance | BindingFlags.Public) ?? ((object)val).GetType().GetField("stats", BindingFlags.Instance | BindingFlags.Public))?.GetValue(val) is Array { Length: not 0 } array)) { return BuildStatBlockFromFallback(cardName, 8); } StringBuilder stringBuilder = new StringBuilder(); int num = 0; for (int num2 = 0; num2 < array.Length; num2++) { if (num >= 8) { break; } object value = array.GetValue(num2); if (value == null) { continue; } Type type2 = value.GetType(); string text2 = ((type2.GetField("stat", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value) as string) ?? "").Trim(); string value2 = ((type2.GetField("amount", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value) as string) ?? "").Trim(); bool flag = !(type2.GetField("positive", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value) is bool flag2) || flag2; if (!string.IsNullOrEmpty(text2) || !string.IsNullOrEmpty(value2)) { string value3 = (flag ? "#88FF88" : "#FF8888"); if (stringBuilder.Length > 0) { stringBuilder.Append("\n"); } string text3 = NormalizeStatLabel(text2); string value4 = ((text3.Length > 16) ? (text3.Substring(0, 14) + "…") : text3); stringBuilder.Append("") .Append(value2) .Append(" ") .Append(value4); num++; } } return stringBuilder.ToString(); Component MatchOne(IEnumerable arr) { if (arr == null) { return null; } foreach (object item in arr) { Component val2 = (Component)((item is Component) ? item : null); if (!((Object)(object)val2 == (Object)null)) { string text4 = ((Object)val2.gameObject).name?.Replace("(Clone)", "").Trim() ?? ""; string text5 = (((object)val2).GetType().GetField("cardName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(val2) as string) ?? ""; if (text4.ToLowerInvariant().Replace(" ", "") == lcA || text4.ToLowerInvariant().Replace(" ", "") == lcB || text5.ToLowerInvariant().Replace(" ", "") == lcA || text5.ToLowerInvariant().Replace(" ", "") == lcB) { return val2; } } } return null; } } catch { return ""; } } public static void ExportCardTierList() { if ((Object)(object)Plugin.Instance == (Object)null) { return; } try { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ExportTierListCoroutine()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TIER-EXPORT] failed: " + ex.Message)); } } private static IEnumerator ExportTierListCoroutine() { if ((Object)(object)tierExportPanel != (Object)null) { Object.Destroy((Object)(object)tierExportPanel); } tierExportPanel = new GameObject("CR_TierExport"); ((Object)tierExportPanel).hideFlags = (HideFlags)61; tierExportPanel.transform.position = new Vector3(50000f, 50000f, 0f); Component obj = tierExportPanel.AddComponent(UIFactory.tCanvas); try { PropertyInfo property = UIFactory.tCanvas.GetProperty("renderMode", BindingFlags.Instance | BindingFlags.Public); if (property != null) { property.SetValue(obj, Enum.ToObject(property.PropertyType, 2)); } PropertyInfo property2 = UIFactory.tCanvas.GetProperty("sortingOrder", BindingFlags.Instance | BindingFlags.Public); if (property2 != null) { property2.SetValue(obj, 30000); } } catch { } RectTransform rootRT = tierExportPanel.GetComponent(); if ((Object)(object)rootRT == (Object)null) { rootRT = tierExportPanel.AddComponent(); } rootRT.sizeDelta = new Vector2(3000f, 6000f); ((Transform)rootRT).localScale = Vector3.one; GameObject val = UIFactory.CreatePanel("BG", tierExportPanel.transform, new Color(0.07f, 0.08f, 0.1f, 1f)); RectTransform bgRT = val.GetComponent(); bgRT.anchorMin = Vector2.zero; bgRT.anchorMax = Vector2.one; bgRT.offsetMin = Vector2.zero; bgRT.offsetMax = Vector2.zero; UIFactory.AddVLG(val, 14f, 24, 24, 18, 18); try { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("UnityEngine.UI.ContentSizeFitter"); if (type != null) { break; } } if (type != null) { Component obj3 = val.AddComponent(type); PropertyInfo property3 = type.GetProperty("verticalFit", BindingFlags.Instance | BindingFlags.Public); if (property3 != null) { property3.SetValue(obj3, Enum.ToObject(property3.PropertyType, 2)); } } } catch { } string filterStr = ((cardFilter == 1) ? "Ranked" : ((cardFilter == 2) ? "Casual" : "All")); UIFactory.CreateText("TXTitle", val.transform, "Sid's Competitive Rounds · Card Tier List (" + filterStr + ")", 36f, C_WHITE, 513, (Vector2?)new Vector2(2900f, 52f), richText: true, raycastTarget: false); List obj5 = ApiClient.CachedCardStats ?? new List(); List list = new List(); Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (ApiClient.CardStatData item in obj5) { string key = (item.card_name ?? "?").ToLower().Replace(" ", ""); if (dictionary.ContainsKey(key)) { ApiClient.CardStatData cardStatData = list[dictionary[key]]; cardStatData.times_picked += item.times_picked; cardStatData.wins_with_card += item.wins_with_card; cardStatData.win_rate = ((cardStatData.times_picked > 0) ? ((float)cardStatData.wins_with_card / (float)cardStatData.times_picked) : 0f); if ((cardStatData.card_rarity == null || cardStatData.card_rarity == "Unknown") && !string.IsNullOrEmpty(item.card_rarity) && item.card_rarity != "Unknown") { cardStatData.card_rarity = item.card_rarity; } } else { dictionary[key] = list.Count; list.Add(new ApiClient.CardStatData { card_name = item.card_name, card_rarity = item.card_rarity, times_picked = item.times_picked, wins_with_card = item.wins_with_card, win_rate = item.win_rate, times_offered = item.times_offered, pass_rate = item.pass_rate }); } } string[] array = new string[8] { "S", "A", "B", "C", "D", "E", "F", "" }; Dictionary> dictionary2 = new Dictionary>(); string[] array2 = array; foreach (string key2 in array2) { dictionary2[key2] = new List(); } foreach (ApiClient.CardStatData item2 in list) { string value; string key3 = (cardTierMap.TryGetValue(CardTierKey(cardFilter, item2.card_name), out value) ? value : ""); if (!dictionary2.ContainsKey(key3)) { key3 = ""; } dictionary2[key3].Add(item2); } int num = 2808; int num2 = Math.Max(3, num / 234); PropertyInfo property4 = UIFactory.tImage.GetProperty("sprite", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property5 = UIFactory.tImage.GetProperty("preserveAspect", BindingFlags.Instance | BindingFlags.Public); PropertyInfo property6 = UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public); array2 = array; foreach (string text in array2) { List list2 = dictionary2[text]; if (list2.Count == 0) { continue; } Color val2 = (Color)(string.IsNullOrEmpty(text) ? new Color(0.3f, 0.32f, 0.36f, 0.95f) : GetTierColor(text)); int num3 = (list2.Count + num2 - 1) / num2 * 416 + 12; GameObject val3 = new GameObject("T_" + text); val3.transform.SetParent(val.transform, false); val3.AddComponent(); UIFactory.AddHLG(val3, 8f, 8, 8, 6, 6); float prefH = num3; UIFactory.AddLE(val3, -1f, num3, -1f, prefH, -1f, 0f); GameObject val4 = UIFactory.CreatePanel("B_" + text, val3.transform, val2); prefH = num3 - 12; UIFactory.AddLE(val4, 130f, num3 - 12, 130f, prefH, 0f); UIFactory.CreateText("BL", val4.transform, "" + (string.IsNullOrEmpty(text) ? "Unranked" : text) + "", string.IsNullOrEmpty(text) ? 36f : 84f, Color.black, 514, (Vector2?)new Vector2(130f, (float)(num3 - 12)), richText: true, raycastTarget: false); GameObject val5 = new GameObject("R_" + text); val5.transform.SetParent(val3.transform, false); val5.AddComponent(); UIFactory.AddVLG(val5, 6f, 4, 4); prefH = num3 - 12; UIFactory.AddLE(val5, -1f, num3 - 12, -1f, prefH, 1f, 0f); GameObject val6 = null; int num4 = 0; foreach (ApiClient.CardStatData item3 in list2) { if ((Object)(object)val6 == (Object)null || num4 >= num2) { val6 = new GameObject($"row{list2.IndexOf(item3)}"); val6.transform.SetParent(val5.transform, false); val6.AddComponent(); UIFactory.AddHLG(val6, 8f); UIFactory.AddLE(val6, -1f, 410f, -1f, 410f, -1f, 0f); num4 = 0; } GameObject val7 = UIFactory.CreatePanel("C_" + item3.card_name, val6.transform, new Color(val2.r, val2.g, val2.b, 0.22f)); UIFactory.AddVLG(val7, 4f, 4, 4, 6, 6); UIFactory.AddLE(val7, 226f, 410f, 226f, 410f, 0f); Sprite sprite = CardImageLoader.GetSprite(item3.card_name); GameObject val8 = new GameObject("Img"); val8.transform.SetParent(val7.transform, false); val8.AddComponent(); Component obj6 = val8.AddComponent(UIFactory.tImage); if ((Object)(object)sprite != (Object)null) { property4?.SetValue(obj6, sprite); property5?.SetValue(obj6, true); property6?.SetValue(obj6, Color.white); } else { property6?.SetValue(obj6, (object)new Color(0.2f, 0.22f, 0.26f, 1f)); UIFactory.CreateText("Miss", val8.transform, "" + Trunc(item3.card_name ?? "?", 14) + "", 22f, C_WHITE, 514, (Vector2?)new Vector2(212f, 60f), richText: true, raycastTarget: false); } UIFactory.AddLE(val8, 220f, 330f, 220f, 330f, 0f, 0f); UIFactory.SetBold(UIFactory.CreateText("P", val7.transform, $"{item3.times_picked} played", 26f, C_WHITE, 514, (Vector2?)new Vector2(218f, 30f), richText: true, raycastTarget: false), b: true); float num5 = item3.win_rate * 100f; string arg = ((num5 >= 55f) ? "#88FF88" : ((num5 <= 45f) ? "#FF8888" : "#FFFFFF")); UIFactory.SetBold(UIFactory.CreateText("W", val7.transform, $"{num5:F0}% won", 26f, C_WHITE, 514, (Vector2?)new Vector2(218f, 30f), richText: true, raycastTarget: false), b: true); num4++; } while ((Object)(object)val6 != (Object)null && num4 < num2) { GameObject val9 = new GameObject("pad"); val9.transform.SetParent(val6.transform, false); val9.AddComponent(); UIFactory.AddLE(val9, 226f, -1f, 226f, -1f, 0f); num4++; } } string text2 = MatchTracker.LocalDisplayName; if (string.IsNullOrEmpty(text2) || text2 == "unknown") { text2 = "Anonymous"; } GameObject val10 = new GameObject("WM"); val10.transform.SetParent(val.transform, false); val10.AddComponent(); UIFactory.AddHLG(val10, 0f); UIFactory.AddLE(val10, -1f, -1f, -1f, 50f, -1f, 0f); UIFactory.CreateText("WMSteam", val10.transform, "" + text2 + "'s tier list", 26f, C_DIM, 513, (Vector2?)new Vector2(1400f, 50f), richText: true, raycastTarget: false); GameObject val11 = new GameObject("S"); val11.transform.SetParent(val10.transform, false); val11.AddComponent(); UIFactory.AddLE(val11, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("WMTxt", val10.transform, string.Format("Sid's Competitive Rounds mod · v{0} · {1:yyyy-MM-dd}", "1.28.2", DateTime.Now), 22f, C_DIM, 516, (Vector2?)new Vector2(1500f, 50f), richText: true, raycastTarget: false); yield return null; yield return null; try { Type type2 = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type2 = assemblies[i].GetType("UnityEngine.Canvas"); if (type2 != null) { break; } } type2?.GetMethod("ForceUpdateCanvases", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); } catch { } yield return null; Rect rect = bgRT.rect; int finalH = Mathf.CeilToInt(((Rect)(ref rect)).height); if (finalH < 600) { finalH = 600; } rootRT.sizeDelta = new Vector2(3000f, (float)finalH); yield return null; string text3; try { text3 = Path.GetFullPath(Path.Combine(Application.dataPath, "..", "CompetitiveRoundsTierLists")); Directory.CreateDirectory(text3); } catch { text3 = Application.persistentDataPath; } string path = $"tierlist-{filterStr}-{DateTime.Now:yyyyMMdd-HHmmss}.png"; string text4 = Path.Combine(text3, path); GameObject val12 = null; RenderTexture val13 = null; Texture2D val14 = null; try { val12 = new GameObject("CR_TierCam"); ((Object)val12).hideFlags = (HideFlags)61; val12.transform.position = new Vector3(50000f, 50000f, -10f); Camera obj9 = val12.AddComponent(); obj9.orthographic = true; obj9.orthographicSize = (float)finalH / 2f; obj9.aspect = 3000f / (float)Math.Max(1, finalH); obj9.clearFlags = (CameraClearFlags)2; obj9.backgroundColor = new Color(0.07f, 0.08f, 0.1f, 1f); obj9.cullingMask = -1; obj9.nearClipPlane = 0.1f; obj9.farClipPlane = 100f; val13 = (obj9.targetTexture = new RenderTexture(3000, finalH, 24)); obj9.Render(); RenderTexture active = RenderTexture.active; RenderTexture.active = val13; val14 = new Texture2D(3000, finalH, (TextureFormat)3, false); val14.ReadPixels(new Rect(0f, 0f, 3000f, (float)finalH), 0, 0); val14.Apply(); RenderTexture.active = active; byte[] bytes = ImageConversion.EncodeToPNG(val14); File.WriteAllBytes(text4, bytes); Plugin.Log.LogInfo((object)$"[TIER-EXPORT] saved {3000}×{finalH} → {text4}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TIER-EXPORT] capture failed: " + ex.Message)); } finally { try { if ((Object)(object)val12 != (Object)null) { Object.Destroy((Object)(object)val12); } } catch { } try { if ((Object)(object)val13 != (Object)null) { Object.Destroy((Object)(object)val13); } } catch { } try { if ((Object)(object)val14 != (Object)null) { Object.Destroy((Object)(object)val14); } } catch { } } try { if ((Object)(object)tierExportPanel != (Object)null) { Object.Destroy((Object)(object)tierExportPanel); } } catch { } tierExportPanel = null; CompetitiveUI.ShowNotification("Tier list saved to " + text4, new Color(0.4f, 0.9f, 0.4f), 12f); Plugin.Log.LogInfo((object)("[TIER-EXPORT] done — " + text4)); } private static Color GetRarityColor(string r) { //IL_0008: 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_0044: 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_0050: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(r)) { return C_LABEL; } return (Color)(r.ToLower() switch { "common" => C_COMMON, "uncommon" => C_UNCOMMON, "rare" => C_RARE, _ => C_LABEL, }); } public static void OnChatMessage(string json) { try { string text = ExtractChatField(json, "source"); string text2 = ExtractChatField(json, "display_name"); string text3 = ExtractChatField(json, "message"); int num = ExtractChatIntField(json, "rating"); string text4 = ExtractChatField(json, "title"); string text5 = ExtractChatField(json, "title_color"); if (string.IsNullOrEmpty(text3)) { return; } if (IsMuted(text2)) { Plugin.Log.LogInfo((object)("[CHAT] muted msg from " + text2 + " dropped locally")); return; } if (text3.Length > 500) { text3 = text3.Substring(0, 497) + "..."; } string text6 = ((text == "discord") ? "[D]" : "[game]"); string text7 = ((num > 0) ? $" ({num})" : ""); string text8 = ""; if (!string.IsNullOrEmpty(text4)) { string text9 = (string.IsNullOrEmpty(text5) ? "#CCCCCC" : text5); text8 = " [" + Escape(text4) + "]"; } string line = text6 + " " + Escape(text2) + "" + text8 + text7 + ": " + Escape(text3); lock (chatLinesLock) { chatLines.Add(new ChatEntry { Line = line, AddedUtc = DateTime.UtcNow }); while (chatLines.Count > 60) { chatLines.RemoveAt(0); } } MarkDirty(); } catch { } } private static HashSet GetMutedSet() { string obj = Plugin.MutedChatNames?.Value ?? ""; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = obj.Split('|'); for (int i = 0; i < array.Length; i++) { string text = (array[i] ?? "").Trim(); if (!string.IsNullOrEmpty(text)) { hashSet.Add(text); } } _mutedCache = hashSet; return hashSet; } private static bool IsMuted(string name) { if (string.IsNullOrEmpty(name)) { return false; } return (_mutedCache ?? GetMutedSet()).Contains(name); } private static void SaveMutedSet(HashSet set) { if (Plugin.MutedChatNames != null) { Plugin.MutedChatNames.Value = string.Join("|", set); _mutedCache = set; } } public static void HandleMuteCommand(string text) { try { if (text.Equals("/muted", StringComparison.OrdinalIgnoreCase)) { HashSet mutedSet = GetMutedSet(); string text2 = ((mutedSet.Count == 0) ? "(none)" : string.Join(", ", mutedSet)); AppendSystemChatLine("Muted: " + text2); return; } int num = text.IndexOf(' '); if (num < 0) { return; } string text3 = text.Substring(0, num).ToLowerInvariant(); string text4 = text.Substring(num + 1).Trim(); if (string.IsNullOrEmpty(text4)) { return; } HashSet mutedSet2 = GetMutedSet(); if (text3 == "/mute") { if (mutedSet2.Add(text4)) { SaveMutedSet(mutedSet2); AppendSystemChatLine("Muted " + Escape(text4) + ""); } else { AppendSystemChatLine("" + Escape(text4) + " is already muted"); } } else if (text3 == "/unmute") { if (mutedSet2.Remove(text4)) { SaveMutedSet(mutedSet2); AppendSystemChatLine("Unmuted " + Escape(text4) + ""); } else { AppendSystemChatLine("" + Escape(text4) + " isn't muted"); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MUTE] " + ex.Message)); } } private static void AppendSystemChatLine(string body) { string line = "[system] " + body; lock (chatLinesLock) { chatLines.Add(new ChatEntry { Line = line, AddedUtc = DateTime.UtcNow }); while (chatLines.Count > 60) { chatLines.RemoveAt(0); } } MarkDirty(); } private static void RefreshChatLog() { if (txtChatLog == null) { return; } string s; lock (chatLinesLock) { if (chatLines.Count == 0) { return; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < chatLines.Count; i++) { if (i > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(chatLines[i].Line); } s = stringBuilder.ToString(); } UIFactory.SetText(txtChatLog, s); CompetitiveRoundsBehaviour instance = Plugin.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(ScrollChatToBottomNextFrame()); } } private static IEnumerator ScrollChatToBottomNextFrame() { yield return null; if ((Object)(object)chatScrollRect == (Object)null) { yield break; } try { UIFactory.tScrollRect.GetProperty("verticalNormalizedPosition", BindingFlags.Instance | BindingFlags.Public)?.SetValue(chatScrollRect, 0f); } catch { } } private static string Escape(string s) { if (string.IsNullOrEmpty(s)) { return ""; } return s.Replace("<", "(").Replace(">", ")"); } private static int ExtractChatIntField(string json, string key) { if (string.IsNullOrEmpty(json)) { return 0; } string text = "\"" + key + "\""; int num = json.IndexOf(text); if (num < 0) { return 0; } int i; for (i = num + text.Length; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length || json[i] != ':') { return 0; } for (i++; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } int j; for (j = i; j < json.Length && (char.IsDigit(json[j]) || json[j] == '-' || json[j] == '.'); j++) { } if (j == i) { return 0; } try { return (int)Math.Round(float.Parse(json.Substring(i, j - i), CultureInfo.InvariantCulture)); } catch { return 0; } } private static string ExtractChatField(string json, string key) { if (string.IsNullOrEmpty(json)) { return ""; } string text = "\"" + key + "\""; int num = json.IndexOf(text); if (num < 0) { return ""; } int i; for (i = num + text.Length; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length || json[i] != ':') { return ""; } for (i++; i < json.Length && (json[i] == ' ' || json[i] == '\t'); i++) { } if (i >= json.Length || json[i] != '"') { return ""; } i++; StringBuilder stringBuilder = new StringBuilder(); while (i < json.Length) { char c = json[i]; if (c == '\\' && i + 1 < json.Length) { char c2 = json[i + 1]; switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 't': stringBuilder.Append('\t'); break; default: stringBuilder.Append(c2); break; } i += 2; } else { if (c == '"') { break; } stringBuilder.Append(c); i++; } } return stringBuilder.ToString(); } private static void RefreshQueueUI() { //IL_0041: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if (txtRankedStatus == null) { return; } bool value = Plugin.RankedEnabled.Value; ApiClient.QueueState currentQueueState = ApiClient.CurrentQueueState; UIFactory.SetText(txtRankedStatus, value ? "RANKED: ON" : "RANKED: OFF"); UIFactory.SetColor(txtRankedStatus, value ? C_GREEN : Color.gray); rankOnBtn.SetActive(!value); rankOffBtn.SetActive(value && !inGameMode); bool flag = GameStateWatcher.IsInMatch && GameStateWatcher.MatchIsRanked; qSearchBtn.SetActive(value && currentQueueState == ApiClient.QueueState.Idle && !flag); qCancelBtn.SetActive(value && currentQueueState == ApiClient.QueueState.Searching); if (currentQueueState == ApiClient.QueueState.Searching) { ApiClient.QueuePollData lastPollData = ApiClient.LastPollData; string s = "Searching..."; if (lastPollData != null && lastPollData.status == "searching") { int num = lastPollData.wait_time / 60; int num2 = lastPollData.wait_time % 60; s = string.Format("Searching... {0}{1}s +/-{2}", (num > 0) ? $"{num}m " : "", num2, lastPollData.elo_range) + ((lastPollData.queue_size > 1) ? $" ({lastPollData.queue_size} in queue)" : ""); } UIFactory.SetText(txtQueueInfo, s); UIFactory.SetColor(txtQueueInfo, C_BLUE); object obj = txtQueueInfo; object obj2 = ((obj is Component) ? obj : null); GameObject obj3 = ((obj2 != null) ? ((Component)obj2).gameObject : null); if (obj3 != null) { obj3.SetActive(true); } } else if (currentQueueState == ApiClient.QueueState.Idle && value) { int cachedQueueSearching = ApiClient.CachedQueueSearching; if (cachedQueueSearching > 0) { UIFactory.SetText(txtQueueInfo, $"{cachedQueueSearching} searching"); UIFactory.SetColor(txtQueueInfo, C_GREEN); } else { UIFactory.SetText(txtQueueInfo, "0 in queue"); UIFactory.SetColor(txtQueueInfo, C_DIM); } object obj4 = txtQueueInfo; object obj5 = ((obj4 is Component) ? obj4 : null); GameObject obj6 = ((obj5 != null) ? ((Component)obj5).gameObject : null); if (obj6 != null) { obj6.SetActive(true); } } else { UIFactory.SetText(txtQueueInfo, ""); object obj7 = txtQueueInfo; object obj8 = ((obj7 is Component) ? obj7 : null); GameObject obj9 = ((obj8 != null) ? ((Component)obj8).gameObject : null); if (obj9 != null) { obj9.SetActive(false); } } if (currentQueueState == ApiClient.QueueState.Matched || currentQueueState == ApiClient.QueueState.ReadySent) { qMatchPanel.SetActive(true); ApiClient.QueuePollData lastPollData2 = ApiClient.LastPollData; if (lastPollData2 != null) { string text = $"MATCH FOUND! vs {lastPollData2.opponent_name} ({lastPollData2.opponent_rating:F0})"; if (currentQueueState == ApiClient.QueueState.ReadySent && lastPollData2.opponent_ready) { text += " [Opponent Ready]"; } UIFactory.SetText(txtMatchFound, text); } bool flag2 = currentQueueState == ApiClient.QueueState.ReadySent; readyBtn.SetActive(!flag2); connectLabel.SetActive(flag2); if (flag2 && txtConnectLabel != null && lastPollData2 != null) { string s2 = ((!string.IsNullOrEmpty(lastPollData2.opponent_name)) ? $"Waiting for {lastPollData2.opponent_name} ({lastPollData2.opponent_rating:F0})..." : "Waiting for opponent..."); if (lastPollData2.opponent_ready) { s2 = lastPollData2.opponent_name + " ready! Joining..."; } UIFactory.SetText(txtConnectLabel, s2); } declineBtn.SetActive(true); } else { qMatchPanel.SetActive(false); } } private static int CalcStreak(List m) { if (m == null || m.Count == 0) { return 0; } bool won = m[0].won; int num = 0; for (int i = 0; i < m.Count && m[i].won == won; i++) { num++; } if (!won) { return -num; } return num; } private static string Trunc(string s, int max) { if (string.IsNullOrEmpty(s)) { return ""; } if (s.Length > max) { return s.Substring(0, max - 2) + ".."; } return s; } private static List GroupBySeries(List ranked) { List list = new List(); SGroup item = new SGroup { series_id = null, matches = null }; foreach (ApiClient.MatchHistoryEntry item2 in ranked) { string series_id = item2.series_id; bool flag = !string.IsNullOrEmpty(series_id) && series_id != "null"; if (flag && item.matches != null && item.series_id == series_id) { item.matches.Add(item2); continue; } if (item.matches != null && item.matches.Count > 0) { list.Add(item); } item = new SGroup { series_id = (flag ? series_id : null), matches = new List { item2 } }; } if (item.matches != null && item.matches.Count > 0) { list.Add(item); } return list; } private static GameObject BuildAdminTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0229: 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) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Expected O, but got Unknown //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Expected O, but got Unknown //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Expected O, but got Unknown //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Expected O, but got Unknown //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Expected O, but got Unknown GameObject val = new GameObject("AdminPanel"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 6f, 8, 8, 6, 6); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("AHdr"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddHLG(val2, 8f); UIFactory.AddLE(val2, -1f, -1f, -1f, 32f, -1f, 0f); UIFactory.CreateText("AT", val2.transform, "Admin Panel (visible only to whitelisted Steam IDs)", 18f, new Color(1f, 0.7f, 0.3f), 513, (Vector2?)new Vector2(600f, 28f), richText: true, raycastTarget: false); Transform transform = val2.transform; Color c_WHITE = C_WHITE; Color c_BTN = C_BTN; object obj = <>c.<>9__405_0; if (obj == null) { UnityAction val3 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.FetchFlaggedMatches(localSteamId); ApiClient.FetchBannedUsers(localSteamId); } }; <>c.<>9__405_0 = val3; obj = (object)val3; } UIFactory.CreateButton("ARefresh", transform, "Refresh", 13f, c_WHITE, c_BTN, (UnityAction)obj, (Vector2?)new Vector2(90f, 26f)); GameObject val4 = new GameObject("AAct"); val4.transform.SetParent(val.transform, false); val4.AddComponent(); UIFactory.AddHLG(val4, 8f); UIFactory.AddLE(val4, -1f, -1f, -1f, 30f, -1f, 0f); Transform transform2 = val4.transform; Color c_WHITE2 = C_WHITE; Color bgColor = new Color(0.55f, 0.15f, 0.15f, 0.9f); object obj2 = <>c.<>9__405_1; if (obj2 == null) { UnityAction val5 = delegate { CompetitiveUI.OpenAdminPrompt("ban"); }; <>c.<>9__405_1 = val5; obj2 = (object)val5; } UIFactory.CreateButton("ABan", transform2, "Ban Steam ID...", 13f, c_WHITE2, bgColor, (UnityAction)obj2, (Vector2?)new Vector2(140f, 26f)); Transform transform3 = val4.transform; Color c_WHITE3 = C_WHITE; Color bgColor2 = new Color(0.2f, 0.45f, 0.2f, 0.9f); object obj3 = <>c.<>9__405_2; if (obj3 == null) { UnityAction val6 = delegate { CompetitiveUI.OpenAdminPrompt("grant"); }; <>c.<>9__405_2 = val6; obj3 = (object)val6; } UIFactory.CreateButton("AGrant", transform3, "Grant Achievement...", 13f, c_WHITE3, bgColor2, (UnityAction)obj3, (Vector2?)new Vector2(170f, 26f)); Transform transform4 = val4.transform; Color c_WHITE4 = C_WHITE; Color bgColor3 = new Color(0.45f, 0.3f, 0.55f, 0.9f); object obj4 = <>c.<>9__405_3; if (obj4 == null) { UnityAction val7 = delegate { CompetitiveUI.OpenAdminPrompt("reverse"); }; <>c.<>9__405_3 = val7; obj4 = (object)val7; } UIFactory.CreateButton("ARev", transform4, "Reverse Series...", 13f, c_WHITE4, bgColor3, (UnityAction)obj4, (Vector2?)new Vector2(150f, 26f)); Transform transform5 = val4.transform; Color c_WHITE5 = C_WHITE; Color bgColor4 = new Color(0.2f, 0.3f, 0.5f, 0.9f); object obj5 = <>c.<>9__405_4; if (obj5 == null) { UnityAction val8 = delegate { CompetitiveUI.OpenBugReportAdminViewer(); }; <>c.<>9__405_4 = val8; obj5 = (object)val8; } UIFactory.CreateButton("ABugRpt", transform5, "Bug Reports...", 13f, c_WHITE5, bgColor4, (UnityAction)obj5, (Vector2?)new Vector2(150f, 26f)); GameObject val9 = new GameObject("ASplit"); val9.transform.SetParent(val.transform, false); val9.AddComponent(); UIFactory.AddHLG(val9, 8f); UIFactory.AddLE(val9, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val10 = new GameObject("AFLeft"); val10.transform.SetParent(val9.transform, false); val10.AddComponent(); UIFactory.AddVLG(val10, 4f); UIFactory.AddLE(val10, -1f, -1f, -1f, -1f, 1f, 1f); txtAdminFlagsHdr = UIFactory.CreateText("AFH", val10.transform, "Flagged Matches", 16f, new Color(1f, 0.55f, 0.3f), 257, (Vector2?)new Vector2(500f, 24f), richText: true, raycastTarget: false); UIFactory.SetBold(txtAdminFlagsHdr, b: true); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("AFSV", val10.transform); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); adminFlagsContainer = scrollViewRefs.content; GameObject val11 = new GameObject("AFRight"); val11.transform.SetParent(val9.transform, false); val11.AddComponent(); UIFactory.AddVLG(val11, 4f); UIFactory.AddLE(val11, -1f, -1f, 360f, -1f, -1f, 1f); txtAdminBansHdr = UIFactory.CreateText("ABH", val11.transform, "Banned Users", 16f, new Color(1f, 0.45f, 0.45f), 257, (Vector2?)new Vector2(340f, 24f), richText: true, raycastTarget: false); UIFactory.SetBold(txtAdminBansHdr, b: true); UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("ABSV", val11.transform); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); adminBansContainer = scrollViewRefs2.content; return val; } private static void RefreshAdmin() { List list = ApiClient.CachedFlaggedMatches ?? new List(); UIFactory.SetText(txtAdminFlagsHdr, $"Flagged Matches ({list.Count} unreviewed)"); for (int i = list.Count; i < adminFlagRowPool.Count; i++) { adminFlagRowPool[i].SetActive(false); } for (int j = 0; j < list.Count; j++) { if (j >= adminFlagRowPool.Count) { adminFlagRowPool.Add(BuildAdminFlagRow(adminFlagsContainer.transform, j)); } FillAdminFlagRow(adminFlagRowPool[j], list[j]); } List list2 = ApiClient.CachedBannedUsers ?? new List(); UIFactory.SetText(txtAdminBansHdr, $"Banned Users ({list2.Count})"); for (int k = list2.Count; k < adminBanRowPool.Count; k++) { adminBanRowPool[k].SetActive(false); } for (int l = 0; l < list2.Count; l++) { if (l >= adminBanRowPool.Count) { adminBanRowPool.Add(BuildAdminBanRow(adminBansContainer.transform, l)); } FillAdminBanRow(adminBanRowPool[l], list2[l]); } } private static GameObject BuildAdminFlagRow(Transform parent, int idx) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown GameObject val = UIFactory.CreatePanel($"AF{idx}", parent, new Color(0.18f, 0.13f, 0.13f, 0.85f)); UIFactory.AddHLG(val, 6f, 6, 6, 4, 4); UIFactory.AddLE(val, -1f, -1f, -1f, 38f, -1f, 0f); UIFactory.SetWordWrap(UIFactory.CreateText("AFT", val.transform, "", 13f, C_WHITE, 513, (Vector2?)new Vector2(420f, 30f), richText: true, raycastTarget: false), on: false); ((Component)val.transform.GetChild(0)).gameObject.AddComponent(); string name = $"AFOK{idx}"; Transform transform = val.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.5f, 0.15f, 0.15f, 0.9f); object obj = <>c.<>9__407_0; if (obj == null) { UnityAction val2 = delegate { }; <>c.<>9__407_0 = val2; obj = (object)val2; } UIFactory.CreateButton(name, transform, "Cheat", 11f, c_WHITE, bgColor, (UnityAction)obj, (Vector2?)new Vector2(70f, 26f)); string name2 = $"AFNO{idx}"; Transform transform2 = val.transform; Color c_WHITE2 = C_WHITE; Color bgColor2 = new Color(0.15f, 0.4f, 0.15f, 0.9f); object obj2 = <>c.<>9__407_1; if (obj2 == null) { UnityAction val3 = delegate { }; <>c.<>9__407_1 = val3; obj2 = (object)val3; } UIFactory.CreateButton(name2, transform2, "False+", 11f, c_WHITE2, bgColor2, (UnityAction)obj2, (Vector2?)new Vector2(70f, 26f)); val.SetActive(false); return val; } private static void FillAdminFlagRow(GameObject row, ApiClient.FlaggedMatchEntry e) { row.SetActive(true); Transform val = row.transform.Find("AFT"); if ((Object)(object)val != (Object)null) { string text = ""; try { if (!string.IsNullOrEmpty(e.created_at)) { text = DateTime.Parse(e.created_at).ToString("HH:mm"); } } catch { } string text2 = (e.auto_invalidated ? "auto-inv" : "advisory"); string text3 = (e.is_ranked ? "R" : "C"); string s = $"[{text}] {e.flag_reason} {text2} {Trunc(e.p1_name, 12)} vs {Trunc(e.p2_name, 12)} {text3}/{e.duration_seconds}s"; Component[] components = ((Component)val).GetComponents(); foreach (Component val2 in components) { if (((object)val2).GetType().Name == "TextMeshProUGUI") { UIFactory.SetText(val2, s); break; } } } Transform val3 = row.transform.Find("AFOK" + ((Object)row).name.Substring(2)); Transform val4 = row.transform.Find("AFNO" + ((Object)row).name.Substring(2)); if ((Object)(object)val3 != (Object)null) { WireButton(((Component)val3).gameObject, delegate { SubmitFlagReview(e.id, "confirmed_cheat"); }); } if ((Object)(object)val4 != (Object)null) { WireButton(((Component)val4).gameObject, delegate { SubmitFlagReview(e.id, "false_positive"); }); } } private static void SubmitFlagReview(string flagId, string action) { string sid = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(sid)) { return; } ApiClient.AdminReviewFlag(sid, flagId, action, delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)("[ADMIN] review " + action + " on " + flagId + ": " + (ok ? "OK" : "FAIL") + " " + resp)); if (ok) { ApiClient.FetchFlaggedMatches(sid); } }); } private static GameObject BuildAdminBanRow(Transform parent, int idx) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_0110: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown GameObject val = UIFactory.CreatePanel($"AB{idx}", parent, new Color(0.2f, 0.13f, 0.13f, 0.85f)); UIFactory.AddHLG(val, 6f, 6, 6, 4, 4); UIFactory.AddLE(val, -1f, -1f, -1f, 32f, -1f, 0f); UIFactory.CreateText("ABT", val.transform, "", 13f, C_WHITE, 513, (Vector2?)new Vector2(220f, 26f), richText: true, raycastTarget: false); string name = $"ABU{idx}"; Transform transform = val.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.2f, 0.45f, 0.2f, 0.9f); object obj = <>c.<>9__410_0; if (obj == null) { UnityAction val2 = delegate { }; <>c.<>9__410_0 = val2; obj = (object)val2; } UIFactory.CreateButton(name, transform, "Unban", 11f, c_WHITE, bgColor, (UnityAction)obj, (Vector2?)new Vector2(70f, 24f)); val.SetActive(false); return val; } private static void FillAdminBanRow(GameObject row, ApiClient.BannedUserEntry e) { row.SetActive(true); Transform val = row.transform.Find("ABT"); if ((Object)(object)val != (Object)null) { string s = "" + Trunc(e.display_name ?? e.steam_id, 16) + " " + Trunc(e.reason, 28) + ""; Component[] components = ((Component)val).GetComponents(); foreach (Component val2 in components) { if (((object)val2).GetType().Name == "TextMeshProUGUI") { UIFactory.SetText(val2, s); break; } } } Transform val3 = row.transform.Find("ABU" + ((Object)row).name.Substring(2)); if (!((Object)(object)val3 != (Object)null)) { return; } WireButton(((Component)val3).gameObject, delegate { string sid = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(sid)) { ApiClient.AdminUnban(sid, e.steam_id, delegate(bool ok, string resp) { Plugin.Log.LogInfo((object)("[ADMIN] unban " + e.steam_id + ": " + (ok ? "OK" : "FAIL") + " " + resp)); if (ok) { ApiClient.FetchBannedUsers(sid); ApiClient.FetchFlaggedMatches(sid); } }); } }); } private static void WireButton(GameObject btn, Action onClick) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown try { Component component = btn.GetComponent(UIFactory.tButton); if ((Object)(object)component == (Object)null) { return; } object obj = UIFactory.tButton.GetProperty("onClick", BindingFlags.Instance | BindingFlags.Public)?.GetValue(component); if (obj != null) { obj.GetType().GetMethod("RemoveAllListeners")?.Invoke(obj, null); MethodInfo method = obj.GetType().GetMethod("AddListener"); if (method != null) { UnityAction val = (UnityAction)delegate { if (ClickGuard.Claim()) { onClick(); } }; method.Invoke(obj, new object[1] { val }); } } ClickHandler component2 = btn.GetComponent(); if (!((Object)(object)component2 != (Object)null)) { return; } component2.onClick = delegate { if (ClickGuard.Claim()) { onClick(); } }; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ADMIN] WireButton failed: " + ex.Message)); } } public static void MaybeRefreshTournament() { if (currentTab == 7 && Time.unscaledTime >= tTournamentRefreshAt) { tTournamentRefreshAt = Time.unscaledTime + 10f; ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId); } } private static GameObject BuildTournamentsTab(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_011b: 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_014e: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: 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_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Expected O, but got Unknown //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Expected O, but got Unknown //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Expected O, but got Unknown //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Unknown result type (might be due to invalid IL or missing references) //IL_0624: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Expected O, but got Unknown //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_0779: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_07a4: Unknown result type (might be due to invalid IL or missing references) //IL_07ae: Expected O, but got Unknown //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Expected O, but got Unknown //IL_080e: Unknown result type (might be due to invalid IL or missing references) //IL_0815: Expected O, but got Unknown //IL_088d: Unknown result type (might be due to invalid IL or missing references) //IL_0892: Unknown result type (might be due to invalid IL or missing references) //IL_089f: Unknown result type (might be due to invalid IL or missing references) //IL_08ae: Unknown result type (might be due to invalid IL or missing references) //IL_08bd: Expected O, but got Unknown //IL_08ed: Unknown result type (might be due to invalid IL or missing references) //IL_0901: Unknown result type (might be due to invalid IL or missing references) //IL_093e: Unknown result type (might be due to invalid IL or missing references) //IL_0945: Expected O, but got Unknown //IL_09ae: Unknown result type (might be due to invalid IL or missing references) //IL_09c7: Unknown result type (might be due to invalid IL or missing references) //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_0a1b: Unknown result type (might be due to invalid IL or missing references) //IL_0a2f: Unknown result type (might be due to invalid IL or missing references) //IL_0a5b: Unknown result type (might be due to invalid IL or missing references) //IL_0a74: Unknown result type (might be due to invalid IL or missing references) //IL_09e0: Unknown result type (might be due to invalid IL or missing references) //IL_09e5: Unknown result type (might be due to invalid IL or missing references) //IL_09eb: Expected O, but got Unknown //IL_0aa2: Unknown result type (might be due to invalid IL or missing references) //IL_0ac1: Unknown result type (might be due to invalid IL or missing references) //IL_0b32: Unknown result type (might be due to invalid IL or missing references) //IL_0b46: Unknown result type (might be due to invalid IL or missing references) //IL_0b9a: Unknown result type (might be due to invalid IL or missing references) //IL_0bae: Unknown result type (might be due to invalid IL or missing references) //IL_0bc9: Unknown result type (might be due to invalid IL or missing references) //IL_0bd0: Expected O, but got Unknown //IL_0c3c: Unknown result type (might be due to invalid IL or missing references) //IL_0c55: Unknown result type (might be due to invalid IL or missing references) //IL_0a8d: Unknown result type (might be due to invalid IL or missing references) //IL_0a92: Unknown result type (might be due to invalid IL or missing references) //IL_0a98: Expected O, but got Unknown //IL_0c83: Unknown result type (might be due to invalid IL or missing references) //IL_0cad: Unknown result type (might be due to invalid IL or missing references) //IL_0cc6: Unknown result type (might be due to invalid IL or missing references) //IL_0c6e: Unknown result type (might be due to invalid IL or missing references) //IL_0c73: Unknown result type (might be due to invalid IL or missing references) //IL_0c79: Expected O, but got Unknown //IL_0cf4: Unknown result type (might be due to invalid IL or missing references) //IL_0d18: Unknown result type (might be due to invalid IL or missing references) //IL_0d1f: Expected O, but got Unknown //IL_0d7d: Unknown result type (might be due to invalid IL or missing references) //IL_0de0: Unknown result type (might be due to invalid IL or missing references) //IL_0df4: Unknown result type (might be due to invalid IL or missing references) //IL_0cdf: Unknown result type (might be due to invalid IL or missing references) //IL_0ce4: Unknown result type (might be due to invalid IL or missing references) //IL_0cea: Expected O, but got Unknown //IL_0e69: Unknown result type (might be due to invalid IL or missing references) //IL_0e70: Expected O, but got Unknown //IL_0edc: Unknown result type (might be due to invalid IL or missing references) //IL_0ef0: Unknown result type (might be due to invalid IL or missing references) //IL_0f19: Unknown result type (might be due to invalid IL or missing references) //IL_0f2d: Unknown result type (might be due to invalid IL or missing references) //IL_0f56: Unknown result type (might be due to invalid IL or missing references) //IL_0f6a: Unknown result type (might be due to invalid IL or missing references) //IL_0fcb: Unknown result type (might be due to invalid IL or missing references) //IL_103a: Unknown result type (might be due to invalid IL or missing references) //IL_104e: Unknown result type (might be due to invalid IL or missing references) //IL_1069: Unknown result type (might be due to invalid IL or missing references) //IL_1073: Expected O, but got Unknown //IL_10c4: Unknown result type (might be due to invalid IL or missing references) //IL_1127: Unknown result type (might be due to invalid IL or missing references) //IL_113b: Unknown result type (might be due to invalid IL or missing references) //IL_11c0: Unknown result type (might be due to invalid IL or missing references) //IL_11c7: Expected O, but got Unknown //IL_1233: Unknown result type (might be due to invalid IL or missing references) //IL_1247: Unknown result type (might be due to invalid IL or missing references) //IL_1322: Unknown result type (might be due to invalid IL or missing references) //IL_132c: Expected O, but got Unknown //IL_135b: Unknown result type (might be due to invalid IL or missing references) //IL_1370: Unknown result type (might be due to invalid IL or missing references) //IL_1385: Unknown result type (might be due to invalid IL or missing references) //IL_1399: Unknown result type (might be due to invalid IL or missing references) //IL_13fb: Unknown result type (might be due to invalid IL or missing references) //IL_140f: Unknown result type (might be due to invalid IL or missing references) //IL_1431: Unknown result type (might be due to invalid IL or missing references) //IL_1494: Unknown result type (might be due to invalid IL or missing references) //IL_14a8: Unknown result type (might be due to invalid IL or missing references) //IL_12bb: Unknown result type (might be due to invalid IL or missing references) //IL_151d: Unknown result type (might be due to invalid IL or missing references) //IL_1524: Expected O, but got Unknown //IL_1590: Unknown result type (might be due to invalid IL or missing references) //IL_15a4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Tournaments"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddHLG(val, 8f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); GameObject val2 = new GameObject("TLeft"); val2.transform.SetParent(val.transform, false); val2.AddComponent(); UIFactory.AddVLG(val2, 6f); UIFactory.AddLE(val2, 360f, -1f, 430f); GameObject val3 = new GameObject("TSubTabs"); val3.transform.SetParent(val2.transform, false); val3.AddComponent(); UIFactory.AddHLG(val3); UIFactory.AddLE(val3, -1f, -1f, -1f, 30f, -1f, 0f); Transform transform = val3.transform; Color c_WHITE = C_WHITE; Color c_TABACT = C_TABACT; object obj = <>c.<>9__460_0; if (obj == null) { UnityAction val4 = delegate { if (!(ApiClient.TournamentKind == "sync")) { ApiClient.TournamentKind = "sync"; ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId, force: true); dirty = true; } }; <>c.<>9__460_0 = val4; obj = (object)val4; } tSubTabSyncBtn = UIFactory.CreateButton("TSTSy", transform, "SYNC (weekly)", 14f, c_WHITE, c_TABACT, (UnityAction)obj, (Vector2?)new Vector2(180f, 26f)); Transform transform2 = val3.transform; Color c_LABEL = C_LABEL; Color c_TAB = C_TAB; object obj2 = <>c.<>9__460_1; if (obj2 == null) { UnityAction val5 = delegate { if (!(ApiClient.TournamentKind == "async")) { ApiClient.TournamentKind = "async"; ApiClient.FetchTournamentCurrent(MatchTracker.LocalSteamId, force: true); dirty = true; } }; <>c.<>9__460_1 = val5; obj2 = (object)val5; } tSubTabAsyncBtn = UIFactory.CreateButton("TSTAs", transform2, "ASYNC (6-week)", 14f, c_LABEL, c_TAB, (UnityAction)obj2, (Vector2?)new Vector2(180f, 26f)); GameObject val6 = UIFactory.CreatePanel("THdr", val2.transform, C_PANEL); UIFactory.AddVLG(val6, 2f, 10, 10, 6, 6); UIFactory.AddLE(val6, -1f, -1f, -1f, -1f, -1f, 0f); txtTState = UIFactory.CreateText("TS", val6.transform, "Loading...", 22f, C_GOLD, 513, (Vector2?)new Vector2(380f, 28f), richText: true, raycastTarget: false); UIFactory.SetBold(txtTState, b: true); txtTWhen = UIFactory.CreateText("TW", val6.transform, "", 15f, C_SUB, 513, (Vector2?)new Vector2(380f, 22f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtTWhen, on: true); txtTInstructions = UIFactory.CreateText("TI", val6.transform, "HOW IT WORKS (Sync)\n 1. Sign up (Discord must be linked)\n 2. Vote on start time if you want\n 3. Keep this tab open at start time\n 4. Mod auto-connects you to your opponent - no queue, no invites\n 5. Play BO3, bracket advances automatically\n\nREADY-UP\n * Press Ready Up within 5 min of your match starting or forfeit\n * Tab open = heartbeat keeps you ready; don't alt-tab for long\n * Bracket hidden until start (no scouting your first opponent)\n\nFORMAT\n * Double-elim BO3 (first to 2) - losing once drops you to the losers bracket\n * Matches run in parallel: you play your next match the moment your opponent is ready\n * Top seeds get byes when fewer than 16 sign up\n * Grand Final: WB champ vs LB champ (bracket reset if LB wins first BO3)\n * All matches count toward ranked Elo\n\nPRIZES (16-player full tier)\n * 1st - 500g / 2500 XP / Winner role\n * 2nd - 300g / 1500 XP / Runner Up role\n * 3rd - 60g / 75 XP / 3rd Place role (loser of LB final)\n * Scaled 60% at 12-15p, 30% at 8-11p, cancelled under 8\n\nPENALTY %\n * Grows when you sign up but no-show at match time\n * Lower penalty = priority if more than 16 sign up", 13f, C_LABEL, 513, (Vector2?)new Vector2(400f, 560f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtTInstructions, on: true); object obj3 = txtTInstructions; object obj4 = ((obj3 is Component) ? obj3 : null); Component val7 = ((obj4 != null) ? ((Component)obj4).gameObject.GetComponent(UIFactory.tLE) : null); if ((Object)(object)val7 != (Object)null) { UIFactory.tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val7, -1f); } GameObject val8 = new GameObject("TZRow"); val8.transform.SetParent(val2.transform, false); val8.AddComponent(); UIFactory.AddHLG(val8, 6f); UIFactory.AddLE(val8, -1f, -1f, -1f, 26f, -1f, 0f); UIFactory.CreateText("TZL", val8.transform, "Times in:", 14f, C_LABEL, 513, (Vector2?)new Vector2(80f, 24f), richText: true, raycastTarget: false); Transform transform3 = val8.transform; string label = _TzLabel(); Color c_WHITE2 = C_WHITE; Color c_BTN = C_BTN; object obj5 = <>c.<>9__460_2; if (obj5 == null) { UnityAction val9 = delegate { _CycleTz(); }; <>c.<>9__460_2 = val9; obj5 = (object)val9; } txtTTzButton = UIFactory.CreateButton("TZBtn", transform3, label, 14f, c_WHITE2, c_BTN, (UnityAction)obj5, (Vector2?)new Vector2(80f, 24f)); UIFactory.CreateText("TDL", val8.transform, "fmt:", 14f, C_LABEL, 513, (Vector2?)new Vector2(40f, 24f), richText: true, raycastTarget: false); Transform transform4 = val8.transform; string label2 = _DateFormat(); Color c_WHITE3 = C_WHITE; Color c_BTN2 = C_BTN; object obj6 = <>c.<>9__460_3; if (obj6 == null) { UnityAction val10 = delegate { _CycleDateFormat(); }; <>c.<>9__460_3 = val10; obj6 = (object)val10; } txtTDateFmtButton = UIFactory.CreateButton("TDFBtn", transform4, label2, 14f, c_WHITE3, c_BTN2, (UnityAction)obj6, (Vector2?)new Vector2(60f, 24f)); txtTTzNow = UIFactory.CreateText("TZN", val8.transform, "", 13f, new Color(0.8f, 0.9f, 1f), 513, (Vector2?)new Vector2(180f, 24f), richText: true, raycastTarget: false); GameObject val11 = new GameObject("TSAct"); val11.transform.SetParent(val2.transform, false); val11.AddComponent(); UIFactory.AddHLG(val11, 6f); UIFactory.AddLE(val11, -1f, -1f, -1f, 30f, -1f, 0f); Transform transform5 = val11.transform; Color c_WHITE4 = C_WHITE; Color bgColor = new Color(0.22f, 0.5f, 0.3f, 0.95f); object obj7 = <>c.<>9__460_4; if (obj7 == null) { UnityAction val12 = delegate { string localSteamId = MatchTracker.LocalSteamId; ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id) && !string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.TournamentSignup(cachedTournament.tournament_id, localSteamId, MatchTracker.LocalDisplayName); } }; <>c.<>9__460_4 = val12; obj7 = (object)val12; } txtTSignupBtn = UIFactory.CreateButton("TSign", transform5, "Sign Up for Tournament", 15f, c_WHITE4, bgColor, (UnityAction)obj7, (Vector2?)new Vector2(220f, 28f)); Transform transform6 = val11.transform; Color c_WHITE5 = C_WHITE; Color bgColor2 = new Color(0.5f, 0.2f, 0.2f, 0.95f); object obj8 = <>c.<>9__460_5; if (obj8 == null) { UnityAction val13 = delegate { string localSteamId = MatchTracker.LocalSteamId; ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id) && !string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.TournamentUnsignup(cachedTournament.tournament_id, localSteamId); } }; <>c.<>9__460_5 = val13; obj8 = (object)val13; } txtTUnsignupBtn = UIFactory.CreateButton("TUns", transform6, "Leave Signup", 15f, c_WHITE5, bgColor2, (UnityAction)obj8, (Vector2?)new Vector2(150f, 28f)); txtTUnsignupBtn.SetActive(false); txtTDiscordGate = UIFactory.CreateText("TDG", val11.transform, "", 13f, new Color(1f, 0.6f, 0.4f), 513, (Vector2?)new Vector2(260f, 28f), richText: true, raycastTarget: false); txtTPenalty = UIFactory.CreateText("TPen", val2.transform, "", 14f, C_LABEL, 513, (Vector2?)new Vector2(400f, 22f), richText: true, raycastTarget: false); tVoteBoxPanel = UIFactory.CreatePanel("TVoteBox", val2.transform, C_PANEL); GameObject val14 = tVoteBoxPanel; UIFactory.AddVLG(val14, 2f, 10, 10, 6, 6); UIFactory.AddLE(val14, -1f, -1f, -1f, -1f, -1f, 0f); UIFactory.CreateText("TVH", val14.transform, "Vote on Start Time (multi-select)", 16f, C_SUB, 513, (Vector2?)new Vector2(380f, 22f), richText: true, raycastTarget: false); tTimeVoteRow = new GameObject("TVR"); tTimeVoteRow.transform.SetParent(val14.transform, false); tTimeVoteRow.AddComponent(); UIFactory.AddVLG(tTimeVoteRow); for (int num = 0; num < 8; num++) { int idx = num; GameObject val15 = new GameObject($"Slot{num}"); val15.transform.SetParent(tTimeVoteRow.transform, false); val15.AddComponent(); UIFactory.AddHLG(val15, 6f); UIFactory.AddLE(val15, -1f, -1f, -1f, 24f, -1f, 0f); GameObject item = UIFactory.CreateButton($"Tog{num}", val15.transform, "[ ]", 14f, C_WHITE, C_BTN, (UnityAction)delegate { if (tSlotChecked.Count > idx) { tSlotChecked[idx] = !tSlotChecked[idx]; _tVoteLocalEdited = true; dirty = true; } }, (Vector2?)new Vector2(36f, 22f)); tSlotToggles.Add(item); object item2 = UIFactory.CreateText($"Lbl{num}", val15.transform, "", 14f, C_LABEL, 513, (Vector2?)new Vector2(320f, 22f), richText: true, raycastTarget: false); tSlotLabels.Add(item2); tSlotChecked.Add(item: false); } GameObject val16 = new GameObject("TVSub"); val16.transform.SetParent(val14.transform, false); val16.AddComponent(); UIFactory.AddHLG(val16, 6f); UIFactory.AddLE(val16, -1f, -1f, -1f, 28f, -1f, 0f); Transform transform7 = val16.transform; Color c_WHITE6 = C_WHITE; Color bgColor3 = new Color(0.22f, 0.38f, 0.65f, 0.95f); object obj9 = <>c.<>9__460_6; if (obj9 == null) { UnityAction val17 = delegate { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id)) { List list = new List(); for (int i = 0; i < tSlotChecked.Count; i++) { int num5 = i; string[] time_slot_options = cachedTournament.time_slot_options; if (num5 >= ((time_slot_options != null) ? time_slot_options.Length : 0)) { break; } if (tSlotChecked[i]) { list.Add(cachedTournament.time_slot_options[i]); } } ApiClient.TournamentTimeVote(cachedTournament.tournament_id, MatchTracker.LocalSteamId, list.ToArray()); _tVoteLocalEdited = false; } }; <>c.<>9__460_6 = val17; obj9 = (object)val17; } UIFactory.CreateButton("TVSubmit", transform7, "Save Votes", 15f, c_WHITE6, bgColor3, (UnityAction)obj9, (Vector2?)new Vector2(120f, 26f)); txtTForceCount = UIFactory.CreateText("TFC", val16.transform, "", 13f, C_DIM, 513, (Vector2?)new Vector2(180f, 26f), richText: true, raycastTarget: false); Transform transform8 = val16.transform; Color c_WHITE7 = C_WHITE; Color bgColor4 = new Color(0.55f, 0.35f, 0.15f, 0.95f); object obj10 = <>c.<>9__460_7; if (obj10 == null) { UnityAction val18 = delegate { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id)) { ApiClient.TournamentForceStartVote(cachedTournament.tournament_id, MatchTracker.LocalSteamId); } }; <>c.<>9__460_7 = val18; obj10 = (object)val18; } txtTForceBtn = UIFactory.CreateButton("TFS", transform8, "Force Start", 15f, c_WHITE7, bgColor4, (UnityAction)obj10, (Vector2?)new Vector2(110f, 26f)); tMyMatchPanel = UIFactory.CreatePanel("TMM", val2.transform, C_PANEL); UIFactory.AddVLG(tMyMatchPanel, 3f, 10, 10, 6, 6); UIFactory.AddLE(tMyMatchPanel, -1f, -1f, -1f, -1f, -1f, 0f); txtTMyMatch = UIFactory.CreateText("TMMTxt", tMyMatchPanel.transform, "", 17f, C_WHITE, 513, (Vector2?)new Vector2(400f, 26f), richText: true, raycastTarget: false); UIFactory.SetBold(txtTMyMatch, b: true); UIFactory.SetWordWrap(txtTMyMatch, on: true); txtTRoomCode = UIFactory.CreateText("TRC", tMyMatchPanel.transform, "", 14f, new Color(0.7f, 0.9f, 1f), 513, (Vector2?)new Vector2(400f, 22f), richText: true, raycastTarget: false); GameObject val19 = new GameObject("TMBR"); val19.transform.SetParent(tMyMatchPanel.transform, false); val19.AddComponent(); UIFactory.AddHLG(val19, 6f); UIFactory.AddLE(val19, -1f, -1f, -1f, 28f, -1f, 0f); Transform transform9 = val19.transform; Color c_WHITE8 = C_WHITE; Color bgColor5 = new Color(0.22f, 0.5f, 0.3f, 0.95f); object obj11 = <>c.<>9__460_8; if (obj11 == null) { UnityAction val20 = delegate { ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && !string.IsNullOrEmpty(cachedTournament.tournament_id)) { ApiClient.TournamentReady(cachedTournament.tournament_id, MatchTracker.LocalSteamId); } }; <>c.<>9__460_8 = val20; obj11 = (object)val20; } txtTReadyBtn = UIFactory.CreateButton("TRdy", transform9, "Ready Up (heartbeat)", 15f, c_WHITE8, bgColor5, (UnityAction)obj11, (Vector2?)new Vector2(200f, 26f)); Transform transform10 = val19.transform; Color c_WHITE9 = C_WHITE; Color bgColor6 = new Color(0.22f, 0.38f, 0.65f, 0.95f); object obj12 = <>c.<>9__460_9; if (obj12 == null) { UnityAction val21 = delegate { //IL_0129: Unknown result type (might be due to invalid IL or missing references) ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament != null && cachedTournament.matches != null) { ApiClient.TournamentMatchRow[] matches = cachedTournament.matches; foreach (ApiClient.TournamentMatchRow tournamentMatchRow in matches) { if ((tournamentMatchRow.status == "ready" || tournamentMatchRow.status == "active") && (tournamentMatchRow.p1_signup_id == cachedTournament.my_signup_id || tournamentMatchRow.p2_signup_id == cachedTournament.my_signup_id) && !string.IsNullOrEmpty(tournamentMatchRow.match_id)) { string text = ((!string.IsNullOrEmpty(tournamentMatchRow.photon_room_name)) ? tournamentMatchRow.photon_room_name : ("sct-" + tournamentMatchRow.match_id.Replace("-", "").Substring(0, 12))); _tournamentDispatchedMatches.Remove(tournamentMatchRow.match_id); Plugin.SetPendingRoom(text, cachedTournament.photon_region); CompetitiveUI.ShowNotification("Reconnecting to " + text + " (region " + (cachedTournament.photon_region ?? "default") + ")", new Color(0.5f, 0.8f, 1f)); break; } } } }; <>c.<>9__460_9 = val21; obj12 = (object)val21; } txtTReconnectBtn = UIFactory.CreateButton("TRC_btn", transform10, "Reconnect to Match", 14f, c_WHITE9, bgColor6, (UnityAction)obj12, (Vector2?)new Vector2(170f, 26f)); tMyMatchPanel.SetActive(false); GameObject val22 = new GameObject("TRight"); val22.transform.SetParent(val.transform, false); val22.AddComponent(); UIFactory.AddVLG(val22, 4f); UIFactory.AddLE(val22, -1f, -1f, -1f, -1f, 1f, 1f); GameObject val23 = UIFactory.CreatePanel("TSignBox", val22.transform, C_PANEL); UIFactory.AddVLG(val23, 2f, 8, 8, 6, 6); UIFactory.AddLE(val23, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("TSH", val23.transform, "Signups", 18f, C_GOLD, 513, (Vector2?)new Vector2(280f, 24f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("TSSV", val23.transform, 1f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); tSignupList = scrollViewRefs.content; for (int num2 = 0; num2 < 24; num2++) { GameObject val24 = new GameObject($"TSig{num2}"); val24.transform.SetParent(tSignupList.transform, false); val24.AddComponent(); UIFactory.AddHLG(val24, 6f); UIFactory.AddLE(val24, -1f, -1f, -1f, 22f, -1f, 0f); object obj13 = UIFactory.CreateText("sd", val24.transform, "", 14f, C_GOLD, 514, (Vector2?)new Vector2(40f, 22f), richText: true, raycastTarget: false); object obj14 = UIFactory.CreateText("nm", val24.transform, "", 15f, C_WHITE, 513, (Vector2?)new Vector2(280f, 22f), richText: true, raycastTarget: false); object obj15 = UIFactory.CreateText("st", val24.transform, "", 13f, C_DIM, 516, (Vector2?)new Vector2(140f, 22f), richText: true, raycastTarget: false); tSignupRowPool.Add(val24); tSignupRowTexts.Add(new object[3] { obj13, obj14, obj15 }); val24.SetActive(false); } tTournBetsBox = UIFactory.CreatePanel("TBetsBox", val22.transform, C_PANEL); UIFactory.AddVLG(tTournBetsBox, 2f, 8, 8, 6, 6); UIFactory.AddLE(tTournBetsBox, -1f, -1f, -1f, -1f, -1f, 0f); tTournBetsHeader = UIFactory.CreateText("TBH_Bets", tTournBetsBox.transform, "Upcoming Match Bets", 17f, C_WHITE, 513, (Vector2?)new Vector2(360f, 24f), richText: true, raycastTarget: false); tTournBetsContainer = new GameObject("TBetsRows"); tTournBetsContainer.transform.SetParent(tTournBetsBox.transform, false); tTournBetsContainer.AddComponent(); UIFactory.AddVLG(tTournBetsContainer); tTournBetsBox.SetActive(false); GameObject val25 = UIFactory.CreatePanel("TBrkBox", val22.transform, C_PANEL); UIFactory.AddVLG(val25, 2f, 8, 8, 6, 6); UIFactory.AddLE(val25, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.CreateText("TBH", val25.transform, "Bracket", 18f, C_GOLD, 513, (Vector2?)new Vector2(280f, 24f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("TBSV", val25.transform, 1f); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); tBracketList = scrollViewRefs2.content; for (int num3 = 0; num3 < 50; num3++) { int idx2 = num3; GameObject val26 = new GameObject($"TBR{num3}"); val26.transform.SetParent(tBracketList.transform, false); val26.AddComponent(); UIFactory.AddHLG(val26, 6f); UIFactory.AddLE(val26, -1f, -1f, -1f, 22f, -1f, 0f); object item3 = UIFactory.CreateText("txt", val26.transform, "", 14f, C_WHITE, 513, (Vector2?)new Vector2(500f, 22f), richText: true, raycastTarget: true); val26.AddComponent().onClick = delegate { if (ClickGuard.Claim() && idx2 < _tBracketRowPurposes.Count) { BracketRowPurpose bracketRowPurpose = _tBracketRowPurposes[idx2]; if (bracketRowPurpose.isHeader && !string.IsNullOrEmpty(bracketRowPurpose.groupKey)) { _tBracketExpanded.TryGetValue(bracketRowPurpose.groupKey, out var value); _tBracketExpanded[bracketRowPurpose.groupKey] = !value; dirty = true; } } }; if (UIFactory.tImage != null) { Component obj16 = val26.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj16, (object)new Color(1f, 1f, 1f, 0.01f)); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj16, true); } tBracketRowPool.Add(val26); tBracketRowTexts.Add(item3); val26.SetActive(false); } tBracketVisual = new GameObject("TBV"); tBracketVisual.transform.SetParent(tBracketList.transform, false); RectTransform obj17 = tBracketVisual.AddComponent(); obj17.anchorMin = new Vector2(0f, 1f); obj17.anchorMax = new Vector2(0f, 1f); obj17.pivot = new Vector2(0f, 1f); obj17.sizeDelta = new Vector2(900f, 600f); UIFactory.AddLE(tBracketVisual, 900f, 600f, 900f, 600f, 0f, 0f); tBracketVisual.SetActive(false); txtTMyHistory = UIFactory.CreateText("TMH", val22.transform, "", 14f, new Color(1f, 0.87f, 0.52f), 513, (Vector2?)new Vector2(600f, 22f), richText: true, raycastTarget: false); GameObject val27 = UIFactory.CreatePanel("TRH", val22.transform, C_PANEL); UIFactory.AddVLG(val27, 2f, 8, 8, 6, 6); UIFactory.AddLE(val27, -1f, -1f, -1f, 150f, -1f, 0f); UIFactory.CreateText("TRH_h", val27.transform, "Recent Tournaments", 16f, C_SUB, 513, (Vector2?)new Vector2(260f, 22f), richText: true, raycastTarget: false); UIFactory.ScrollViewRefs scrollViewRefs3 = UIFactory.CreateScrollView("TRHSV", val27.transform, 1f); UIFactory.AddLE(scrollViewRefs3.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); tHistoryList = scrollViewRefs3.content; for (int num4 = 0; num4 < 12; num4++) { GameObject val28 = new GameObject($"TH{num4}"); val28.transform.SetParent(tHistoryList.transform, false); val28.AddComponent(); UIFactory.AddHLG(val28); UIFactory.AddLE(val28, -1f, -1f, -1f, 20f, -1f, 0f); object item4 = UIFactory.CreateText("txt", val28.transform, "", 13f, C_LABEL, 513, (Vector2?)new Vector2(520f, 20f), richText: true, raycastTarget: false); tHistoryRowPool.Add(val28); tHistoryRowTexts.Add(item4); val28.SetActive(false); } return val; } private static TimeZoneInfo _ResolveTz() { string text = Plugin.TournamentTimezone?.Value ?? "Local"; if (text == "Local") { return TimeZoneInfo.Local; } (string, string)[] tzPresets = _tzPresets; for (int i = 0; i < tzPresets.Length; i++) { (string, string) tuple = tzPresets[i]; if (string.Equals(tuple.Item1, text, StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrEmpty(tuple.Item2)) { return TimeZoneInfo.Local; } try { return TimeZoneInfo.FindSystemTimeZoneById(tuple.Item2); } catch { return TimeZoneInfo.Local; } } } try { return TimeZoneInfo.FindSystemTimeZoneById(text); } catch { return TimeZoneInfo.Local; } } private static string _TzLabel() { string text = Plugin.TournamentTimezone?.Value ?? "Local"; (string, string)[] tzPresets = _tzPresets; for (int i = 0; i < tzPresets.Length; i++) { (string, string) tuple = tzPresets[i]; if (string.Equals(tuple.Item1, text, StringComparison.OrdinalIgnoreCase)) { return tuple.Item1; } } return text; } private static void _CycleTz() { string b = Plugin.TournamentTimezone?.Value ?? "Local"; int num = 0; for (int i = 0; i < _tzPresets.Length; i++) { if (string.Equals(_tzPresets[i].Label, b, StringComparison.OrdinalIgnoreCase)) { num = i; break; } } num = (num + 1) % _tzPresets.Length; Plugin.TournamentTimezone.Value = _tzPresets[num].Label; dirty = true; } private static string _DateFormat() { string text = Plugin.TournamentDateFormat?.Value ?? "ISO"; if (text != "ISO" && text != "US" && text != "EU") { text = "ISO"; } return text; } private static void _CycleDateFormat() { string value = _DateFormat(); int num = Array.IndexOf(_dateFormats, value); if (num < 0) { num = 0; } num = (num + 1) % _dateFormats.Length; Plugin.TournamentDateFormat.Value = _dateFormats[num]; dirty = true; } private static string _FmtSlot(string iso) { if (string.IsNullOrEmpty(iso)) { return "(TBD)"; } try { DateTime dateTime = DateTime.Parse(iso, _INV, DateTimeStyles.RoundtripKind).ToUniversalTime(); TimeZoneInfo destinationTimeZone = _ResolveTz(); DateTime dateTime2 = TimeZoneInfo.ConvertTimeFromUtc(dateTime, destinationTimeZone); return _DateFormat() switch { "ISO" => dateTime2.ToString("yyyy-MM-dd HH:mm", _INV), "US" => dateTime2.ToString("ddd MM/dd h:mm tt", _INV), "EU" => dateTime2.ToString("ddd dd/MM HH:mm", _INV), _ => dateTime2.ToString("yyyy-MM-dd HH:mm", _INV), } + " " + _TzLabel(); } catch { return iso; } } private static void RenderVisualBracket(ApiClient.TournamentSnapshot t, bool blankNames, int blankSize, bool isAsync) { //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Unknown result type (might be due to invalid IL or missing references) //IL_0598: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tBracketVisual == (Object)null) { return; } for (int num = tBracketVisual.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)tBracketVisual.transform.GetChild(num)).gameObject); } ApiClient.TournamentMatchRow[] array = t.matches; if (array == null || array.Length == 0) { if (blankSize < 4) { return; } array = SynthesizeBlankBracket(blankSize); } Dictionary>> dictionary = new Dictionary>>(); int num2 = 0; int num3 = 0; ApiClient.TournamentMatchRow[] array2 = array; foreach (ApiClient.TournamentMatchRow tournamentMatchRow in array2) { if (!dictionary.TryGetValue(tournamentMatchRow.bracket_side, out var value)) { value = new Dictionary>(); dictionary[tournamentMatchRow.bracket_side] = value; } if (!value.TryGetValue(tournamentMatchRow.round, out var value2)) { value2 = new List(); value[tournamentMatchRow.round] = value2; } value2.Add(tournamentMatchRow); if (tournamentMatchRow.bracket_side == "W" && tournamentMatchRow.round > num2) { num2 = tournamentMatchRow.round; } if (tournamentMatchRow.bracket_side == "L" && tournamentMatchRow.round > num3) { num3 = tournamentMatchRow.round; } } Dictionary> value3; List value4; int num4 = ((dictionary.TryGetValue("W", out value3) && value3.TryGetValue(1, out value4)) ? value4.Count : 0); Dictionary> value5; List value6; int num5 = ((dictionary.TryGetValue("L", out value5) && value5.TryGetValue(1, out value6)) ? value6.Count : 0); int num6 = Math.Max(num4 * 56, 56); Math.Max(num5 * 56, 56); Dictionary dictionary2 = new Dictionary(); int num7 = 0; int num8 = 0; if (value3 != null) { foreach (KeyValuePair> item in value3) { int key = item.Key; foreach (ApiClient.TournamentMatchRow item2 in item.Value) { int slot_idx = item2.slot_idx; int num9 = 12 + (key - 1) * 194; float num10 = 56 * (1 << key - 1); float num11 = 12f + (float)slot_idx * num10 + (num10 - 56f) / 2f; dictionary2[item2.match_id] = new Vector2((float)num9, num11); if (num9 + 170 > num7) { num7 = num9 + 170; } if (num11 + 48f > (float)num8) { num8 = (int)(num11 + 48f); } } } } int num12 = 12 + num6 + 30; if (value5 != null) { foreach (KeyValuePair> item3 in value5) { int key2 = item3.Key; foreach (ApiClient.TournamentMatchRow item4 in item3.Value) { int slot_idx2 = item4.slot_idx; int num13 = 12 + (key2 - 1) * 194; int num14 = (key2 - 1) / 2; float num15 = 56 * (1 << num14); float num16 = ((key2 % 2 == 0) ? (num15 / 2f) : 0f); float num17 = (float)num12 + (float)slot_idx2 * num15 + num16; dictionary2[item4.match_id] = new Vector2((float)num13, num17); if (num13 + 170 > num7) { num7 = num13 + 170; } if (num17 + 48f > (float)num8) { num8 = (int)(num17 + 48f); } } } } int num18 = 12 + Math.Max(num2, num3) * 194; float num19 = 12f + (float)(num6 + 30) / 2f - 24f; int num20 = 0; string[] array3 = new string[3] { "GF", "GF_RESET", "TP" }; foreach (string key3 in array3) { if (!dictionary.TryGetValue(key3, out var value7)) { continue; } foreach (KeyValuePair> item5 in value7) { foreach (ApiClient.TournamentMatchRow item6 in item5.Value) { int num21 = num18; float num22 = num19 + (float)(num20 * 62); dictionary2[item6.match_id] = new Vector2((float)num21, num22); if (num21 + 170 > num7) { num7 = num21 + 170; } if (num22 + 48f > (float)num8) { num8 = (int)(num22 + 48f); } num20++; } } } int num23 = num7 + 12; int num24 = num8 + 12; tBracketVisual.GetComponent().sizeDelta = new Vector2((float)num23, (float)num24); GameObject go = tBracketVisual; float prefH = num24; float minH = num24; float prefW = num23; UIFactory.AddLE(go, num23, minH, prefW, prefH, 0f, 0f); array2 = array; Vector2 toTopLeftPx = default(Vector2); Vector2 fromTopLeftPx = default(Vector2); foreach (ApiClient.TournamentMatchRow tournamentMatchRow2 in array2) { if (tournamentMatchRow2.prereq_match_ids == null || !dictionary2.TryGetValue(tournamentMatchRow2.match_id, out var value8)) { continue; } ((Vector2)(ref toTopLeftPx))..ctor(value8.x, value8.y + 24f); array3 = tournamentMatchRow2.prereq_match_ids; foreach (string text in array3) { if (!string.IsNullOrEmpty(text) && dictionary2.TryGetValue(text, out var value9)) { ((Vector2)(ref fromTopLeftPx))..ctor(value9.x + 170f, value9.y + 24f); DrawBracketConnector(tBracketVisual, fromTopLeftPx, toTopLeftPx); } } } array2 = array; foreach (ApiClient.TournamentMatchRow tournamentMatchRow3 in array2) { if (dictionary2.TryGetValue(tournamentMatchRow3.match_id, out var value10)) { CreateBracketCell(tBracketVisual, tournamentMatchRow3, value10, blankNames, isAsync); } } } private static void DrawBracketConnector(GameObject host, Vector2 fromTopLeftPx, Vector2 toTopLeftPx) { //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) float num = (fromTopLeftPx.x + toTopLeftPx.x) / 2f; float num2 = 2f; Color c = default(Color); ((Color)(ref c))..ctor(1f, 0.85f, 0.3f, 0.55f); DrawLineSegment(host, fromTopLeftPx.x, fromTopLeftPx.y, num - fromTopLeftPx.x, num2, c); float y = Math.Min(fromTopLeftPx.y, toTopLeftPx.y); float h = Math.Abs(toTopLeftPx.y - fromTopLeftPx.y) + num2; DrawLineSegment(host, num - num2 / 2f, y, num2, h, c); DrawLineSegment(host, num, toTopLeftPx.y, toTopLeftPx.x - num, num2, c); } private static void DrawLineSegment(GameObject host, float x, float y, float w, float h, Color c) { //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_001c: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) GameObject val = new GameObject("Conn"); val.transform.SetParent(host.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.anchoredPosition = new Vector2(x, 0f - y); obj.sizeDelta = new Vector2(Math.Max(1f, w), Math.Max(1f, h)); Component obj2 = val.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, c); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj2, false); } private static void CreateBracketCell(GameObject host, ApiClient.TournamentMatchRow m, Vector2 topLeftPx, bool blankNames, bool isAsync) { //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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0055: Unknown result type (might be due to invalid IL or missing references) Color bgColor = (m.is_bye ? new Color(0.18f, 0.2f, 0.24f, 0.8f) : ((m.status == "completed") ? new Color(0.18f, 0.32f, 0.45f, 0.85f) : ((m.status == "active") ? new Color(0.2f, 0.42f, 0.2f, 0.9f) : ((m.status == "ready") ? new Color(0.45f, 0.38f, 0.15f, 0.9f) : new Color(0.16f, 0.17f, 0.21f, 0.85f))))); GameObject obj = UIFactory.CreatePanel("M_" + m.match_id, host.transform, bgColor); RectTransform component = obj.GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(topLeftPx.x, 0f - topLeftPx.y); component.sizeDelta = new Vector2(170f, 48f); string playerName = (blankNames ? "?" : (m.p1_display_name ?? (m.is_bye ? "BYE" : "TBD"))); string playerName2 = (blankNames ? "?" : (m.p2_display_name ?? (m.is_bye ? "BYE" : "TBD"))); string score = ""; string score2 = ""; if (m.status == "completed") { score = m.p1_series_wins.ToString(); score2 = m.p2_series_wins.ToString(); } else if (m.status == "forfeit" || m.status == "double_forfeit") { score = ((m.status == "forfeit") ? "FF" : "FF"); score2 = ((m.status == "forfeit") ? "FF" : "FF"); } int winnerSlot = 0; if (m.status == "completed") { winnerSlot = ((m.p1_series_wins > m.p2_series_wins) ? 1 : 2); } float num = 23f; CreateBracketCellRow(obj, playerName, score, 1, winnerSlot, 0f, num, 170f); CreateBracketCellRow(obj, playerName2, score2, 2, winnerSlot, num + 1f, num, 170f); } private static void CreateBracketCellRow(GameObject cell, string playerName, string score, int rowSlot, int winnerSlot, float yTop, float h, float cellW) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"R{rowSlot}"); val.transform.SetParent(cell.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.anchoredPosition = new Vector2(0f, 0f - yTop); obj.sizeDelta = new Vector2(cellW, h); bool flag = winnerSlot == rowSlot; bool flag2 = winnerSlot != 0 && winnerSlot != rowSlot; Color color = (flag ? new Color(0.95f, 1f, 0.7f) : (flag2 ? new Color(0.55f, 0.55f, 0.55f) : new Color(0.92f, 0.95f, 1f))); string text = (flag ? ("" + playerName + "") : playerName); UIFactory.CreateText("N", val.transform, text, 13f, color, 513, (Vector2?)new Vector2(cellW - 36f, h), richText: true, raycastTarget: false); Transform val2 = val.transform.Find("N"); if ((Object)(object)val2 != (Object)null) { RectTransform component = ((Component)val2).GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(8f, 0f); } if (!string.IsNullOrEmpty(score)) { Color color2 = (flag ? new Color(1f, 0.95f, 0.4f) : new Color(0.7f, 0.7f, 0.7f)); UIFactory.CreateText("S", val.transform, score, 14f, color2, 516, (Vector2?)new Vector2(28f, h), richText: true, raycastTarget: false); Transform val3 = val.transform.Find("S"); if ((Object)(object)val3 != (Object)null) { RectTransform component2 = ((Component)val3).GetComponent(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(0f, 1f); component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(cellW - 32f, 0f); } } } private static ApiClient.TournamentMatchRow[] SynthesizeBlankBracket(int n) { List list = new List(); int num = 0; int num2 = n; while (num2 > 1) { num2 >>= 1; num++; } Dictionary<(int, int), string> dictionary = new Dictionary<(int, int), string>(); for (int i = 1; i <= num; i++) { int num3 = n / (1 << i); for (int j = 0; j < num3; j++) { string text = $"BLANK_W_{i}_{j}"; dictionary[(i, j)] = text; List list2 = new List(); if (i > 1) { if (dictionary.TryGetValue((i - 1, j * 2), out var value)) { list2.Add(value); } if (dictionary.TryGetValue((i - 1, j * 2 + 1), out var value2)) { list2.Add(value2); } } list.Add(new ApiClient.TournamentMatchRow { match_id = text, bracket_side = "W", round = i, slot_idx = j, status = "pending", prereq_match_ids = list2.ToArray() }); } } list.Add(new ApiClient.TournamentMatchRow { match_id = "BLANK_GF", bracket_side = "GF", round = 1, slot_idx = 0, status = "pending", prereq_match_ids = new string[0] }); return list.ToArray(); } private static void RefreshTournamentBets() { if ((Object)(object)tTournBetsBox == (Object)null || (Object)(object)tTournBetsContainer == (Object)null) { return; } foreach (GameObject item in tTournBetRowPool) { item.SetActive(false); } List cachedActiveSeries = ApiClient.CachedActiveSeries; List list = new List(); if (cachedActiveSeries != null) { foreach (ApiClient.ActiveSeriesEntry item2 in cachedActiveSeries) { if (item2.is_tournament && item2.phase == "pre_match") { list.Add(item2); } } } if (list.Count == 0) { tTournBetsBox.SetActive(false); return; } tTournBetsBox.SetActive(true); UIFactory.SetText(tTournBetsHeader, $"Upcoming Match Bets ({list.Count})"); int num = 0; foreach (ApiClient.ActiveSeriesEntry item3 in list) { ApplyHeaderRow(GetOrCreateTournBetRow(num++), item3); ApplyBetRow(GetOrCreateTournBetRow(num++), item3, betOnP1: true); ApplyBetRow(GetOrCreateTournBetRow(num++), item3, betOnP1: false); } } private static GameObject GetOrCreateTournBetRow(int idx) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown while (tTournBetRowPool.Count <= idx) { GameObject val = new GameObject($"tbet{tTournBetRowPool.Count}"); val.transform.SetParent(tTournBetsContainer.transform, false); val.AddComponent(); UIFactory.AddHLG(val); UIFactory.AddLE(val, -1f, -1f, -1f, 26f, -1f, 0f); tTournBetRowPool.Add(val); } GameObject val2 = tTournBetRowPool[idx]; for (int num = val2.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val2.transform.GetChild(num)).gameObject); } val2.SetActive(true); return val2; } private static void RefreshTournaments() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0f5f: Unknown result type (might be due to invalid IL or missing references) //IL_0ede: Unknown result type (might be due to invalid IL or missing references) //IL_0a39: Unknown result type (might be due to invalid IL or missing references) RefreshTournamentBets(); ApiClient.TournamentSnapshot cachedTournament = ApiClient.CachedTournament; if (cachedTournament == null) { UIFactory.SetText(txtTState, "Loading..."); UIFactory.SetText(txtTWhen, ""); if ((Object)(object)txtTSignupBtn != (Object)null) { txtTSignupBtn.SetActive(false); } if ((Object)(object)txtTUnsignupBtn != (Object)null) { txtTUnsignupBtn.SetActive(false); } if ((Object)(object)tMyMatchPanel != (Object)null) { tMyMatchPanel.SetActive(false); } return; } Color c = C_GOLD; string s; switch (cachedTournament.status) { case "voting": s = "VOTING / SIGNUPS OPEN"; ((Color)(ref c))..ctor(0.4f, 1f, 0.5f); break; case "locked": s = "LOCKED - STARTING SOON"; ((Color)(ref c))..ctor(1f, 0.85f, 0.3f); break; case "running": s = "LIVE"; ((Color)(ref c))..ctor(1f, 0.4f, 0.4f); break; case "completed": s = "COMPLETED"; c = C_DIM; break; case "cancelled": s = "CANCELLED (not enough players)"; c = C_DIM; break; default: s = "No active tournament"; break; } UIFactory.SetText(txtTState, s); UIFactory.SetColor(txtTState, c); if ((Object)(object)txtTTzButton != (Object)null) { UIFactory.SetText(UIFactory.GetButtonText(txtTTzButton), _TzLabel()); } if ((Object)(object)txtTDateFmtButton != (Object)null) { UIFactory.SetText(UIFactory.GetButtonText(txtTDateFmtButton), _DateFormat()); } bool flag = ApiClient.TournamentKind == "async"; if (txtTInstructions != null) { UIFactory.SetText(txtTInstructions, flag ? "HOW IT WORKS (Async)\n 1. Sign up any time during the 7-day signup window (Discord must be linked)\n 2. On lock, bracket is built and first-round matches activate\n 3. Coordinate with your opponent via /dm-opponent on Discord\n 4. Both of you enable Ranked, join any private lobby in ROUNDS, play the BO3\n 5. Mod records the result automatically - no manual report, no room code needed\n 6. Winner advances in bracket; loser drops to LB (or is eliminated)\n\nAUTO-RECORDING REQUIREMENTS\n * Both players must have Ranked toggled ON in-game when playing\n * Any private ROUNDS lobby works - tournament doesn't force a specific room\n * Once you hit 2 BO3 wins, the mod advances the bracket and notifies you\n\nSCHEDULING\n * No fixed start time - self-paced, 7 days per match\n * Total tournament runs up to 6-9 weeks depending on how fast matches happen\n * Miss the deadline and you forfeit that match (tracked in penalty %)\n\nFORMAT\n * Double-elim BO3 - lose once, you drop to losers bracket\n * Grand Final: WB champ vs LB champ (bracket reset if LB wins first BO3)\n * All matches count toward ranked Elo\n\nPRIZES\n * Same scaled tier as sync - 1st / 2nd / 3rd get gold + XP + trophy roles\n * 3rd place = loser of LB final\n\nPENALTY %\n * Grows when you sign up but forfeit a match by missing the 7-day deadline" : "HOW IT WORKS (Sync)\n 1. Sign up (Discord must be linked)\n 2. Vote on start time if you want\n 3. Keep this tab open at start time\n 4. Mod auto-connects you to your opponent - no queue, no invites\n 5. Play BO3, bracket advances automatically\n\nREADY-UP\n * Press Ready Up within 5 min of your match starting or forfeit\n * Tab open = heartbeat keeps you ready; don't alt-tab for long\n * Bracket hidden until start (no scouting your first opponent)\n\nFORMAT\n * Double-elim BO3 (first to 2) - losing once drops you to the losers bracket\n * Matches run in parallel: you play your next match the moment your opponent is ready\n * Top seeds get byes when fewer than 16 sign up\n * Grand Final: WB champ vs LB champ (bracket reset if LB wins first BO3)\n * All matches count toward ranked Elo\n\nPRIZES (16-player full tier)\n * 1st - 500g / 2500 XP / Winner role\n * 2nd - 300g / 1500 XP / Runner Up role\n * 3rd - 60g / 75 XP / 3rd Place role (loser of LB final)\n * Scaled 60% at 12-15p, 30% at 8-11p, cancelled under 8\n\nPENALTY %\n * Grows when you sign up but no-show at match time\n * Lower penalty = priority if more than 16 sign up"); } if ((Object)(object)tSubTabSyncBtn != (Object)null) { UIFactory.SetImageColor(tSubTabSyncBtn, flag ? C_TAB : C_TABACT); UIFactory.SetColor(UIFactory.GetButtonText(tSubTabSyncBtn), flag ? C_LABEL : C_WHITE); UIFactory.SetBold(UIFactory.GetButtonText(tSubTabSyncBtn), !flag); } if ((Object)(object)tSubTabAsyncBtn != (Object)null) { UIFactory.SetImageColor(tSubTabAsyncBtn, flag ? C_TABACT : C_TAB); UIFactory.SetColor(UIFactory.GetButtonText(tSubTabAsyncBtn), flag ? C_WHITE : C_LABEL); UIFactory.SetBold(UIFactory.GetButtonText(tSubTabAsyncBtn), flag); } try { DateTime dateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, _ResolveTz()); UIFactory.SetText(s: "now: " + _DateFormat() switch { "ISO" => dateTime.ToString("yyyy-MM-dd HH:mm", _INV), "US" => dateTime.ToString("ddd MM/dd h:mm tt", _INV), "EU" => dateTime.ToString("ddd dd/MM HH:mm", _INV), _ => dateTime.ToString("yyyy-MM-dd HH:mm", _INV), } + "", t: txtTTzNow); } catch { UIFactory.SetText(txtTTzNow, ""); } string s2 = ""; if (!string.IsNullOrEmpty(cachedTournament.scheduled_start_ts)) { s2 = "Starts: " + _FmtSlot(cachedTournament.scheduled_start_ts) + ""; } else if (!string.IsNullOrEmpty(cachedTournament.default_start_ts)) { s2 = "Default start: " + _FmtSlot(cachedTournament.default_start_ts) + " Signups close: " + _FmtSlot(cachedTournament.lock_at); } UIFactory.SetText(txtTWhen, s2); bool flag2 = !string.IsNullOrEmpty(cachedTournament.my_signup_id); bool active = cachedTournament.status == "voting" && !flag2 && cachedTournament.my_discord_linked; if ((Object)(object)txtTSignupBtn != (Object)null) { txtTSignupBtn.SetActive(active); } if ((Object)(object)txtTUnsignupBtn != (Object)null) { txtTUnsignupBtn.SetActive(cachedTournament.status == "voting" && flag2); } UIFactory.SetText(txtTDiscordGate, cachedTournament.my_discord_linked ? "" : "Link Discord first (My Stats tab) to sign up."); UIFactory.SetText(txtTPenalty, $"Your no-show penalty: {cachedTournament.my_penalty_pct * 100f:0.0}%"); if ((Object)(object)tVoteBoxPanel != (Object)null) { tVoteBoxPanel.SetActive(!flag); } bool flag3 = !flag && cachedTournament.status == "voting" && flag2; string[] time_slot_options = cachedTournament.time_slot_options; int num = ((time_slot_options != null) ? time_slot_options.Length : 0); HashSet hashSet = new HashSet(cachedTournament.my_votes ?? Array.Empty()); Dictionary dictionary = new Dictionary(); if (cachedTournament.time_slot_tallies != null) { ApiClient.TimeVoteTally[] time_slot_tallies = cachedTournament.time_slot_tallies; foreach (ApiClient.TimeVoteTally timeVoteTally in time_slot_tallies) { dictionary[timeVoteTally.slot_ts] = timeVoteTally.votes; } } for (int j = 0; j < tSlotToggles.Count; j++) { if (j >= num) { ((Component)tSlotToggles[j].transform.parent).gameObject.SetActive(false); continue; } ((Component)tSlotToggles[j].transform.parent).gameObject.SetActive(flag3); string text = cachedTournament.time_slot_options[j]; bool flag4 = hashSet.Contains(text); if (j >= tSlotChecked.Count) { tSlotChecked.Add(flag4); } else if (!_tVoteLocalEdited) { tSlotChecked[j] = flag4; } UIFactory.SetText(UIFactory.GetButtonText(tSlotToggles[j]), tSlotChecked[j] ? "[X]" : "[ ]"); dictionary.TryGetValue(text, out var value); string text2 = ((hashSet.Count > 0) ? string.Format(" ({0} {1})", value, (value == 1) ? "vote" : "votes") : ""); UIFactory.SetText(tSlotLabels[j], _FmtSlot(text) + text2); } int num2 = 0; if (cachedTournament.signups != null) { ApiClient.TournamentSignupRow[] signups = cachedTournament.signups; for (int i = 0; i < signups.Length; i++) { if (!signups[i].is_speculative) { num2++; } } } bool flag5 = !flag && flag3 && num2 >= cachedTournament.min_players; UIFactory.SetText(txtTForceCount, (!(cachedTournament.status == "voting")) ? "" : (flag5 ? $"Force-start votes: {cachedTournament.force_vote_count}/{num2}" : $"Force-start unlocks at {cachedTournament.min_players} signups ({num2}/{cachedTournament.min_players})")); if ((Object)(object)txtTForceBtn != (Object)null) { txtTForceBtn.SetActive(flag5); } bool active2 = false; string s3 = ""; string text3 = ""; if (cachedTournament.status == "running" && flag2 && cachedTournament.matches != null) { ApiClient.TournamentMatchRow[] matches = cachedTournament.matches; foreach (ApiClient.TournamentMatchRow tournamentMatchRow in matches) { if ((tournamentMatchRow.status != "ready" && tournamentMatchRow.status != "active") || (tournamentMatchRow.p1_signup_id != cachedTournament.my_signup_id && tournamentMatchRow.p2_signup_id != cachedTournament.my_signup_id)) { continue; } if (!string.IsNullOrEmpty(tournamentMatchRow.match_id)) { text3 = ((!string.IsNullOrEmpty(tournamentMatchRow.photon_room_name)) ? tournamentMatchRow.photon_room_name : ("sct-" + tournamentMatchRow.match_id.Replace("-", "").Substring(0, 12))); } string text4 = ((tournamentMatchRow.p1_signup_id == cachedTournament.my_signup_id) ? tournamentMatchRow.p2_display_name : tournamentMatchRow.p1_display_name); string text5 = ((tournamentMatchRow.p1_signup_id == cachedTournament.my_signup_id) ? tournamentMatchRow.p2_signup_id : tournamentMatchRow.p1_signup_id); bool flag6 = false; if (cachedTournament.signups != null) { ApiClient.TournamentSignupRow[] signups = cachedTournament.signups; foreach (ApiClient.TournamentSignupRow tournamentSignupRow in signups) { if (tournamentSignupRow.signup_id == text5) { flag6 = tournamentSignupRow.ready; break; } } } string text6 = ((!cachedTournament.my_ready) ? "press Ready Up" : (flag6 ? "both ready - connecting..." : "waiting on opponent to ready")); s3 = string.Format("Your match (R{0}{1}): vs {2} - {3}", tournamentMatchRow.round, (tournamentMatchRow.bracket_side == "TP") ? " 3rd Place" : "", text4 ?? "?", text6); active2 = true; if (!flag && cachedTournament.my_ready && flag6 && !string.IsNullOrEmpty(tournamentMatchRow.match_id)) { string text7 = ((!string.IsNullOrEmpty(tournamentMatchRow.photon_room_name)) ? tournamentMatchRow.photon_room_name : ("sct-" + tournamentMatchRow.match_id.Replace("-", "").Substring(0, 12))); if (!_tournamentDispatchedMatches.Contains(tournamentMatchRow.match_id) && Plugin.PendingRankedRoom != text7) { _tournamentDispatchedMatches.Add(tournamentMatchRow.match_id); Plugin.SetPendingRoom(text7, cachedTournament.photon_region); Plugin.Log.LogInfo((object)("[TOURNAMENT] Auto-connecting to " + text7 + " in region '" + (cachedTournament.photon_region ?? "(client default)") + "' for match " + tournamentMatchRow.match_id)); CompetitiveUI.ShowNotification("Tournament match starting vs " + text4, new Color(0.5f, 1f, 0.5f)); } } break; } } UIFactory.SetText(txtTMyMatch, s3); string text8 = (string.IsNullOrEmpty(cachedTournament.photon_region) ? "" : (" [" + cachedTournament.photon_region.ToUpper() + "]")); UIFactory.SetText(txtTRoomCode, string.IsNullOrEmpty(text3) ? "" : ("Room code: " + text3 + "" + text8 + " (if auto-connect fails, Reconnect or join via Private Lobby)")); if ((Object)(object)txtTReconnectBtn != (Object)null) { txtTReconnectBtn.SetActive(active2); } if ((Object)(object)tMyMatchPanel != (Object)null) { tMyMatchPanel.SetActive(active2); } bool flag7 = cachedTournament.status == "running" || cachedTournament.status == "completed"; int num3 = 0; int num4 = 0; if (cachedTournament.signups != null) { for (int l = 0; l < cachedTournament.signups.Length; l++) { if (num3 >= tSignupRowPool.Count) { break; } ApiClient.TournamentSignupRow tournamentSignupRow2 = cachedTournament.signups[l]; GameObject obj2 = tSignupRowPool[num3]; object[] array = tSignupRowTexts[num3]; string s4 = ((flag7 && tournamentSignupRow2.seed > 0) ? $"#{tournamentSignupRow2.seed}" : $"{l + 1}."); string text9 = tournamentSignupRow2.display_name ?? ""; if (tournamentSignupRow2.is_speculative) { text9 = "~ " + text9; } string s5 = ((tournamentSignupRow2.placed_rank == 1) ? "1st" : ((tournamentSignupRow2.placed_rank == 2) ? "2nd" : ((tournamentSignupRow2.placed_rank == 3) ? "3rd" : ((!string.IsNullOrEmpty(tournamentSignupRow2.progress_label)) ? (tournamentSignupRow2.progress_label.StartsWith("eliminated") ? ("" + tournamentSignupRow2.progress_label + "") : ((!(tournamentSignupRow2.progress_label == "CHAMPION")) ? ("" + tournamentSignupRow2.progress_label + "") : "CHAMPION")) : (tournamentSignupRow2.forfeited ? "FORFEIT" : ((!tournamentSignupRow2.ready) ? $"{tournamentSignupRow2.penalty_at_signup * 100f:0}% pen" : "ready")))))); UIFactory.SetText(array[0], s4); UIFactory.SetText(array[1], text9); UIFactory.SetText(array[2], s5); obj2.SetActive(true); num3++; if (!tournamentSignupRow2.is_speculative) { num4++; } } } for (int m = num3; m < tSignupRowPool.Count; m++) { tSignupRowPool[m].SetActive(false); } int num5 = 0; bool flag8 = !flag && cachedTournament.status != "running" && cachedTournament.status != "completed"; bool flag9 = cachedTournament.matches != null && cachedTournament.matches.Length != 0; bool blankNames = flag8 && flag9; int num6 = 0; if (!flag9 && (cachedTournament.status == "voting" || cachedTournament.status == "locked")) { int num7 = 0; if (cachedTournament.signups != null) { ApiClient.TournamentSignupRow[] signups = cachedTournament.signups; for (int i = 0; i < signups.Length; i++) { if (!signups[i].is_speculative) { num7++; } } } int num8 = Math.Max(num7, 4); for (num6 = 1; num6 < num8; num6 *= 2) { } if (num6 > 16) { num6 = 16; } } if (flag9 || num6 > 0) { for (int n = 0; n < tBracketRowPool.Count; n++) { tBracketRowPool[n].SetActive(false); } if ((Object)(object)tBracketVisual != (Object)null) { tBracketVisual.SetActive(true); RenderVisualBracket(cachedTournament, blankNames, num6, flag); } _tBracketRowPurposes.Clear(); num5 = tBracketRowPool.Count; } else if (flag8 && !flag9) { if ((Object)(object)tBracketVisual != (Object)null) { tBracketVisual.SetActive(false); } if (num5 < tBracketRowPool.Count) { UIFactory.SetColor(tBracketRowTexts[num5], C_DIM); UIFactory.SetText(tBracketRowTexts[num5], "Bracket revealed when the tournament starts (" + _FmtSlot(cachedTournament.scheduled_start_ts) + ")."); tBracketRowPool[num5].SetActive(true); num5++; } } else { if ((Object)(object)tBracketVisual != (Object)null) { tBracketVisual.SetActive(false); } if (num5 < tBracketRowPool.Count) { UIFactory.SetColor(tBracketRowTexts[num5], C_DIM); UIFactory.SetText(tBracketRowTexts[num5], "Bracket appears once signups have rolled in."); tBracketRowPool[num5].SetActive(true); num5++; } } for (int num9 = num5; num9 < tBracketRowPool.Count; num9++) { tBracketRowPool[num9].SetActive(false); } string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown" && ApiClient.CachedPlayerTournaments.TryGetValue(localSteamId, out var value2) && value2 != null && value2.participant_count > 0) { UIFactory.SetText(txtTMyHistory, $"Your placements: 1stx{value2.winner_count} 2ndx{value2.runner_up_count} 3rdx{value2.third_place_count} (played {value2.participant_count})"); } else { UIFactory.SetText(txtTMyHistory, "Your placements: no completed tournaments yet"); } ApiClient.PlayerTournamentEntry[] cachedSiteTournamentHistory = ApiClient.CachedSiteTournamentHistory; int num10 = 0; if (cachedSiteTournamentHistory != null) { for (int num11 = 0; num11 < cachedSiteTournamentHistory.Length; num11++) { if (num10 >= tHistoryRowPool.Count) { break; } ApiClient.PlayerTournamentEntry playerTournamentEntry = cachedSiteTournamentHistory[num11]; string text10 = playerTournamentEntry.ended_at; try { if (!string.IsNullOrEmpty(text10)) { text10 = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(playerTournamentEntry.ended_at, _INV, DateTimeStyles.RoundtripKind).ToUniversalTime(), _ResolveTz()).ToString((_DateFormat() == "EU") ? "dd/MM/yy" : "MM/dd/yy", _INV); } } catch { } string arg = (string.IsNullOrEmpty(playerTournamentEntry.winner_display_name) ? "-" : playerTournamentEntry.winner_display_name); UIFactory.SetText(tHistoryRowTexts[num10], $"{text10} Winner: {arg} ({playerTournamentEntry.signup_count}p)"); tHistoryRowPool[num10].SetActive(true); num10++; } } for (int num12 = num10; num12 < tHistoryRowPool.Count; num12++) { tHistoryRowPool[num12].SetActive(false); } } private static GameObject BuildTeamTab(Transform parent) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00d6: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Expected O, but got Unknown //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Expected O, but got Unknown //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Expected O, but got Unknown //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Expected O, but got Unknown //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Expected O, but got Unknown //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Expected O, but got Unknown //IL_05d3: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0632: Unknown result type (might be due to invalid IL or missing references) //IL_0697: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Unknown result type (might be due to invalid IL or missing references) //IL_06d7: Unknown result type (might be due to invalid IL or missing references) //IL_06eb: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05c9: Expected O, but got Unknown //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Expected O, but got Unknown //IL_07bd: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_0862: Unknown result type (might be due to invalid IL or missing references) //IL_0876: Unknown result type (might be due to invalid IL or missing references) //IL_08e3: Unknown result type (might be due to invalid IL or missing references) //IL_0948: Unknown result type (might be due to invalid IL or missing references) //IL_095c: Unknown result type (might be due to invalid IL or missing references) //IL_0988: Unknown result type (might be due to invalid IL or missing references) //IL_099c: Unknown result type (might be due to invalid IL or missing references) //IL_0a27: Unknown result type (might be due to invalid IL or missing references) //IL_0a3b: Unknown result type (might be due to invalid IL or missing references) //IL_0a57: Unknown result type (might be due to invalid IL or missing references) //IL_0a5e: Expected O, but got Unknown //IL_0ab5: Unknown result type (might be due to invalid IL or missing references) //IL_0abc: Expected O, but got Unknown //IL_0b25: Unknown result type (might be due to invalid IL or missing references) //IL_0b39: Unknown result type (might be due to invalid IL or missing references) //IL_0b54: Unknown result type (might be due to invalid IL or missing references) //IL_0b5b: Expected O, but got Unknown //IL_0d22: Unknown result type (might be due to invalid IL or missing references) //IL_0d3b: Unknown result type (might be due to invalid IL or missing references) //IL_0d48: Unknown result type (might be due to invalid IL or missing references) //IL_0d5b: Unknown result type (might be due to invalid IL or missing references) //IL_0d6a: Expected O, but got Unknown //IL_0ca8: Unknown result type (might be due to invalid IL or missing references) //IL_0e22: Unknown result type (might be due to invalid IL or missing references) //IL_0e29: Expected O, but got Unknown //IL_0e81: Unknown result type (might be due to invalid IL or missing references) //IL_0e88: Expected O, but got Unknown //IL_0ef1: Unknown result type (might be due to invalid IL or missing references) //IL_0f05: Unknown result type (might be due to invalid IL or missing references) //IL_0f20: Unknown result type (might be due to invalid IL or missing references) //IL_0f25: Unknown result type (might be due to invalid IL or missing references) //IL_0f38: Unknown result type (might be due to invalid IL or missing references) //IL_0f62: Expected O, but got Unknown //IL_0f78: Unknown result type (might be due to invalid IL or missing references) //IL_0f91: Unknown result type (might be due to invalid IL or missing references) //IL_0ccb: Unknown result type (might be due to invalid IL or missing references) //IL_0fbf: Unknown result type (might be due to invalid IL or missing references) //IL_0fe9: Unknown result type (might be due to invalid IL or missing references) //IL_0ffd: Unknown result type (might be due to invalid IL or missing references) //IL_1029: Unknown result type (might be due to invalid IL or missing references) //IL_1042: Unknown result type (might be due to invalid IL or missing references) //IL_0faa: Unknown result type (might be due to invalid IL or missing references) //IL_0faf: Unknown result type (might be due to invalid IL or missing references) //IL_0fb5: Expected O, but got Unknown //IL_1070: Unknown result type (might be due to invalid IL or missing references) //IL_105b: Unknown result type (might be due to invalid IL or missing references) //IL_1060: Unknown result type (might be due to invalid IL or missing references) //IL_1066: Expected O, but got Unknown GameObject val = new GameObject("Team2v2Outer"); val.transform.SetParent(parent, false); val.AddComponent(); UIFactory.AddVLG(val, 0f); UIFactory.AddLE(val, -1f, -1f, -1f, -1f, -1f, 1f); UIFactory.ScrollViewRefs scrollViewRefs = UIFactory.CreateScrollView("Team2v2Scroll", val.transform, 6f); UIFactory.AddLE(scrollViewRefs.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); GameObject content = scrollViewRefs.content; GameObject val2 = new GameObject("Team2v2Inner"); val2.transform.SetParent(content.transform, false); val2.AddComponent(); UIFactory.AddVLG(val2, 6f, 10, 10, 8, 8); content = val2; txtTeamHeader = UIFactory.CreateText("THdr", content.transform, "2v2 Ranked (separate Glicko, FF on, BO3 series)", 20f, C_GOLD, 513, (Vector2?)new Vector2(900f, 28f), richText: true, raycastTarget: false); GameObject val3 = UIFactory.CreatePanel("TStat", content.transform, C_PANEL); UIFactory.AddVLG(val3, 6f, 12, 12, 8, 8); UIFactory.AddLE(val3, -1f, -1f, -1f, -1f, -1f, 0f); txtTeamStatus = UIFactory.CreateText("TS", val3.transform, "Click Search to start finding a 2v2.", 17f, C_WHITE, 513, (Vector2?)new Vector2(900f, 24f), richText: true, raycastTarget: false); txtTeamMembers = UIFactory.CreateText("TM", val3.transform, "", 15f, C_LABEL, 257, (Vector2?)new Vector2(900f, 60f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(txtTeamMembers, on: true); txtTeamDcGrace = UIFactory.CreateText("TDC", val3.transform, "", 16f, new Color(1f, 0.7f, 0.3f), 513, (Vector2?)new Vector2(900f, 26f), richText: true, raycastTarget: false); UIFactory.SetBold(txtTeamDcGrace, b: true); object obj = txtTeamDcGrace; object obj2 = ((obj is Component) ? obj : null); if (obj2 != null) { GameObject gameObject = ((Component)obj2).gameObject; if (gameObject != null) { gameObject.SetActive(false); } } GameObject val4 = new GameObject("TBR"); val4.transform.SetParent(val3.transform, false); val4.AddComponent(); UIFactory.AddHLG(val4, 8f); UIFactory.AddLE(val4, -1f, 32f, -1f, 32f, -1f, 0f); Transform transform = val4.transform; Color c_WHITE = C_WHITE; Color bgColor = new Color(0.2f, 0.55f, 0.3f, 0.95f); object obj3 = <>c.<>9__494_0; if (obj3 == null) { UnityAction val5 = delegate { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"[TEAM-QUEUE-UI] Search Random clicked"); string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { Plugin.Log.LogWarning((object)("[TEAM-QUEUE-UI] LocalSteamId='" + localSteamId + "' — Steam not ready yet, ignoring click")); CompetitiveUI.ShowNotification("Steam ID not ready yet — try again in a few seconds", new Color(1f, 0.6f, 0.2f), 4f); } else { string text = ""; try { text = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { } Plugin.Log.LogInfo((object)("[TEAM-QUEUE-UI] joining auto team queue sid=" + localSteamId + " region='" + text + "'")); ApiClient.JoinTeamQueue(localSteamId, MatchTracker.LocalDisplayName, text); } }; <>c.<>9__494_0 = val5; obj3 = (object)val5; } teamSearchBtn = UIFactory.CreateButton("TSB", transform, "Search Random", 16f, c_WHITE, bgColor, (UnityAction)obj3, (Vector2?)new Vector2(160f, 28f)); Transform transform2 = val4.transform; Color c_WHITE2 = C_WHITE; Color bgColor2 = new Color(0.4f, 0.3f, 0.55f, 0.95f); object obj4 = <>c.<>9__494_1; if (obj4 == null) { UnityAction val6 = delegate { //IL_003e: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)"[TEAM-QUEUE-UI] Find Custom Lobby clicked"); string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || localSteamId == "unknown") { CompetitiveUI.ShowNotification("Steam ID not ready yet — try again in a few seconds", new Color(1f, 0.6f, 0.2f), 4f); } else { string text = ""; try { text = PhotonNetwork.CloudRegion?.Replace("/*", "") ?? ""; } catch { } Plugin.Log.LogInfo((object)("[TEAM-QUEUE-UI] joining manual team queue sid=" + localSteamId + " region='" + text + "'")); ApiClient.JoinTeamQueue(localSteamId, MatchTracker.LocalDisplayName, text, "manual"); } }; <>c.<>9__494_1 = val6; obj4 = (object)val6; } teamSearchCustomBtn = UIFactory.CreateButton("TSC", transform2, "Find Custom Lobby", 16f, c_WHITE2, bgColor2, (UnityAction)obj4, (Vector2?)new Vector2(180f, 28f)); Transform transform3 = val4.transform; Color c_WHITE3 = C_WHITE; Color bgColor3 = new Color(0.55f, 0.2f, 0.2f, 0.95f); object obj5 = <>c.<>9__494_2; if (obj5 == null) { UnityAction val7 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.LeaveTeamQueue(localSteamId); } }; <>c.<>9__494_2 = val7; obj5 = (object)val7; } teamLeaveBtn = UIFactory.CreateButton("TLB", transform3, "Leave Queue", 16f, c_WHITE3, bgColor3, (UnityAction)obj5, (Vector2?)new Vector2(160f, 28f)); teamLeaveBtn.SetActive(false); Transform transform4 = val4.transform; Color c_WHITE4 = C_WHITE; Color bgColor4 = new Color(0.2f, 0.55f, 0.3f, 0.95f); object obj6 = <>c.<>9__494_3; if (obj6 == null) { UnityAction val8 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.ReadyUpTeam(localSteamId); } }; <>c.<>9__494_3 = val8; obj6 = (object)val8; } teamReadyBtn = UIFactory.CreateButton("TRB", transform4, "Ready Up", 16f, c_WHITE4, bgColor4, (UnityAction)obj6, (Vector2?)new Vector2(160f, 28f)); teamReadyBtn.SetActive(false); GameObject val9 = new GameObject("TPR"); val9.transform.SetParent(val3.transform, false); val9.AddComponent(); UIFactory.AddHLG(val9, 8f); UIFactory.AddLE(val9, -1f, 30f, -1f, 30f, -1f, 0f); Transform transform5 = val9.transform; Color c_WHITE5 = C_WHITE; Color bgColor5 = new Color(0.55f, 0.3f, 0.1f, 0.5f); object obj7 = <>c.<>9__494_4; if (obj7 == null) { UnityAction val10 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.SetTeamPreferredTeam(localSteamId, 1); } }; <>c.<>9__494_4 = val10; obj7 = (object)val10; } teamPickT1Btn = UIFactory.CreateButton("TPT1", transform5, "Team 1 (Orange)", 14f, c_WHITE5, bgColor5, (UnityAction)obj7, (Vector2?)new Vector2(140f, 26f)); Transform transform6 = val9.transform; Color c_WHITE6 = C_WHITE; Color bgColor6 = new Color(0.1f, 0.3f, 0.55f, 0.5f); object obj8 = <>c.<>9__494_5; if (obj8 == null) { UnityAction val11 = delegate { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId)) { ApiClient.SetTeamPreferredTeam(localSteamId, 2); } }; <>c.<>9__494_5 = val11; obj8 = (object)val11; } teamPickT2Btn = UIFactory.CreateButton("TPT2", transform6, "Team 2 (Blue)", 14f, c_WHITE6, bgColor6, (UnityAction)obj8, (Vector2?)new Vector2(140f, 26f)); txtPickStatus = UIFactory.CreateText("TPS", val9.transform, "Custom lobby — claim Team 1 or Team 2.", 13f, C_LABEL, 513, (Vector2?)new Vector2(440f, 26f), richText: true, raycastTarget: false); GameObject val12 = UIFactory.CreatePanel("TLT", content.transform, C_PANEL); UIFactory.AddVLG(val12, 2f, 12, 12, 6, 6); UIFactory.AddLE(val12, -1f, -1f, -1f, -1f, -1f, 0f); txtTeamLiveHeader = UIFactory.CreateText("TLTH", val12.transform, "* Live 2v2 Now", 16f, C_SUB, 513, (Vector2?)new Vector2(900f, 22f), richText: true, raycastTarget: false); txtTeamLiveBody = UIFactory.CreateText("TLTB", val12.transform, "No live 2v2 right now.", 14f, C_LABEL, 257, (Vector2?)new Vector2(900f, 22f), richText: true, raycastTarget: false); object obj9 = txtTeamLiveBody; Component val13 = (Component)((obj9 is Component) ? obj9 : null); if ((Object)(object)val13 != (Object)null) { UIFactory.AddLE(val13.gameObject, -1f, 22f, -1f, 22f, -1f, 0f); } UIFactory.SetWordWrap(txtTeamLiveBody, on: false); teamLivePanel = val12; GameObject val14 = new GameObject("TQR"); val14.transform.SetParent(content.transform, false); val14.AddComponent(); UIFactory.AddHLG(val14, 8f); UIFactory.AddLE(val14, -1f, -1f, -1f, -1f, -1f, 0f); GameObject val15 = UIFactory.CreatePanel("TQL", val14.transform, C_PANEL); UIFactory.AddVLG(val15, 2f, 10, 10, 6, 6); UIFactory.AddLE(val15, -1f, -1f, -1f, -1f, 1f, 0f); txtTeamQueueListHeader = UIFactory.CreateText("TQLH", val15.transform, "Random Queue", 16f, C_SUB, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false); txtTeamQueueListBody = UIFactory.CreateText("TQLB", val15.transform, "Loading…", 14f, C_LABEL, 257, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false); object obj10 = txtTeamQueueListBody; Component val16 = (Component)((obj10 is Component) ? obj10 : null); if ((Object)(object)val16 != (Object)null) { UIFactory.AddLE(val16.gameObject, -1f, 22f, -1f, 22f, -1f, 0f); } UIFactory.SetWordWrap(txtTeamQueueListBody, on: true); GameObject val17 = UIFactory.CreatePanel("TQM", val14.transform, C_PANEL); UIFactory.AddVLG(val17, 2f, 10, 10, 6, 6); UIFactory.AddLE(val17, -1f, -1f, -1f, -1f, 1f, 0f); txtTeamQueueManualHeader = UIFactory.CreateText("TQMH", val17.transform, "Custom Lobbies", 16f, C_SUB, 513, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false); txtTeamQueueManualBody = UIFactory.CreateText("TQMB", val17.transform, "Loading…", 14f, C_LABEL, 257, (Vector2?)new Vector2(440f, 22f), richText: true, raycastTarget: false); object obj11 = txtTeamQueueManualBody; Component val18 = (Component)((obj11 is Component) ? obj11 : null); if ((Object)(object)val18 != (Object)null) { UIFactory.AddLE(val18.gameObject, -1f, 22f, -1f, 22f, -1f, 0f); } UIFactory.SetWordWrap(txtTeamQueueManualBody, on: true); disablePanelRaycast(val12); disablePanelRaycast(val15); disablePanelRaycast(val17); UIFactory.SetBold(UIFactory.CreateText("TSH", content.transform, "v Scroll down for leaderboard + recent series v", 13f, C_LABEL, 514, (Vector2?)new Vector2(900f, 18f), richText: true, raycastTarget: false), b: false); GameObject val19 = new GameObject("TBot"); val19.transform.SetParent(content.transform, false); val19.AddComponent(); UIFactory.AddHLG(val19, 8f); UIFactory.AddLE(val19, -1f, 400f, -1f, 720f, -1f, 0f); GameObject val20 = new GameObject("TLBCol"); val20.transform.SetParent(val19.transform, false); val20.AddComponent(); UIFactory.AddVLG(val20, 4f); UIFactory.AddLE(val20, -1f, -1f, -1f, -1f, 1f, 1f); txtTeamLBHeader = UIFactory.CreateText("TLBH", val20.transform, "2v2 Leaderboard", 18f, C_SUB, 513, (Vector2?)new Vector2(560f, 24f), richText: true, raycastTarget: false); GameObject val21 = new GameObject("TLBHR"); val21.transform.SetParent(val20.transform, false); val21.AddComponent(); UIFactory.AddHLG(val21, 4f, 8, 8); UIFactory.AddLE(val21, -1f, 24f, -1f, 24f, -1f, 0f); string[] array = new string[8] { "#", "Player", "Rating", "W-L", "WR", "Avg Mate Elo", "Gold", "XP" }; string[] hdrSortKey = new string[8] { null, null, "rating", "wins", "win_rate", "avg_teammate_elo", "team_gold_earned", "team_xp_earned" }; teamLBSortBtns = new List(); teamLBSortKeys = hdrSortKey; teamLBHeaderTexts = new object[array.Length]; for (int num = 0; num < array.Length; num++) { int idx = num; if (hdrSortKey[num] == null) { object obj12 = UIFactory.CreateText($"TLBH_{num}", val21.transform, array[num], 13f, C_LABEL, (num == 0) ? 513 : 513, (Vector2?)new Vector2((float)TLB_COL_W[num], 24f), richText: true, raycastTarget: false); teamLBHeaderTexts[num] = obj12; teamLBSortBtns.Add(null); continue; } GameObject val22 = UIFactory.CreateButton("TLBS_" + hdrSortKey[num], val21.transform, array[num], 13f, C_LABEL, new Color(0.18f, 0.2f, 0.24f, 0.85f), (UnityAction)delegate { ApiClient.FetchTeamLeaderboard(200, hdrSortKey[idx]); }, (Vector2?)new Vector2((float)TLB_COL_W[num], 24f)); teamLBSortBtns.Add(val22); teamLBHeaderTexts[num] = UIFactory.GetButtonText(val22); } UIFactory.ScrollViewRefs scrollViewRefs2 = UIFactory.CreateScrollView("TLBSV", val20.transform, 1f); UIFactory.AddLE(scrollViewRefs2.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); teamLBContainer = scrollViewRefs2.content; for (int num2 = 0; num2 < 100; num2++) { teamLBRows.Add(CreateTeamLBRow(teamLBContainer.transform, $"tlb{num2}")); } GameObject val23 = new GameObject("TH2Col"); val23.transform.SetParent(val19.transform, false); val23.AddComponent(); UIFactory.AddVLG(val23, 4f); UIFactory.AddLE(val23, -1f, -1f, -1f, -1f, 1f, 1f); GameObject val24 = new GameObject("THHR"); val24.transform.SetParent(val23.transform, false); val24.AddComponent(); UIFactory.AddHLG(val24, 6f); UIFactory.AddLE(val24, -1f, 26f, -1f, 26f, -1f, 0f); txtTeamHistHeader = UIFactory.CreateText("THH", val24.transform, "Recent 2v2 Series", 18f, C_SUB, 513, (Vector2?)new Vector2(280f, 26f), richText: true, raycastTarget: false); GameObject val25 = new GameObject("THSp"); val25.transform.SetParent(val24.transform, false); val25.AddComponent(); UIFactory.AddLE(val25, -1f, -1f, -1f, -1f, 1f); Transform transform7 = val24.transform; Color c_WHITE7 = C_WHITE; Color bgColor7 = new Color(0.22f, 0.25f, 0.3f, 0.95f); object obj13 = <>c.<>9__494_7; if (obj13 == null) { UnityAction val26 = delegate { teamSeriesPageReq = Math.Max(0, teamSeriesPageReq - 1); ApiClient.FetchAllSeriesPaged(teamSeriesPageReq, 10); }; <>c.<>9__494_7 = val26; obj13 = (object)val26; } teamHistPrevBtn = UIFactory.CreateButton("THPP", transform7, "<", 13f, c_WHITE7, bgColor7, (UnityAction)obj13, (Vector2?)new Vector2(28f, 22f)); txtTeamHistPageIndicator = UIFactory.CreateText("THPI", val24.transform, "1/1", 13f, C_LABEL, 514, (Vector2?)new Vector2(48f, 22f), richText: true, raycastTarget: false); Transform transform8 = val24.transform; Color c_WHITE8 = C_WHITE; Color bgColor8 = new Color(0.22f, 0.25f, 0.3f, 0.95f); object obj14 = <>c.<>9__494_8; if (obj14 == null) { UnityAction val27 = delegate { teamSeriesPageReq++; ApiClient.FetchAllSeriesPaged(teamSeriesPageReq, 10); }; <>c.<>9__494_8 = val27; obj14 = (object)val27; } teamHistNextBtn = UIFactory.CreateButton("THPN", transform8, ">", 13f, c_WHITE8, bgColor8, (UnityAction)obj14, (Vector2?)new Vector2(28f, 22f)); UIFactory.ScrollViewRefs scrollViewRefs3 = UIFactory.CreateScrollView("THSV", val23.transform); UIFactory.AddLE(scrollViewRefs3.scrollGO, -1f, -1f, -1f, -1f, -1f, 1f); teamHistContainer = scrollViewRefs3.content; teamHistScrollRect = scrollViewRefs3.scrollGO.GetComponent(UIFactory.tScrollRect); for (int num3 = 0; num3 < 80; num3++) { teamHistRows.Add(CreateTeamHistRow(teamHistContainer.transform, $"th{num3}")); } return val; static void disablePanelRaycast(GameObject p) { Component component = p.GetComponent(UIFactory.tImage); if ((Object)(object)component != (Object)null) { UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, false); } } } private static TeamHistRow CreateTeamHistRow(Transform parent, string name) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_019b: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) TeamHistRow teamHistRow = new TeamHistRow(); teamHistRow.root = new GameObject(name); teamHistRow.root.transform.SetParent(parent, false); teamHistRow.root.AddComponent(); UIFactory.AddVLG(teamHistRow.root, 2f, 8, 6, 4, 4); UIFactory.AddLE(teamHistRow.root, -1f, 30f, -1f, -1f, -1f, 0f); teamHistRow.txtLine1 = UIFactory.CreateText("l1", teamHistRow.root.transform, "", 15f, C_WHITE, 257, (Vector2?)new Vector2(560f, 22f), richText: true, raycastTarget: false); teamHistRow.txtLine2 = UIFactory.CreateText("l2", teamHistRow.root.transform, "", 13f, C_LABEL, 257, (Vector2?)new Vector2(560f, 22f), richText: true, raycastTarget: false); teamHistRow.cardsRow = new GameObject("cardsRow"); teamHistRow.cardsRow.transform.SetParent(teamHistRow.root.transform, false); teamHistRow.cardsRow.AddComponent(); UIFactory.AddHLG(teamHistRow.cardsRow, 4f, 12); UIFactory.AddLE(teamHistRow.cardsRow, -1f, 24f, -1f, -1f, -1f, 0f); teamHistRow.txtCardsLeft = UIFactory.CreateText("cl", teamHistRow.cardsRow.transform, "", 13f, new Color(0.55f, 0.8f, 1f), 257, (Vector2?)new Vector2(220f, 200f), richText: true, raycastTarget: false); teamHistRow.txtCardsRight = UIFactory.CreateText("cr", teamHistRow.cardsRow.transform, "", 13f, new Color(1f, 0.69f, 0.53f), 257, (Vector2?)new Vector2(220f, 200f), richText: true, raycastTarget: false); UIFactory.SetWordWrap(teamHistRow.txtCardsLeft, on: true); UIFactory.SetWordWrap(teamHistRow.txtCardsRight, on: true); teamHistRow.cardsRow.SetActive(false); if (UIFactory.tImage != null && (Object)(object)teamHistRow.root.GetComponent(UIFactory.tImage) == (Object)null) { Component obj = teamHistRow.root.AddComponent(UIFactory.tImage); UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, (object)new Color(1f, 1f, 1f, 0.01f)); UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public)?.SetValue(obj, true); } if ((Object)(object)teamHistRow.root.GetComponent() == (Object)null) { ClickHandler clickHandler = teamHistRow.root.AddComponent(); TeamHistRow capturedRow = teamHistRow; clickHandler.onClick = delegate { if (ClickGuard.Claim() && capturedRow.isHeader && !string.IsNullOrEmpty(capturedRow.seriesKey)) { _teamSeriesExpanded.TryGetValue(capturedRow.seriesKey, out var value); _teamSeriesExpanded[capturedRow.seriesKey] = !value; dirty = true; } }; } teamHistRow.root.SetActive(false); return teamHistRow; } private static TeamLBRow CreateTeamLBRow(Transform parent, string name) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) TeamLBRow teamLBRow = new TeamLBRow(); teamLBRow.root = new GameObject(name); teamLBRow.root.transform.SetParent(parent, false); teamLBRow.root.AddComponent(); UIFactory.AddHLG(teamLBRow.root, 4f, 8, 8); UIFactory.AddLE(teamLBRow.root, -1f, 22f, -1f, 22f, -1f, 0f); teamLBRow.txtRank = UIFactory.CreateText("r", teamLBRow.root.transform, "", 15f, C_GOLD, 513, (Vector2?)new Vector2((float)TLB_COL_W[0], 22f), richText: true, raycastTarget: false); teamLBRow.txtName = UIFactory.CreateText("n", teamLBRow.root.transform, "", 15f, C_WHITE, 513, (Vector2?)new Vector2((float)TLB_COL_W[1], 22f), richText: true, raycastTarget: false); teamLBRow.txtRating = UIFactory.CreateText("rt", teamLBRow.root.transform, "", 15f, C_WHITE, 514, (Vector2?)new Vector2((float)TLB_COL_W[2], 22f), richText: true, raycastTarget: false); UIFactory.SetBold(teamLBRow.txtRating, b: true); teamLBRow.txtWL = UIFactory.CreateText("wl", teamLBRow.root.transform, "", 14f, C_LABEL, 514, (Vector2?)new Vector2((float)TLB_COL_W[3], 22f), richText: true, raycastTarget: false); teamLBRow.txtWR = UIFactory.CreateText("wr", teamLBRow.root.transform, "", 14f, C_LABEL, 514, (Vector2?)new Vector2((float)TLB_COL_W[4], 22f), richText: true, raycastTarget: false); teamLBRow.txtMate = UIFactory.CreateText("mt", teamLBRow.root.transform, "", 14f, C_LABEL, 514, (Vector2?)new Vector2((float)TLB_COL_W[5], 22f), richText: true, raycastTarget: false); teamLBRow.txtGold = UIFactory.CreateText("g", teamLBRow.root.transform, "", 14f, C_LABEL, 514, (Vector2?)new Vector2((float)TLB_COL_W[6], 22f), richText: true, raycastTarget: false); teamLBRow.txtXp = UIFactory.CreateText("xp", teamLBRow.root.transform, "", 14f, C_LABEL, 514, (Vector2?)new Vector2((float)TLB_COL_W[7], 22f), richText: true, raycastTarget: false); teamLBRow.root.SetActive(false); return teamLBRow; } private static float ReadTeamHistScroll() { try { if (teamHistScrollRect == null) { return -1f; } PropertyInfo property = UIFactory.tScrollRect.GetProperty("verticalNormalizedPosition", BindingFlags.Instance | BindingFlags.Public); return (property != null) ? ((float)property.GetValue(teamHistScrollRect)) : (-1f); } catch { return -1f; } } private static void WriteTeamHistScroll(float v) { try { if (teamHistScrollRect != null && !(v < 0f)) { UIFactory.tScrollRect.GetProperty("verticalNormalizedPosition", BindingFlags.Instance | BindingFlags.Public)?.SetValue(teamHistScrollRect, Mathf.Clamp01(v)); } } catch { } } private static IEnumerator RestoreTeamHistScroll(float v) { yield return null; yield return (object)new WaitForEndOfFrame(); WriteTeamHistScroll(v); } private static void RefreshTeamTab() { //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0a57: Unknown result type (might be due to invalid IL or missing references) //IL_0a50: Unknown result type (might be due to invalid IL or missing references) //IL_092a: Unknown result type (might be due to invalid IL or missing references) //IL_090f: Unknown result type (might be due to invalid IL or missing references) float num = ReadTeamHistScroll(); int cachedTeamQueueSearching = ApiClient.CachedTeamQueueSearching; string arg = ((cachedTeamQueueSearching > 0) ? "#88FF88" : "#888"); UIFactory.SetText(txtTeamHeader, $"2v2 Ranked ({cachedTeamQueueSearching} searching)"); ApiClient.TeamQueueState currentTeamQueueState = ApiClient.CurrentTeamQueueState; ApiClient.TeamQueuePollData lastTeamPollData = ApiClient.LastTeamPollData; string s = ""; string s2; switch (currentTeamQueueState) { case ApiClient.TeamQueueState.Idle: s2 = "Pick Search Random for matchmaking, or Find Custom Lobby to choose teams."; if ((Object)(object)teamSearchBtn != (Object)null) { teamSearchBtn.SetActive(true); } if ((Object)(object)teamSearchCustomBtn != (Object)null) { teamSearchCustomBtn.SetActive(true); } if ((Object)(object)teamLeaveBtn != (Object)null) { teamLeaveBtn.SetActive(false); } if ((Object)(object)teamReadyBtn != (Object)null) { teamReadyBtn.SetActive(false); } break; case ApiClient.TeamQueueState.Searching: { int num2 = ((lastTeamPollData == null || lastTeamPollData.queue_count <= 0) ? 1 : lastTeamPollData.queue_count); if (num2 < 1) { num2 = 1; } if (num2 > 4) { num2 = 4; } string arg2 = ((ApiClient.CurrentTeamQueueType == "manual") ? "custom 2v2 lobby" : "2v2"); s2 = $"Searching for {arg2}... {num2}/4"; if ((Object)(object)teamSearchBtn != (Object)null) { teamSearchBtn.SetActive(false); } if ((Object)(object)teamSearchCustomBtn != (Object)null) { teamSearchCustomBtn.SetActive(false); } if ((Object)(object)teamLeaveBtn != (Object)null) { teamLeaveBtn.SetActive(true); } if ((Object)(object)teamReadyBtn != (Object)null) { teamReadyBtn.SetActive(false); } break; } case ApiClient.TeamQueueState.Matched: s2 = "Match found! Click Ready Up."; if ((Object)(object)teamSearchBtn != (Object)null) { teamSearchBtn.SetActive(false); } if ((Object)(object)teamSearchCustomBtn != (Object)null) { teamSearchCustomBtn.SetActive(false); } if ((Object)(object)teamLeaveBtn != (Object)null) { teamLeaveBtn.SetActive(true); } if ((Object)(object)teamReadyBtn != (Object)null) { teamReadyBtn.SetActive(true); } s = BuildTeamMembersString(lastTeamPollData); break; case ApiClient.TeamQueueState.ReadySent: s2 = "Ready! Waiting for the other 3..."; if ((Object)(object)teamSearchBtn != (Object)null) { teamSearchBtn.SetActive(false); } if ((Object)(object)teamSearchCustomBtn != (Object)null) { teamSearchCustomBtn.SetActive(false); } if ((Object)(object)teamLeaveBtn != (Object)null) { teamLeaveBtn.SetActive(true); } if ((Object)(object)teamReadyBtn != (Object)null) { teamReadyBtn.SetActive(false); } s = BuildTeamMembersString(lastTeamPollData); break; default: s2 = ""; break; } UIFactory.SetText(txtTeamStatus, s2); UIFactory.SetText(txtTeamMembers, s); ApiClient.UpdateTeamSeriesStatePoll(force: false); int lastSeriesDcGraceSeconds = ApiClient.LastSeriesDcGraceSeconds; string lastSeriesStateStatus = ApiClient.LastSeriesStateStatus; object obj = txtTeamDcGrace; object obj2 = ((obj is Component) ? obj : null); GameObject val = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)val != (Object)null) { if (lastSeriesStateStatus == "dc_paused" && lastSeriesDcGraceSeconds > 0) { int num3 = lastSeriesDcGraceSeconds / 60; int num4 = lastSeriesDcGraceSeconds % 60; int lastSeriesT1Wins = ApiClient.LastSeriesT1Wins; int lastSeriesT2Wins = ApiClient.LastSeriesT2Wins; UIFactory.SetText(txtTeamDcGrace, $"Series paused — same 4 can re-queue to resume {num3}:{num4:D2} (score {lastSeriesT1Wins}-{lastSeriesT2Wins})"); val.SetActive(true); } else { val.SetActive(false); } } ApiClient.UpdateTeamQueueList(); List cachedTeamQueueAuto = ApiClient.CachedTeamQueueAuto; List cachedTeamQueueManual = ApiClient.CachedTeamQueueManual; int num5 = 0; bool flag = ApiClient.CurrentTeamQueueType == "manual" && (currentTeamQueueState == ApiClient.TeamQueueState.Searching || currentTeamQueueState == ApiClient.TeamQueueState.Matched); if (cachedTeamQueueManual != null) { foreach (ApiClient.TeamQueueListEntry item in cachedTeamQueueManual) { if (item.steam_id == MatchTracker.LocalSteamId) { num5 = item.preferred_team; break; } } } if ((Object)(object)teamPickT1Btn != (Object)null) { teamPickT1Btn.SetActive(flag); } if ((Object)(object)teamPickT2Btn != (Object)null) { teamPickT2Btn.SetActive(flag); } object obj3 = txtPickStatus; Component val2 = (Component)((obj3 is Component) ? obj3 : null); if ((Object)(object)val2 != (Object)null) { val2.gameObject.SetActive(flag); } if (flag) { float num6 = 0.95f; float num7 = 0.95f; Color c = ((num5 == 1) ? new Color(1f, 0.65f, 0.2f, num6) : new Color(0.4f, 0.25f, 0.1f, num6 * 0.7f)); Color c2 = ((num5 == 2) ? new Color(0.3f, 0.7f, 1f, num7) : new Color(0.1f, 0.25f, 0.45f, num7 * 0.7f)); UIFactory.SetImageColor(teamPickT1Btn, c); UIFactory.SetImageColor(teamPickT2Btn, c2); UIFactory.SetText(UIFactory.GetButtonText(teamPickT1Btn), (num5 == 1) ? "✓ Team 1 (Orange)" : "Team 1 (Orange)"); UIFactory.SetText(UIFactory.GetButtonText(teamPickT2Btn), (num5 == 2) ? "✓ Team 2 (Blue)" : "Team 2 (Blue)"); int num8 = 0; if (cachedTeamQueueManual != null) { foreach (ApiClient.TeamQueueListEntry item2 in cachedTeamQueueManual) { if (item2.status == "searching") { num8++; } } } string s3 = ((num5 == 0) ? $"Claim Team 1 or Team 2. ({num8}/4 in lobby)" : $"Locked in to Team {num5}. ({num8}/4 in lobby)"); UIFactory.SetText(txtPickStatus, s3); } RenderTeamQueueSection(cachedTeamQueueAuto, txtTeamQueueListHeader, txtTeamQueueListBody, "Random Queue"); RenderTeamQueueSection(cachedTeamQueueManual, txtTeamQueueManualHeader, txtTeamQueueManualBody, "Custom Lobbies"); List cachedActiveTeamSeries = ApiClient.CachedActiveTeamSeries; int num9 = cachedActiveTeamSeries?.Count ?? 0; if ((Object)(object)teamLivePanel != (Object)null) { teamLivePanel.SetActive(num9 > 0); } if (num9 > 0) { UIFactory.SetText(txtTeamLiveHeader, $"* Live 2v2 Now ({num9})"); StringBuilder stringBuilder = new StringBuilder(); foreach (ApiClient.ActiveTeamSeriesEntry item3 in cachedActiveTeamSeries) { stringBuilder.Append($"{Trunc(item3.t1a_name, 7)}({item3.t1a_rating})+{Trunc(item3.t1b_name, 7)}({item3.t1b_rating})"); stringBuilder.Append($" {item3.t1_wins}-{item3.t2_wins} "); stringBuilder.Append($"{Trunc(item3.t2a_name, 7)}({item3.t2a_rating})+{Trunc(item3.t2b_name, 7)}({item3.t2b_rating})\n"); } UIFactory.SetText(txtTeamLiveBody, stringBuilder.ToString().TrimEnd('\n')); int num10 = Math.Max(22, num9 * 18 + 4); object obj4 = txtTeamLiveBody; Component val3 = (Component)((obj4 is Component) ? obj4 : null); if ((Object)(object)val3 != (Object)null) { Component component = val3.gameObject.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { UIFactory.tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, (float)num10); UIFactory.tLE.GetProperty("minHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, (float)num10); } } } List list = ApiClient.CachedTeamLeaderboard ?? new List(); string text = ApiClient.CachedTeamLeaderboardSort ?? "rating"; if (teamLBSortKeys != null && teamLBHeaderTexts != null && teamLBSortBtns != null) { for (int i = 0; i < teamLBSortKeys.Length; i++) { bool flag2 = teamLBSortKeys[i] != null && teamLBSortKeys[i] == text; string text2 = i switch { 0 => "#", 1 => "Player", 2 => "Rating", 3 => "W-L", 4 => "WR", 5 => "Avg Mate Elo", 6 => "Gold", 7 => "XP", _ => "", }; if (flag2) { text2 += " v"; } UIFactory.SetText(teamLBHeaderTexts[i], text2); if ((Object)(object)teamLBSortBtns[i] != (Object)null) { UIFactory.SetImageColor(teamLBSortBtns[i], flag2 ? new Color(0.3f, 0.4f, 0.55f, 0.95f) : new Color(0.18f, 0.2f, 0.24f, 0.85f)); } } } for (int j = 0; j < teamLBRows.Count; j++) { TeamLBRow teamLBRow = teamLBRows[j]; if (j >= list.Count) { teamLBRow.root.SetActive(false); continue; } ApiClient.TeamLeaderboardEntry teamLeaderboardEntry = list[j]; bool flag3 = teamLeaderboardEntry.steam_id == MatchTracker.LocalSteamId; UIFactory.SetText(teamLBRow.txtRank, $"#{teamLeaderboardEntry.rank}"); string text3 = Trunc(teamLeaderboardEntry.display_name, 14); if (!string.IsNullOrEmpty(teamLeaderboardEntry.title)) { string text4 = (string.IsNullOrEmpty(teamLeaderboardEntry.title_color) ? "#FFD94D" : teamLeaderboardEntry.title_color); text3 = text3 + " [" + Trunc(teamLeaderboardEntry.title, 12) + "]"; } UIFactory.SetText(teamLBRow.txtName, text3); UIFactory.SetColor(teamLBRow.txtName, flag3 ? C_GREEN : C_WHITE); if (teamLeaderboardEntry.rd > 0) { UIFactory.SetText(teamLBRow.txtRating, $"{teamLeaderboardEntry.rating} ±{teamLeaderboardEntry.rd}"); } else { UIFactory.SetText(teamLBRow.txtRating, $"{teamLeaderboardEntry.rating}"); } UIFactory.SetText(teamLBRow.txtWL, $"{teamLeaderboardEntry.series_wins}-{teamLeaderboardEntry.series_losses}"); UIFactory.SetText(teamLBRow.txtWR, $"{teamLeaderboardEntry.win_rate * 100f:F0}%"); UIFactory.SetText(teamLBRow.txtMate, (teamLeaderboardEntry.avg_teammate_elo > 0) ? $"{teamLeaderboardEntry.avg_teammate_elo}" : "—"); UIFactory.SetText(teamLBRow.txtGold, $"{teamLeaderboardEntry.team_gold_earned}"); UIFactory.SetText(teamLBRow.txtXp, $"{teamLeaderboardEntry.team_xp_earned}"); teamLBRow.root.SetActive(true); } if (list.Count == 0) { UIFactory.SetText(txtTeamLBHeader, "2v2 Leaderboard — no completed series yet"); } else { UIFactory.SetText(txtTeamLBHeader, $"2v2 Leaderboard ({list.Count} ranked)"); } List obj5 = ApiClient.CachedTeamSeriesPaged ?? new List(); string localSteamId = MatchTracker.LocalSteamId; int num11 = 0; CompetitiveUI.ClearCardHoverRegions(); foreach (ApiClient.TeamSeriesPagedEntry item4 in obj5) { if (num11 >= teamHistRows.Count) { break; } ApiClient.TeamSeriesSlot teamSeriesSlot = null; int num12 = 0; if (item4.t1a?.steam_id == localSteamId) { teamSeriesSlot = item4.t1a; num12 = 1; } else if (item4.t1b?.steam_id == localSteamId) { teamSeriesSlot = item4.t1b; num12 = 1; } else if (item4.t2a?.steam_id == localSteamId) { teamSeriesSlot = item4.t2a; num12 = 2; } else if (item4.t2b?.steam_id == localSteamId) { teamSeriesSlot = item4.t2b; num12 = 2; } bool flag4 = teamSeriesSlot != null; int num13 = ((flag4 && num12 == 2) ? item4.t2_series_wins : item4.t1_series_wins); int num14 = ((flag4 && num12 == 2) ? item4.t1_series_wins : item4.t2_series_wins); bool flag5 = flag4 && item4.winner_team == num12; string text5 = ((!flag4) ? "·" : (flag5 ? "W" : "L")); string text6 = ""; if (teamSeriesSlot != null && Mathf.Abs(teamSeriesSlot.rating_change) > 0.01f) { string arg3 = ((teamSeriesSlot.rating_change > 0f) ? "#00FF00" : "#FF6666"); text6 = string.Format(" {1}{2:F0} elo", arg3, (teamSeriesSlot.rating_change > 0f) ? "+" : "", teamSeriesSlot.rating_change); } string text7 = ""; if (teamSeriesSlot != null && (teamSeriesSlot.gold_earned > 0 || teamSeriesSlot.xp_earned > 0)) { text7 = $" +{teamSeriesSlot.gold_earned}g +{teamSeriesSlot.xp_earned}xp"; } string text8 = ""; try { if (!string.IsNullOrEmpty(item4.completed_at) && item4.completed_at.Length >= 10) { text8 = DateTime.Parse(item4.completed_at).ToString("M/d"); } } catch { } ApiClient.TeamSeriesSlot a; ApiClient.TeamSeriesSlot b; ApiClient.TeamSeriesSlot a2; ApiClient.TeamSeriesSlot b2; if (flag4 && num12 == 2) { a = item4.t2a; b = item4.t2b; a2 = item4.t1a; b2 = item4.t1b; } else { a = item4.t1a; b = item4.t1b; a2 = item4.t2a; b2 = item4.t2b; } string text9 = (flag4 ? " (you)" : ""); string s4 = FormatTeamSide(a, b, "#6FB7FF") + text9 + " vs " + FormatTeamSide(a2, b2, "#FFA864"); _teamSeriesExpanded.TryGetValue(item4.series_id ?? "", out var value); string text10 = (value ? "[-]" : "[+]"); string text11; if (flag4) { text11 = (flag5 ? $"WON {num13}-{num14}" : $"LOST {num13}-{num14}"); } else { string arg4 = ((item4.winner_team == 1) ? "Blue" : "Orange"); int num15 = Math.Max(num13, num14); int num16 = Math.Min(num13, num14); text11 = $"{arg4} won {num15}-{num16}"; } TeamHistRow teamHistRow = teamHistRows[num11++]; teamHistRow.isHeader = true; teamHistRow.seriesKey = item4.series_id ?? ""; UIFactory.SetText(teamHistRow.txtLine1, text10 + " " + text5 + " " + text11 + " " + text8 + "" + text6 + text7); UIFactory.SetText(teamHistRow.txtLine2, s4); object txtLine = teamHistRow.txtLine2; object obj7 = ((txtLine is Component) ? txtLine : null); GameObject val4 = ((obj7 != null) ? ((Component)obj7).gameObject : null); if ((Object)(object)val4 != (Object)null) { val4.SetActive(true); } if ((Object)(object)teamHistRow.cardsRow != (Object)null) { teamHistRow.cardsRow.SetActive(false); } SetTeamHistRowPrefH(teamHistRow, 46); teamHistRow.root.SetActive(true); if (!value) { continue; } int num17 = 0; foreach (ApiClient.TeamSeriesMatch match in item4.matches) { if (num11 >= teamHistRows.Count) { break; } num17++; int num18 = ((flag4 && num12 == 2) ? match.t2_rounds_won : match.t1_rounds_won); int num19 = ((flag4 && num12 == 2) ? match.t1_rounds_won : match.t2_rounds_won); string text12 = ((!flag4) ? "·" : ((num18 > num19) ? "W" : "L")); string text13 = BuildTeamCardsColumnChips(match, a, b); string text14 = BuildTeamCardsColumnChips(match, a2, b2); TeamHistRow teamHistRow2 = teamHistRows[num11++]; teamHistRow2.isHeader = false; teamHistRow2.seriesKey = item4.series_id ?? ""; UIFactory.SetText(teamHistRow2.txtLine1, $" Game {num17}: {text12} {num18}-{num19}"); object txtLine2 = teamHistRow2.txtLine2; object obj8 = ((txtLine2 is Component) ? txtLine2 : null); GameObject val5 = ((obj8 != null) ? ((Component)obj8).gameObject : null); if ((Object)(object)val5 != (Object)null) { val5.SetActive(false); } UIFactory.SetText(teamHistRow2.txtCardsLeft, string.IsNullOrEmpty(text13) ? "—" : text13); UIFactory.SetText(teamHistRow2.txtCardsRight, string.IsNullOrEmpty(text14) ? "—" : text14); if ((Object)(object)teamHistRow2.cardsRow != (Object)null) { teamHistRow2.cardsRow.SetActive(true); } RegisterHoverRectFor(teamHistRow2.txtCardsLeft, BuildTeamCardsFullLine(match, a, b), isOpponent: false, "", BuildTeamCardsTooltipBody(match, a, b)); RegisterHoverRectFor(teamHistRow2.txtCardsRight, BuildTeamCardsFullLine(match, a2, b2), isOpponent: true, "", BuildTeamCardsTooltipBody(match, a2, b2)); int val6 = CountCardChipLines(match, a, b); int val7 = CountCardChipLines(match, a2, b2); int num20 = Math.Max(2, Math.Max(val6, val7)) * 19 + 4; SetTeamHistRowPrefH(teamHistRow2, 26 + num20); teamHistRow2.root.SetActive(true); } } for (int k = num11; k < teamHistRows.Count; k++) { teamHistRows[k].root.SetActive(false); } int cachedTeamSeriesTotal = ApiClient.CachedTeamSeriesTotal; int cachedTeamSeriesTotalPages = ApiClient.CachedTeamSeriesTotalPages; int cachedTeamSeriesPage = ApiClient.CachedTeamSeriesPage; if (cachedTeamSeriesTotal == 0) { UIFactory.SetText(txtTeamHistHeader, "Recent 2v2 Series — none yet"); if (txtTeamHistPageIndicator != null) { UIFactory.SetText(txtTeamHistPageIndicator, "—"); } if ((Object)(object)teamHistPrevBtn != (Object)null) { teamHistPrevBtn.SetActive(false); } if ((Object)(object)teamHistNextBtn != (Object)null) { teamHistNextBtn.SetActive(false); } } else { UIFactory.SetText(txtTeamHistHeader, $"Recent 2v2 Series ({cachedTeamSeriesTotal} total)"); if (txtTeamHistPageIndicator != null) { UIFactory.SetText(txtTeamHistPageIndicator, $"{cachedTeamSeriesPage + 1}/{Math.Max(1, cachedTeamSeriesTotalPages)}"); } if ((Object)(object)teamHistPrevBtn != (Object)null) { teamHistPrevBtn.SetActive(cachedTeamSeriesPage > 0); } if ((Object)(object)teamHistNextBtn != (Object)null) { teamHistNextBtn.SetActive(cachedTeamSeriesPage + 1 < cachedTeamSeriesTotalPages); } } if (num >= 0f && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(RestoreTeamHistScroll(num)); } } private static string FormatTitleName(ApiClient.TeamSeriesSlot s) { if (s == null) { return "?"; } string text = Trunc(s.name ?? "?", 12); if (string.IsNullOrEmpty(s.title)) { return text; } string text2 = (string.IsNullOrEmpty(s.title_color) ? "#FFD94D" : s.title_color); return text + " [" + Trunc(s.title, 10) + "]"; } private static string FormatTeamSide(ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b, string sideColor) { return FormatPlayerToken(a, sideColor) + " + " + FormatPlayerToken(b, sideColor); } private static string FormatPlayerToken(ApiClient.TeamSeriesSlot s, string sideColor) { if (s == null) { return "?"; } string text = "" + Trunc(s.name ?? "?", 12) + ""; string text2 = ""; if (!string.IsNullOrEmpty(s.title)) { string text3 = (string.IsNullOrEmpty(s.title_color) ? "#FFD94D" : s.title_color); text2 = " [" + Trunc(s.title, 10) + "]"; } string text4 = ((s.rating > 0) ? $" {s.rating}" : ""); return text + text2 + text4; } private static string BuildTeamCardsColumnChips(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { if (m == null || m.cards_by_player == null) { return ""; } bool flag = false; ApiClient.TeamSeriesSlot[] array = new ApiClient.TeamSeriesSlot[2] { a, b }; foreach (ApiClient.TeamSeriesSlot teamSeriesSlot in array) { if (teamSeriesSlot != null && !string.IsNullOrEmpty(teamSeriesSlot.steam_id) && m.cards_by_player.TryGetValue(teamSeriesSlot.steam_id, out var value) && value != null && value.Count > 0) { flag = true; break; } } if (!flag) { return "(card data not recorded)"; } StringBuilder sb = new StringBuilder(); appendFor(a); appendFor(b); return sb.ToString(); void appendFor(ApiClient.TeamSeriesSlot s) { if (s != null && !string.IsNullOrEmpty(s.steam_id)) { if (sb.Length > 0) { sb.Append("\n"); } List value2; bool num = m.cards_by_player.TryGetValue(s.steam_id, out value2) && value2 != null && value2.Count > 0; sb.Append("").Append(Trunc(s.name ?? "?", 14)).Append(""); if (!num) { sb.Append("\n —"); } else { sb.Append("\n ").Append(CardsToChips(value2)); } } } } private static string BuildTeamCardsFullLine(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { if (m == null || m.cards_by_player == null) { return ""; } List parts = new List(); addFor(a); addFor(b); return string.Join(", ", parts); void addFor(ApiClient.TeamSeriesSlot s) { if (s == null || string.IsNullOrEmpty(s.steam_id) || !m.cards_by_player.TryGetValue(s.steam_id, out var value) || value == null) { return; } foreach (string item in value) { if (!string.IsNullOrEmpty(item)) { parts.Add(item.Trim()); } } } } private static string BuildTeamCardsTooltipBody(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { if (m == null || m.cards_by_player == null) { return ""; } StringBuilder sb = new StringBuilder(); addFor(a); addFor(b); return sb.ToString(); void addFor(ApiClient.TeamSeriesSlot s) { if (s != null && !string.IsNullOrEmpty(s.steam_id)) { if (sb.Length > 0) { sb.Append('\n'); } sb.Append("").Append(Trunc(s.name ?? "?", 16)).Append(""); if (m.cards_by_player.TryGetValue(s.steam_id, out var value) && value != null && value.Count > 0) { foreach (string item in value) { string text = (item ?? "").Trim(); if (text.Length != 0) { int num = text.IndexOf('>'); if (num >= 0 && num < text.Length - 1) { text = text.Substring(num + 1); } int num2 = text.IndexOf('<'); if (num2 > 0) { text = text.Substring(0, num2); } text = text.Trim(); if (text.Length != 0) { sb.Append("\n • ").Append(text); } } } return; } sb.Append("\n (no cards)"); } } } private static string CardsToChips(List cards) { if (cards == null || cards.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); foreach (string card in cards) { string text = (card ?? "").Trim(); if (text.Length != 0) { int num = text.IndexOf('>'); if (num >= 0 && num < text.Length - 1) { text = text.Substring(num + 1); } int num2 = text.IndexOf('<'); if (num2 > 0) { text = text.Substring(0, num2); } text = text.Trim(); if (text.Length != 0) { string value = ((text.Length >= 2) ? text.Substring(0, 2).ToUpperInvariant() : text.ToUpperInvariant()); stringBuilder.Append('[').Append(value).Append("] "); } } } return stringBuilder.ToString().TrimEnd(); } private static int CountCardChipLines(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { int lines = 0; countFor(a); countFor(b); return lines; void countFor(ApiClient.TeamSeriesSlot s) { if (s != null && !string.IsNullOrEmpty(s.steam_id)) { lines++; if (m != null && m.cards_by_player != null && m.cards_by_player.TryGetValue(s.steam_id, out var value) && value != null && value.Count > 0) { lines += Math.Max(1, (value.Count + 7) / 8); } else { lines++; } } } } private static void SetTeamHistRowPrefH(TeamHistRow row, int prefH) { try { Component component = row.root.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { UIFactory.tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, (float)prefH); } int contentH; if ((Object)(object)row.cardsRow != (Object)null && row.cardsRow.activeSelf) { contentH = Math.Max(40, prefH - 26); resizeText(row.txtCardsLeft); resizeText(row.txtCardsRight); } void resizeText(object t) { //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_002a: 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) Component val = (Component)((t is Component) ? t : null); if (!((Object)(object)val == (Object)null)) { RectTransform component2 = val.GetComponent(); if (!((Object)(object)component2 == (Object)null)) { Vector2 sizeDelta = component2.sizeDelta; component2.sizeDelta = new Vector2(sizeDelta.x, (float)contentH); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2-HIST] row size update failed: " + ex.Message)); } } private static string BuildTeamCardsColumn(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { if (m == null || m.cards_by_player == null) { return ""; } bool flag = false; ApiClient.TeamSeriesSlot[] array = new ApiClient.TeamSeriesSlot[2] { a, b }; foreach (ApiClient.TeamSeriesSlot teamSeriesSlot in array) { if (teamSeriesSlot != null && !string.IsNullOrEmpty(teamSeriesSlot.steam_id) && m.cards_by_player.TryGetValue(teamSeriesSlot.steam_id, out var value) && value != null && value.Count > 0) { flag = true; break; } } if (!flag) { return "(card data not recorded)"; } StringBuilder sb = new StringBuilder(); appendFor(a); appendFor(b); return sb.ToString(); void appendFor(ApiClient.TeamSeriesSlot s) { if (s != null && !string.IsNullOrEmpty(s.steam_id)) { if (sb.Length > 0) { sb.Append("\n"); } List value2; bool num = m.cards_by_player.TryGetValue(s.steam_id, out value2) && value2 != null && value2.Count > 0; sb.Append("").Append(Trunc(s.name ?? "?", 14)).Append(""); if (!num) { sb.Append("\n —"); } else { for (int j = 0; j < value2.Count; j += 2) { sb.Append("\n ").Append(value2[j]); if (j + 1 < value2.Count) { sb.Append(", ").Append(value2[j + 1]); } } } } } } private static int CountCardLines(ApiClient.TeamSeriesMatch m, ApiClient.TeamSeriesSlot a, ApiClient.TeamSeriesSlot b) { int lines = 0; countFor(a); countFor(b); return lines; void countFor(ApiClient.TeamSeriesSlot s) { if (s != null && !string.IsNullOrEmpty(s.steam_id)) { lines++; if (m != null && m.cards_by_player != null && m.cards_by_player.TryGetValue(s.steam_id, out var value) && value != null && value.Count > 0) { lines += (value.Count + 1) / 2; } else { lines++; } } } } private static void RenderTeamQueueSection(List list, object header, object body, string label) { //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) int num = list?.Count ?? 0; float num2 = 18f; int num3; if (num == 0) { UIFactory.SetText(header, "" + label + " (empty)"); UIFactory.SetText(body, "No one in " + label.ToLower() + " right now."); num3 = 22; } else { UIFactory.SetText(header, $"{label} ({num})"); StringBuilder stringBuilder = new StringBuilder(); foreach (ApiClient.TeamQueueListEntry item in list) { string text = ((item.steam_id == MatchTracker.LocalSteamId) ? "" : ""); string text2 = (item.using_fallback_rating ? $"{item.balance_rating} 1v1" : $"{item.rating}"); string text3 = ((item.status == "searching") ? "searching" : ((item.status == "matched") ? "matched" : ("" + item.status + ""))); int num4 = item.wait_seconds / 60; int num5 = item.wait_seconds % 60; string text4 = ((num4 > 0) ? $"{num4}m{num5:D2}s" : $"{num5}s"); string text5 = ""; if (item.preferred_team == 1) { text5 = " T1"; } else if (item.preferred_team == 2) { text5 = " T2"; } stringBuilder.Append(" " + text + Trunc(item.display_name, 18) + " " + text2 + " " + text3 + " " + text4 + "" + text5 + "\n"); } UIFactory.SetText(body, stringBuilder.ToString()); num3 = (int)((float)num * num2 + 6f); } Component val = (Component)((body is Component) ? body : null); if ((Object)(object)val != (Object)null) { Component component = val.gameObject.GetComponent(UIFactory.tLE); if ((Object)(object)component != (Object)null) { UIFactory.tLE.GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, (float)num3); UIFactory.tLE.GetProperty("minHeight", BindingFlags.Instance | BindingFlags.Public)?.SetValue(component, (float)num3); } RectTransform component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.sizeDelta = new Vector2(component2.sizeDelta.x, (float)num3); } } } private static string JoinTeamCards(ApiClient.TeamMatchHistoryEntry m, int team) { if (m.cards_by_player == null || m.cards_by_player.Count == 0) { return ""; } string key = ((team == 1) ? m.t1a_steam_id : m.t2a_steam_id); string key2 = ((team == 1) ? m.t1b_steam_id : m.t2b_steam_id); string s = ((team == 1) ? m.t1a_name : m.t2a_name); string s2 = ((team == 1) ? m.t1b_name : m.t2b_name); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Trunc(s, 8)).Append(": "); if (m.cards_by_player.TryGetValue(key, out var value) && value.Count > 0) { stringBuilder.Append(string.Join(", ", value.GetRange(0, Math.Min(value.Count, 6)).ToArray())); } else { stringBuilder.Append("(no cards)"); } stringBuilder.Append(" | "); stringBuilder.Append(Trunc(s2, 8)).Append(": "); if (m.cards_by_player.TryGetValue(key2, out var value2) && value2.Count > 0) { stringBuilder.Append(string.Join(", ", value2.GetRange(0, Math.Min(value2.Count, 6)).ToArray())); } else { stringBuilder.Append("(no cards)"); } return stringBuilder.ToString(); } private static string BuildTeamMembersString(ApiClient.TeamQueuePollData poll) { if (poll == null) { return ""; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Your Team: "); stringBuilder.Append(ReadyTag(poll.my_ready) + "YOU"); if (poll.teammates != null) { foreach (ApiClient.TeamQueueMember teammate in poll.teammates) { stringBuilder.Append(", " + ReadyTag(teammate.ready) + Trunc(teammate.display_name, 16) + " " + FmtMemberRating(teammate)); } } stringBuilder.Append("\nOpponents: "); if (poll.opponents != null) { bool flag = true; foreach (ApiClient.TeamQueueMember opponent in poll.opponents) { if (!flag) { stringBuilder.Append(", "); } stringBuilder.Append(ReadyTag(opponent.ready) + Trunc(opponent.display_name, 16) + " " + FmtMemberRating(opponent)); flag = false; } } return stringBuilder.ToString(); } private static string ReadyTag(bool isReady) { if (!isReady) { return "[ ] "; } return "[R] "; } private static string FmtMemberRating(ApiClient.TeamQueueMember m) { if (m.using_fallback_rating && m.balance_rating > 0) { return $"({m.balance_rating} 1v1, {m.completed_series}/10 2v2 series)"; } return $"({m.rating})"; } [CompilerGenerated] internal static int g__rank|253_8(string sku) { if (sku.StartsWith("nametag_neon_", StringComparison.OrdinalIgnoreCase)) { return 2; } string subgroup = NametagStyler.GetSubgroup(sku); if (subgroup == null) { return 0; } return subgroup switch { "color" => 1, "glow" => 3, "size" => 4, _ => 5, }; } [CompilerGenerated] internal static int g__TierRank|369_0(string tier) { if (string.IsNullOrEmpty(tier)) { return 99; } return tier switch { "S" => 0, "A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5, "F" => 6, _ => 99, }; } } internal static class PerfGate { private static readonly Dictionary _counts = new Dictionary(); private static readonly Dictionary _lifetime = new Dictionary(); private static readonly HashSet _firstFireLogged = new HashSet(); public static bool Check(ConfigEntry perPatch) { ConfigEntry perfOptimizations = Plugin.PerfOptimizations; if (perfOptimizations != null && !perfOptimizations.Value) { return false; } if (perPatch != null && !perPatch.Value) { return false; } return true; } public static void Hit(string patch) { try { _counts.TryGetValue(patch, out var value); _counts[patch] = value + 1; _lifetime.TryGetValue(patch, out var value2); _lifetime[patch] = value2 + 1; if (_firstFireLogged.Add(patch)) { Plugin.Log.LogInfo((object)$"[PERF] {patch} FIRST FIRE (frame {Time.frameCount})"); } } catch { } } public static void DumpAndReset() { try { if (_counts.Count == 0) { Plugin.Log.LogInfo((object)"[PERF] No perf patches fired this match (toggles off, or none triggered)."); return; } StringBuilder stringBuilder = new StringBuilder("[PERF] Per-match patch hits: "); foreach (KeyValuePair count in _counts) { stringBuilder.Append(count.Key).Append('=').Append(count.Value) .Append(" "); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); _counts.Clear(); } catch { } } public static Dictionary LifetimeSnapshot() { try { return new Dictionary(_lifetime); } catch { return new Dictionary(); } } } [HarmonyPatch(typeof(PlayerManager), "SetInputActive")] internal class PlayerManagerSetInputActiveNullGuard { private static bool Prefix(PlayerManager __instance, bool inputActive) { try { List list = (((Object)(object)__instance != (Object)null) ? __instance.players : null); if (list == null) { return false; } for (int i = 0; i < list.Count; i++) { Player val = list[i]; try { if (!((Object)(object)val == (Object)null)) { CharacterData data = val.data; if (!((Object)(object)data == (Object)null) && !((Object)(object)data.view == (Object)null) && data.playerActions != null && data.view.IsMine) { ((PlayerActionSet)data.playerActions).Enabled = inputActive; } } } catch { } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[INPUTFIX] SetInputActive guard error: " + ex.Message)); } return false; } } [HarmonyPatch(typeof(EscapeMenuHandler), "ToggleEsc")] internal class EscapeMenuToggleEscFinalizer { private static Exception Finalizer(Exception __exception) { if (__exception != null) { Plugin.Log.LogWarning((object)("[INPUTFIX] EscapeMenuHandler.ToggleEsc threw (swallowed): " + __exception.Message)); } return null; } } [HarmonyPatch(typeof(StunPlayer), "Go")] internal class StunPlayerGoNullGuard { private static bool Prefix(StunPlayer __instance) { if (!PerfGate.Check(Plugin.PerfStunPlayerNullGuard)) { return true; } int num; if ((Object)(object)__instance != (Object)null) { num = (((Object)(object)((Component)__instance).GetComponentInParent() != (Object)null) ? 1 : 0); if (num != 0) { goto IL_0033; } } else { num = 0; } PerfGate.Hit("StunPlayerGoNullGuard"); goto IL_0033; IL_0033: return (byte)num != 0; } } [HarmonyPatch(typeof(ProjectileHit), "Update")] internal class ProjectileHitOutOfBoundsCleanup { private static readonly Dictionary _lastChecked = new Dictionary(64); private const float CHECK_INTERVAL = 0.5f; private const float X_MIN = -0.25f; private const float X_MAX = 1.25f; private const float Y_MIN = -1f; private static void Prefix(ProjectileHit __instance) { if (!PerfGate.Check(Plugin.PerfDespawnOffscreenBullets) || (Object)(object)__instance == (Object)null) { return; } int instanceID; try { instanceID = ((Object)__instance).GetInstanceID(); } catch { return; } float time = Time.time; if (_lastChecked.TryGetValue(instanceID, out var value) && time < value + 0.5f) { return; } _lastChecked[instanceID] = time; if (_lastChecked.Count > 512) { List list = new List(); foreach (KeyValuePair item in _lastChecked) { if (time - item.Value > 30f) { list.Add(item.Key); } } foreach (int item2 in list) { _lastChecked.Remove(item2); } } try { if (IsOutOfBounds(((Component)__instance).transform) && !((Object)(object)__instance.ownPlayer == (Object)null) && !((Object)(object)__instance.ownPlayer.data == (Object)null) && !((Object)(object)__instance.ownPlayer.data.view == (Object)null) && __instance.ownPlayer.data.view.IsMine && (Object)(object)((Component)__instance).gameObject != (Object)null) { PhotonNetwork.Destroy(((Component)__instance).gameObject); PerfGate.Hit("DespawnOffscreenBullets"); } } catch { } } private static bool IsOutOfBounds(Transform t) { //IL_002d: 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_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_0051: Unknown result type (might be due to invalid IL or missing references) try { MainCam instance = MainCam.instance; object obj; if (instance == null) { obj = null; } else { Transform transform = ((Component)instance).transform; obj = ((transform != null) ? ((Component)transform).GetComponent() : null); } Camera val = (Camera)obj; if ((Object)(object)val == (Object)null) { return false; } Vector3 val2 = val.WorldToScreenPoint(new Vector3(t.position.x, t.position.y, 0f)); float num = val2.x / Mathf.Max(1f, (float)Screen.width); float num2 = val2.y / Mathf.Max(1f, (float)Screen.height); return num <= -0.25f || num >= 1.25f || num2 <= -1f; } catch { return false; } } } [HarmonyPatch(typeof(RayHitBulletSound), "DoHitEffect")] internal class RayHitBulletSoundDoHitEffectFinalizer { private static Exception Finalizer(Exception __exception) { if (!PerfGate.Check(Plugin.PerfSwallowHitSoundNREs)) { return __exception; } if (__exception is NullReferenceException || __exception is MissingReferenceException) { PerfGate.Hit("SwallowHitSoundNRE"); return null; } return __exception; } } [HarmonyPatch(typeof(ScreenEdgeBounce), "DoHit")] internal class ScreenEdgeBounceDoHitFinalizer { private static Exception Finalizer(ScreenEdgeBounce __instance, Exception __exception) { if (!PerfGate.Check(Plugin.PerfSwallowEdgeBounceNREs)) { return __exception; } return _PerfHelpers.SwallowAndDestroy((MonoBehaviour)(object)__instance, __exception); } } [HarmonyPatch(typeof(ScreenEdgeBounce), "Update")] internal class ScreenEdgeBounceUpdateFinalizer { private static Exception Finalizer(ScreenEdgeBounce __instance, Exception __exception) { if (!PerfGate.Check(Plugin.PerfSwallowEdgeBounceNREs)) { return __exception; } return _PerfHelpers.SwallowAndDestroy((MonoBehaviour)(object)__instance, __exception); } } internal static class _PerfHelpers { internal static Exception SwallowAndDestroy(MonoBehaviour mb, Exception ex) { if (ex is NullReferenceException || ex is MissingReferenceException) { PerfGate.Hit("SwallowEdgeBounceNRE"); return null; } return ex; } } internal static class _PerfHelpersAlias { public static Exception _SwallowAndDestroy(ScreenEdgeBounce mb, Exception ex) { return _PerfHelpers.SwallowAndDestroy((MonoBehaviour)(object)mb, ex); } } [HarmonyPatch(typeof(DynamicParticles), "PlayBulletHit")] internal class DynamicParticlesPlayBulletHitCap { private const int MAX_PER_FRAME = 2; private static int _lastFrame = -1; private static int _countThisFrame; private static bool Prefix() { if (!PerfGate.Check(Plugin.PerfBulletHitParticleCap)) { return true; } int frameCount = Time.frameCount; if (frameCount != _lastFrame) { _lastFrame = frameCount; _countThisFrame = 0; } if (_countThisFrame >= 2) { PerfGate.Hit("BulletHitParticleCap"); return false; } _countThisFrame++; return true; } } [HarmonyPatch] internal class ObjectPoolInitClamp { private static MethodBase TargetMethod() { try { ConstructorInfo[] constructors = typeof(ObjectPool).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (ConstructorInfo constructorInfo in constructors) { ParameterInfo[] parameters = constructorInfo.GetParameters(); if (parameters.Length >= 2 && parameters[0].ParameterType == typeof(GameObject) && parameters[1].ParameterType == typeof(int)) { return constructorInfo; } } } catch { } return null; } private static void Prefix(ref int initSpawn) { if (!PerfGate.Check(Plugin.PerfClampObjectPoolInit)) { return; } try { if (!GameStateWatcher.IsInMatch) { return; } } catch { return; } if (initSpawn > 4) { initSpawn = 4; PerfGate.Hit("ClampObjectPoolInit"); } } } [HarmonyPatch(typeof(CardChoiceVisuals), "Show")] internal class CardChoiceVisualsShowParticlePause { private static void Postfix(CardChoiceVisuals __instance) { if (!PerfGate.Check(Plugin.PerfPauseCardPickParticles) || (Object)(object)__instance == (Object)null) { return; } try { object? obj = typeof(CardChoiceVisuals).GetField("currentSkin", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val == (Object)null)) { ParticleSystem componentInChildren = val.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.Pause(); PerfGate.Hit("PauseCardPickParticles"); } } } catch { } } } [HarmonyPatch(typeof(MenuControllerHandler), "Update")] [HarmonyPriority(800)] internal class MenuControllerHandlerUpdateBail { private static bool Prefix() { if (!PerfGate.Check(Plugin.PerfSkipMenuUpdateInMatch)) { return true; } try { bool isInMatch = GameStateWatcher.IsInMatch; bool flag = false; try { flag = EscapeMenuHandler.isEscMenu; } catch { } bool num = !isInMatch || flag; if (!num) { PerfGate.Hit("SkipMenuUpdateInMatch"); } return num; } catch { return true; } } } internal static class PlayerColorCosmetic { private class AnimState { public string sku; public Color baseColor; public Color teamBaseline; public bool baselineCaptured; public List tintedSkins = new List(); public List skinColorFields = new List(); public List originalSkinColors = new List(); public List tintedSprites = new List(); public List originalSpriteColors = new List(); public List tintedParticles = new List(); public List originalParticleColors = new List(); } private const string PROP_SKU = "cr_pcolor_sku"; private const string PROP_COLOR = "cr_pcolor_color"; private static readonly Dictionary animByActor = new Dictionary(); private static Coroutine animLoop; public static void PublishLocalProps() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown try { if (PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null) { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; Hashtable val = new Hashtable(); val[(object)"cr_pcolor_sku"] = cachedPlayerStats?.active_player_color_sku ?? ""; val[(object)"cr_pcolor_color"] = cachedPlayerStats?.active_player_color_hex ?? ""; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)string.Format("[PCOLOR] Published sku={0} color={1}", val[(object)"cr_pcolor_sku"], val[(object)"cr_pcolor_color"])); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] PublishLocalProps failed: " + ex.Message)); } } public static void OnMatchStart() { if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { return; } try { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedApplyAll()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] OnMatchStart error: " + ex.Message)); } } public static void OnRoundStart() { if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { return; } try { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedApplyAll()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] OnRoundStart error: " + ex.Message)); } } public static void OnMatchEnd() { foreach (KeyValuePair item in animByActor) { try { RevertOnState(item.Value); } catch { } } animByActor.Clear(); if (animLoop != null && (Object)(object)Plugin.Instance != (Object)null) { try { ((MonoBehaviour)Plugin.Instance).StopCoroutine(animLoop); } catch { } animLoop = null; } } public static void RevertPlayer(int actor) { if (animByActor.TryGetValue(actor, out var value)) { try { RevertOnState(value); } catch { } animByActor.Remove(actor); } } public static void OnShowPlayerColorsToggled() { if (Plugin.ShowPlayerColors == null) { return; } if (!Plugin.ShowPlayerColors.Value) { foreach (KeyValuePair item in animByActor) { try { RevertOnState(item.Value); } catch { } } animByActor.Clear(); if (animLoop != null && (Object)(object)Plugin.Instance != (Object)null) { try { ((MonoBehaviour)Plugin.Instance).StopCoroutine(animLoop); } catch { } animLoop = null; } try { PlayerManager instance = PlayerManager.instance; if (!((Object)(object)instance != (Object)null) || instance.players == null) { return; } foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { Component componentInChildren = ((Component)player).GetComponentInChildren(typeof(PlayerSkinHandler), true); if (!((Object)(object)componentInChildren == (Object)null)) { typeof(PlayerSkinHandler).GetMethod("Init", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(componentInChildren, null); } } } return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] re-bake on toggle-off failed: " + ex.Message)); return; } } if (GameStateWatcher.IsInMatch) { OnMatchStart(); } } private static void RevertOnState(AnimState st) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) if (st == null) { return; } for (int i = 0; i < st.tintedSkins.Count && i < st.originalSkinColors.Count; i++) { try { st.skinColorFields[i].SetValue(st.tintedSkins[i], st.originalSkinColors[i]); } catch { } } for (int j = 0; j < st.tintedSprites.Count && j < st.originalSpriteColors.Count; j++) { try { if ((Object)(object)st.tintedSprites[j] != (Object)null) { st.tintedSprites[j].color = st.originalSpriteColors[j]; } } catch { } } for (int k = 0; k < st.tintedParticles.Count && k < st.originalParticleColors.Count; k++) { try { ParticleSystem val = st.tintedParticles[k]; if (!((Object)(object)val == (Object)null)) { MainModule main = val.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(st.originalParticleColors[k]); } } catch { } } } public static void OnPlayerPropertiesChanged(Player target, Hashtable changed) { if (target != null && changed != null && (((Dictionary)(object)changed).ContainsKey((object)"cr_pcolor_sku") || ((Dictionary)(object)changed).ContainsKey((object)"cr_pcolor_color")) && (PhotonNetwork.LocalPlayer == null || target.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)) { ReapplyForActor(target.ActorNumber); } } public static void ReapplyForActor(int actor) { try { PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { return; } Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == actor) { val = val2; break; } } if (val == null || val.CustomProperties == null) { return; } Hashtable customProperties = val.CustomProperties; string text = ((!((Dictionary)(object)customProperties).ContainsKey((object)"cr_pcolor_sku")) ? "" : (customProperties[(object)"cr_pcolor_sku"]?.ToString() ?? "")); string colorHex = ((!((Dictionary)(object)customProperties).ContainsKey((object)"cr_pcolor_color")) ? "" : (customProperties[(object)"cr_pcolor_color"]?.ToString() ?? "")); if (string.IsNullOrEmpty(text)) { return; } foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.OwnerActorNr == actor) { ApplyToPlayer(((Component)player).transform, actor, text, colorHex); Plugin.Log.LogInfo((object)$"[PCOLOR] Re-applied for actor={actor} (late props) sku={text}"); break; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] ReapplyForActor failed: " + ex.Message)); } } private static IEnumerator DelayedApplyAll() { for (int i = 0; i < 30; i++) { yield return null; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { yield break; } animByActor.Clear(); foreach (Player player in instance.players) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } int ownerActorNr = component.OwnerActorNr; Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == ownerActorNr) { val = val2; break; } } string text = ""; string colorHex = ""; if (component.IsMine) { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; text = cachedPlayerStats?.active_player_color_sku ?? ""; colorHex = cachedPlayerStats?.active_player_color_hex ?? ""; } else if (val != null && val.CustomProperties != null) { Hashtable customProperties = val.CustomProperties; if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_pcolor_sku")) { text = customProperties[(object)"cr_pcolor_sku"]?.ToString() ?? ""; } if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_pcolor_color")) { colorHex = customProperties[(object)"cr_pcolor_color"]?.ToString() ?? ""; } } if (!string.IsNullOrEmpty(text)) { ApplyToPlayer(((Component)player).transform, ownerActorNr, text, colorHex); } } bool flag = false; foreach (AnimState value in animByActor.Values) { if (IsAnimatedSku(value.sku)) { flag = true; break; } } if (flag && animLoop == null) { animLoop = ((MonoBehaviour)Plugin.Instance).StartCoroutine(AnimTickLoop()); } } private static bool IsAnimatedSku(string sku) { if (!(sku == "pcolor_prismatic")) { return sku == "pcolor_chrome"; } return true; } private static void ApplyToPlayer(Transform playerRoot, int actor, string sku, string colorHex) { //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: 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) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Expected O, but got Unknown //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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) if ((Object)(object)playerRoot == (Object)null) { return; } if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { RevertPlayer(actor); return; } Color val = ParseHex(colorHex, Color.white); Color val2 = default(Color); bool flag = false; if (animByActor.TryGetValue(actor, out var value)) { val2 = value.teamBaseline; flag = value.baselineCaptured; RevertOnState(value); } AnimState animState = new AnimState { sku = sku, baseColor = val }; Color val3 = (Color)(flag ? val2 : new Color(1f, 0.5f, 0.2f)); if (!flag) { try { MonoBehaviour[] componentsInChildren = ((Component)playerRoot).GetComponentsInChildren(true); foreach (MonoBehaviour val4 in componentsInChildren) { if ((Object)(object)val4 == (Object)null) { continue; } Type type = ((object)val4).GetType(); if (type.Name != "PlayerSkin" && type.Name != "PlayerSkinHandler") { continue; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Color val5 = val3; float num = -1f; FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (fieldInfo.FieldType != typeof(Color)) { continue; } try { Color val6 = (Color)fieldInfo.GetValue(val4); float num2 = ColorSaturation(val6); if (num2 > num) { num = num2; val5 = val6; } } catch { } } if (num > 0.2f) { val3 = val5; break; } } } catch { } } animState.teamBaseline = val3; animState.baselineCaptured = true; try { MonoBehaviour[] componentsInChildren = ((Component)playerRoot).GetComponentsInChildren(true); foreach (MonoBehaviour val7 in componentsInChildren) { if ((Object)(object)val7 == (Object)null) { continue; } Type type2 = ((object)val7).GetType(); if (type2.Name != "PlayerSkin" && type2.Name != "PlayerSkinHandler") { continue; } FieldInfo[] array = type2.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in array) { if (fieldInfo2.FieldType != typeof(Color)) { continue; } Color val8; try { val8 = (Color)fieldInfo2.GetValue(val7); if (!IsTeamLike(val8, val3)) { continue; } } catch { continue; } fieldInfo2.SetValue(val7, val); animState.tintedSkins.Add((Component)(object)val7); animState.skinColorFields.Add(fieldInfo2); animState.originalSkinColors.Add(val8); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PCOLOR] PlayerSkin tint failed: " + ex.Message)); } try { ParticleSystem[] componentsInChildren2 = ((Component)playerRoot).GetComponentsInChildren(true); foreach (ParticleSystem val9 in componentsInChildren2) { if ((Object)(object)val9 == (Object)null) { continue; } MainModule main = val9.main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; Color color = ((MinMaxGradient)(ref startColor)).color; if (IsTeamLike(color, val3)) { ((MainModule)(ref main)).startColor = new MinMaxGradient(val); ColorOverLifetimeModule colorOverLifetime = val9.colorOverLifetime; if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled) { Gradient val10 = new Gradient(); val10.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(val, 0f), new GradientColorKey(val, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val10); } animState.tintedParticles.Add(val9); animState.originalParticleColors.Add(color); } } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[PCOLOR] ParticleSystem tint failed: " + ex2.Message)); } try { SpriteRenderer[] componentsInChildren3 = ((Component)playerRoot).GetComponentsInChildren(true); foreach (SpriteRenderer val11 in componentsInChildren3) { if (!((Object)(object)val11 == (Object)null)) { Color color2 = val11.color; if (!(color2.a < 0.3f) && IsTeamLike(color2, val3)) { val11.color = val; animState.tintedSprites.Add(val11); animState.originalSpriteColors.Add(color2); } } } } catch { } animByActor[actor] = animState; Plugin.Log.LogInfo((object)$"[PCOLOR] Applied actor={actor} sku={sku} hex={colorHex} baseline=({val3.r:F2},{val3.g:F2},{val3.b:F2}) skins={animState.tintedSkins.Count} particles={animState.tintedParticles.Count} sprites={animState.tintedSprites.Count}"); try { if (IsAnimatedSku(sku) && animLoop == null && (Object)(object)Plugin.Instance != (Object)null) { animLoop = ((MonoBehaviour)Plugin.Instance).StartCoroutine(AnimTickLoop()); Plugin.Log.LogInfo((object)$"[PCOLOR] Started anim tick loop (triggered by actor={actor} sku={sku})"); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[PCOLOR] anim loop start failed: " + ex3.Message)); } } private static bool IsTeamLike(Color c, Color baseline) { //IL_0000: 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_0015: 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_0036: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (c.a < 0.2f) { return false; } float num = ColorSaturation(c); float num2 = ColorSaturation(baseline); if (num < 0.18f) { return false; } if (Mathf.Max(new float[3] { c.r, c.g, c.b }) < 0.18f) { return false; } bool num3 = baseline.r > baseline.b; bool flag = c.r > c.b; if (num3 != flag && num2 > 0.2f) { return false; } float num4 = c.r - baseline.r; float num5 = c.g - baseline.g; float num6 = c.b - baseline.b; return Mathf.Sqrt(num4 * num4 + num5 * num5 + num6 * num6) < 0.55f; } private static float ColorSaturation(Color c) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(c.r, Mathf.Max(c.g, c.b)); float num2 = Mathf.Min(c.r, Mathf.Min(c.g, c.b)); if (!(num <= 0.001f)) { return (num - num2) / num; } return 0f; } private static IEnumerator AnimTickLoop() { WaitForSeconds wait = new WaitForSeconds(1f / 30f); while (animByActor.Count > 0) { float time = Time.time; foreach (KeyValuePair item in animByActor) { AnimState value = item.Value; if (!IsAnimatedSku(value.sku)) { continue; } Color val = value.baseColor; if (value.sku == "pcolor_prismatic") { val = Color.HSVToRGB(time * 0.25f % 1f, 0.85f, 1f); } else if (value.sku == "pcolor_chrome") { float num = (Mathf.Sin(time * 0.7f) + 1f) * 0.5f; val = Color.Lerp(new Color(0.78f, 0.78f, 0.86f), new Color(0.92f, 0.92f, 0.96f), num); } for (int i = 0; i < value.tintedSkins.Count; i++) { value.skinColorFields[i].SetValue(value.tintedSkins[i], val); } foreach (SpriteRenderer tintedSprite in value.tintedSprites) { if ((Object)(object)tintedSprite != (Object)null) { tintedSprite.color = val; } } foreach (ParticleSystem tintedParticle in value.tintedParticles) { if (!((Object)(object)tintedParticle == (Object)null)) { MainModule main = tintedParticle.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(val); } } } yield return wait; } animLoop = null; } private static Color ParseHex(string hex, Color fallback) { //IL_0080: 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) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(hex)) { return fallback; } if (hex.StartsWith("#")) { hex = hex.Substring(1); } if (hex.Length != 6) { return fallback; } try { int num = Convert.ToInt32(hex.Substring(0, 2), 16); int num2 = Convert.ToInt32(hex.Substring(2, 2), 16); int num3 = Convert.ToInt32(hex.Substring(4, 2), 16); return new Color((float)num / 255f, (float)num2 / 255f, (float)num3 / 255f, 1f); } catch { return fallback; } } } internal static class PlayerEffectCosmetic { private const string PROP_SKU = "cr_effect_sku"; private static readonly Dictionary auraByActor = new Dictionary(); private static readonly Dictionary skuByActor = new Dictionary(); private static readonly Dictionary _texCache = new Dictionary(); private static Material _baseParticleMat; private static bool _baseMatSearched; private const int TEX = 32; public static void PublishLocalProps() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown try { if (PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null) { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; Hashtable val = new Hashtable(); val[(object)"cr_effect_sku"] = cachedPlayerStats?.active_player_effect_sku ?? ""; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)string.Format("[EFFECT] Published sku={0}", val[(object)"cr_effect_sku"])); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] PublishLocalProps failed: " + ex.Message)); } } public static void OnMatchStart() { if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { return; } try { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedApplyAll()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] OnMatchStart error: " + ex.Message)); } } public static void OnRoundStart() { if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { return; } try { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedApplyAll()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] OnRoundStart error: " + ex.Message)); } } public static void OnMatchEnd() { foreach (KeyValuePair item in auraByActor) { try { if ((Object)(object)item.Value != (Object)null) { Object.Destroy((Object)(object)item.Value); } } catch { } } auraByActor.Clear(); skuByActor.Clear(); } public static void OnShowPlayerColorsToggled() { if (Plugin.ShowPlayerColors != null) { if (!Plugin.ShowPlayerColors.Value) { OnMatchEnd(); } else if (GameStateWatcher.IsInMatch) { OnMatchStart(); } } } public static void OnPlayerPropertiesChanged(Player target, Hashtable changed) { if (target == null || changed == null || !((Dictionary)(object)changed).ContainsKey((object)"cr_effect_sku") || (PhotonNetwork.LocalPlayer != null && target.ActorNumber == PhotonNetwork.LocalPlayer.ActorNumber)) { return; } try { ReapplyForActor(target.ActorNumber); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] propchange failed: " + ex.Message)); } } public static void ReapplyForActor(int actor) { if (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value) { return; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { return; } Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == actor) { val = val2; break; } } if (val == null || val.CustomProperties == null) { return; } string sku = ((!((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_effect_sku")) ? "" : (val.CustomProperties[(object)"cr_effect_sku"]?.ToString() ?? "")); foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.OwnerActorNr == actor) { ApplyToPlayer(((Component)player).transform, actor, sku); break; } } } } private static IEnumerator DelayedApplyAll() { for (int i = 0; i < 30; i++) { yield return null; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { yield break; } foreach (Player player in instance.players) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } int ownerActorNr = component.OwnerActorNr; string sku = ""; if (component.IsMine) { sku = ApiClient.CachedPlayerStats?.active_player_effect_sku ?? ""; } else { Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == ownerActorNr) { val = val2; break; } } if (val != null && val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_effect_sku")) { sku = val.CustomProperties[(object)"cr_effect_sku"]?.ToString() ?? ""; } } ApplyToPlayer(((Component)player).transform, ownerActorNr, sku); } } private static void ApplyToPlayer(Transform playerRoot, int actor, string sku) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)playerRoot == (Object)null) { return; } if (auraByActor.TryGetValue(actor, out var value)) { try { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } catch { } auraByActor.Remove(actor); } skuByActor.Remove(actor); if (string.IsNullOrEmpty(sku) || (Plugin.ShowPlayerColors != null && !Plugin.ShowPlayerColors.Value)) { return; } try { GameObject val = new GameObject("cr_effect"); val.transform.SetParent(playerRoot, false); val.transform.localPosition = Vector3.zero; ParticleSystem obj2 = val.AddComponent(); obj2.Stop(true, (ParticleSystemStopBehavior)0); ConfigureForSku(obj2, sku); ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Material val2 = BuildMaterialForSku(playerRoot, sku); if ((Object)(object)val2 != (Object)null) { ((Renderer)component).material = val2; } component.sortingFudge = -2f; component.renderMode = (ParticleSystemRenderMode)0; } obj2.Play(true); auraByActor[actor] = val; skuByActor[actor] = sku; Plugin.Log.LogInfo((object)$"[EFFECT] Applied actor={actor} sku={sku}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] ApplyToPlayer failed: " + ex.Message)); } } private static void ConfigureForSku(ParticleSystem ps, string sku) { //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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_06df: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_061c: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_067e: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06be: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0294: 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_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: 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_04f0: Unknown result type (might be due to invalid IL or missing references) MainModule main = ps.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)1; ((MainModule)(ref main)).maxParticles = 200; EmissionModule emission = ps.emission; ((EmissionModule)(ref emission)).enabled = true; ShapeModule shape = ps.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.7f; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.2f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.5f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(14f); VelocityOverLifetimeModule velocityOverLifetime = ps.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false; ColorOverLifetimeModule colorOverLifetime = ps.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = false; switch (sku) { case "effect_smoke": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.55f, 0.55f, 0.6f, 0.5f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2.2f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.6f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.9f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(10f); EnableRise(ps, 0.8f); FadeOut(ps, new Color(0.55f, 0.55f, 0.6f), new Color(0.7f, 0.7f, 0.75f)); break; case "effect_clover": { ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.25f, 0.72f, 0.32f, 1f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.8f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.9f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.4f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.35f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(12f); RotationOverLifetimeModule rotationOverLifetime = ps.rotationOverLifetime; ((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true; ((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(-3f, 3f); break; } case "effect_hearts": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.95f, 0.36f, 0.58f, 1f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.8f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.7f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.5f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(9f); EnableRise(ps, 1.1f); FadeOut(ps, new Color(0.95f, 0.36f, 0.58f), new Color(1f, 0.55f, 0.72f)); break; case "effect_bubbles": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.5f, 0.78f, 0.94f, 0.7f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.6f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.45f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(11f); EnableRise(ps, 1f); break; case "effect_embers": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.94f, 0.47f, 0.16f, 1f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1.1f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.25f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(22f); EnableRise(ps, 1.5f); FadeOut(ps, new Color(1f, 0.6f, 0.2f), new Color(0.7f, 0.15f, 0.05f)); break; case "effect_sparks": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.96f, 0.88f, 0.29f, 1f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.7f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(2.4f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.18f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(30f); ((ShapeModule)(ref shape)).radius = 0.4f; FadeOut(ps, new Color(1f, 0.95f, 0.5f), new Color(1f, 0.6f, 0.1f)); break; case "effect_rainbow": ((MainModule)(ref main)).startColor = new MinMaxGradient(Color.white); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.6f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.9f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.4f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(24f); EnableRise(ps, 0.7f); RainbowOverLifetime(ps); break; case "effect_void": ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.6f, 0.36f, 0.88f, 1f), new Color(0.2f, 0.78f, 0.9f, 1f)); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.5f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.45f); ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(20f); ((ShapeModule)(ref shape)).radius = 0.9f; OrbitSwirl(ps); FadeOut(ps, new Color(0.6f, 0.36f, 0.88f), new Color(0.12f, 0.05f, 0.2f)); break; default: ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 1f, 1f, 0.6f)); EnableRise(ps, 0.8f); break; } } private static void EnableRise(ParticleSystem ps, float speed) { //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_001a: Unknown result type (might be due to invalid IL or missing references) VelocityOverLifetimeModule velocityOverLifetime = ps.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(speed); } private static void OrbitSwirl(ParticleSystem ps) { //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_001e: Unknown result type (might be due to invalid IL or missing references) VelocityOverLifetimeModule velocityOverLifetime = ps.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)0; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalZ = new MinMaxCurve(1.4f); } private static void FadeOut(ParticleSystem ps, Color from, Color to) { //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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_001e: 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_0029: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) ColorOverLifetimeModule colorOverLifetime = ps.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(from, 0f), new GradientColorKey(to, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0.9f, 0.3f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val); } private static void RainbowOverLifetime(ParticleSystem ps) { //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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_002d: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) //IL_0086: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) ColorOverLifetimeModule colorOverLifetime = ps.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[6] { new GradientColorKey(new Color(1f, 0.2f, 0.2f), 0f), new GradientColorKey(new Color(1f, 0.8f, 0.2f), 0.2f), new GradientColorKey(new Color(0.3f, 1f, 0.3f), 0.4f), new GradientColorKey(new Color(0.2f, 0.8f, 1f), 0.6f), new GradientColorKey(new Color(0.5f, 0.3f, 1f), 0.8f), new GradientColorKey(new Color(1f, 0.3f, 0.9f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val); } private static Material BuildMaterialForSku(Transform playerRoot, string sku) { //IL_0014: 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 try { Material val = FindBaseParticleMaterial(playerRoot); Material val2 = ((!((Object)(object)val != (Object)null)) ? ((Material)null) : new Material(val)); if ((Object)(object)val2 == (Object)null) { Shader val3 = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val3 == (Object)null) { return null; } val2 = new Material(val3); } val2.mainTexture = (Texture)(object)GetTextureForSku(sku); return val2; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[EFFECT] material build failed: " + ex.Message)); return null; } } private static Material FindBaseParticleMaterial(Transform playerRoot) { if (_baseMatSearched && (Object)(object)_baseParticleMat != (Object)null) { return _baseParticleMat; } _baseMatSearched = true; try { if ((Object)(object)playerRoot != (Object)null) { ParticleSystemRenderer componentInChildren = ((Component)playerRoot).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null) { _baseParticleMat = ((Renderer)componentInChildren).sharedMaterial; return _baseParticleMat; } } ParticleSystemRenderer[] array = Object.FindObjectsOfType(); foreach (ParticleSystemRenderer val in array) { if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)val).sharedMaterial != (Object)null) { _baseParticleMat = ((Renderer)val).sharedMaterial; return _baseParticleMat; } } } catch { } return _baseParticleMat; } private static Texture2D GetTextureForSku(string sku) { string text = ((sku == "effect_hearts") ? "heart" : ((sku == "effect_clover") ? "clover" : "dot")); if (_texCache.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = ((text == "heart") ? BuildHeartTex() : ((text == "clover") ? BuildCloverTex() : BuildDotTex())); _texCache[text] = val; return val; } private static Texture2D NewTex() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new Texture2D(32, 32, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1, hideFlags = (HideFlags)61 }; } private static Texture2D BuildDotTex() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Texture2D val = NewTex(); Color[] array = (Color[])(object)new Color[1024]; float num = 15.5f; float num2 = num; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num3 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)) / num2; float num4 = Mathf.Clamp01(1f - num3); num4 *= num4; array[i * 32 + j] = new Color(1f, 1f, 1f, num4); } } val.SetPixels(array); val.Apply(); return val; } private static Texture2D BuildHeartTex() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) Texture2D val = NewTex(); Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num = (float)j / 31f * 2f - 1f; float num2 = 1f - (float)i / 31f * 2f; num *= 1.25f; num2 = num2 * 1.25f + 0.15f; float num3 = ((Mathf.Pow(num * num + num2 * num2 - 1f, 3f) - num * num * num2 * num2 * num2 <= 0f) ? 1f : 0f); array[i * 32 + j] = new Color(1f, 1f, 1f, num3); } } val.SetPixels(array); val.Apply(); return val; } private static Texture2D BuildCloverTex() { //IL_0031: 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_0042: 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_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_0064: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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) Texture2D val = NewTex(); Color[] array = (Color[])(object)new Color[1024]; float num = 15.5f; float num2 = 8.32f; float num3 = 6.4f; Vector2[] array2 = (Vector2[])(object)new Vector2[4] { new Vector2(num - num3, num), new Vector2(num + num3, num), new Vector2(num, num - num3), new Vector2(num, num + num3) }; for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num4 = 1f; Vector2[] array3 = array2; foreach (Vector2 val2 in array3) { float num5 = Mathf.Sqrt(((float)j - val2.x) * ((float)j - val2.x) + ((float)i - val2.y) * ((float)i - val2.y)) / num2; if (num5 < num4) { num4 = num5; } } float num6 = ((num4 <= 1f) ? Mathf.Clamp01(1.2f - num4) : 0f); array[i * 32 + j] = new Color(1f, 1f, 1f, num6); } } val.SetPixels(array); val.Apply(); return val; } } [BepInPlugin("com.competitiverounds.mod", "Competitive ROUNDS", "1.28.2")] [BepInProcess("Rounds.exe")] public class Plugin : BaseUnityPlugin { public const string ModId = "com.competitiverounds.mod"; public const string ModName = "Competitive ROUNDS"; public const string ModVersion = "1.28.2"; public const string RequiredGameVersion = "1.1.2"; internal static ManualLogSource Log; internal static CompetitiveRoundsBehaviour Instance; internal static Harmony HarmonyInstance; internal static ConfigEntry ApiBaseUrl; internal static ConfigEntry RankedEnabled; internal static ConfigEntry ShowNotifications; internal static ConfigEntry ShowFps; internal static ConfigEntry ShowRegionPing; internal static ConfigEntry ShowIngameChat; internal static ConfigEntry ShowTrails; internal static ConfigEntry ShowBlockDebug; internal static ConfigEntry ShowPlayerColors; internal static ConfigEntry ShowInputOverlay; internal static ConfigEntry PerfOptimizations; internal static ConfigEntry PerfStunPlayerNullGuard; internal static ConfigEntry PerfDespawnOffscreenBullets; internal static ConfigEntry PerfSwallowHitSoundNREs; internal static ConfigEntry PerfSwallowEdgeBounceNREs; internal static ConfigEntry PerfSkipMenuUpdateInMatch; internal static ConfigEntry PerfBulletHitParticleCap; internal static ConfigEntry PerfClampObjectPoolInit; internal static ConfigEntry PerfPauseCardPickParticles; internal static ConfigEntry TournamentTimezone; internal static ConfigEntry TournamentDateFormat; internal static ConfigEntry MutedChatNames; internal static ConfigEntry DataConsent; private static bool spawned = false; internal static bool modDisabled = false; private static string pendingRankedRoom = null; private static string pendingRankedRegion = null; private static bool pendingRoomLeaving = false; private static float pendingRoomLogTimer = 0f; private static int pending2v2Slot = -1; public static bool DataConsentGranted { get { if (DataConsent != null) { return DataConsent.Value == "granted"; } return false; } } public static bool DataConsentAsked { get { if (DataConsent != null) { return !string.IsNullOrEmpty(DataConsent.Value); } return false; } } public static string PendingRankedRoom => pendingRankedRoom; public static string PendingRankedRegion => pendingRankedRegion; public static int Pending2v2Slot => pending2v2Slot; public static void SetPendingRoom(string roomName, string region = null) { pendingRankedRoom = roomName; pendingRankedRegion = region; Log.LogInfo((object)("[QUEUE] Pending ranked room set: " + roomName + " (region: " + (region ?? "auto") + ")")); } public static void ClearPendingRoom() { pendingRankedRoom = null; pendingRankedRegion = null; pendingRoomLeaving = false; } public static void SetPending2v2Slot(int slot) { pending2v2Slot = slot; Log.LogInfo((object)$"[2v2] Pending slot set: {slot} (team={((slot < 2) ? 1 : 2)})"); } public static void ClearPending2v2Slot() { if (pending2v2Slot >= 0) { Log.LogInfo((object)"[2v2] Pending slot cleared"); } pending2v2Slot = -1; } private void Awake() { //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Expected O, but got Unknown //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Expected O, but got Unknown //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Expected O, but got Unknown //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04f0: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { Application.quitting += delegate { try { string text2 = CompetitiveUI.BepInExLogPathPublic(); string text3 = CompetitiveUI.BepInExLogPreviousPath(); if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(text3) && File.Exists(text2)) { File.Copy(text2, text3, overwrite: true); Log.LogInfo((object)("[BUG-REPORT] log snapshot saved: " + text3)); } } catch (Exception ex4) { Log.LogWarning((object)("[BUG-REPORT] quit-time log copy failed: " + ex4.Message)); } }; } catch (Exception ex) { Log.LogWarning((object)("[BUG-REPORT] quit hook bind failed: " + ex.Message)); } ApiBaseUrl = ((BaseUnityPlugin)this).Config.Bind("API", "BaseUrl", "http://competitive-rounds.duckdns.org:8443", "Base URL of the Competitive ROUNDS API server"); RankedEnabled = ((BaseUnityPlugin)this).Config.Bind("Ranked", "Enabled", true, "Whether ranked tracking is active"); ShowNotifications = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowNotifications", true, "Show in-game notifications for match results"); ShowFps = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowFps", true, "Show FPS counter in the top-left corner"); ShowRegionPing = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowRegionPing", true, "Show Photon ping and region alongside FPS when in a room"); ShowIngameChat = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowIngameChat", true, "Show the in-game chat overlay while outside the F5 menu"); ShowTrails = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowTrails", true, "Show cosmetic trails behind players during matches (including your own and opponents')"); ShowBlockDebug = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowBlockDebug", false, "Show the Block Debug overlay (top-right corner) during matches. Displays live counts of block activations vs successful absorbs, dedup drops, and per-hit timing ('too early' / 'too slow') so you can see why a block didn't land."); ShowPlayerColors = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowPlayerColors", true, "Render custom player body colors (purchased from the Body Color shop tab) — your own and other modded players'. Off = everyone falls back to the default orange/blue team colors."); ShowInputOverlay = ((BaseUnityPlugin)this).Config.Bind("UI", "ShowInputOverlay", false, "Show a bottom-left WASD + Space + L/R-click input visualizer during matches. Keys glow red when pressed."); PerfOptimizations = ((BaseUnityPlugin)this).Config.Bind("Performance", "Enabled", true, "Master switch for the v1.26.8 performance pass. Turn OFF to disable ALL patches below in one click. Individual patches below also have their own toggle for granular control."); PerfStunPlayerNullGuard = ((BaseUnityPlugin)this).Config.Bind("Performance", "StunPlayerNullGuard", true, "Null-guard StunPlayer.Go so a destroyed parent Player reference doesn't NRE every frame. Pure error suppression, no visual change."); PerfDespawnOffscreenBullets = ((BaseUnityPlugin)this).Config.Bind("Performance", "DespawnOffscreenBullets", true, "Host of each projectile despawns it once it flies outside the camera viewport (0.5s throttle). Without this, missed bullets keep ticking physics + RPC handlers indefinitely. Slight bandwidth savings, no gameplay difference."); PerfSwallowHitSoundNREs = ((BaseUnityPlugin)this).Config.Bind("Performance", "SwallowHitSoundNREs", true, "Catch the NullReferenceException that fires from RayHitBulletSound.DoHitEffect when its parent is destroyed mid-frame, and destroy the now-dead instance. Reduces BepInEx log spam, no visual change."); PerfSwallowEdgeBounceNREs = ((BaseUnityPlugin)this).Config.Bind("Performance", "SwallowEdgeBounceNREs", true, "Catch NullReferenceExceptions from ScreenEdgeBounce.DoHit and ScreenEdgeBounce.Update when a parent bullet was destroyed mid-frame. Reduces log spam, no visual change."); PerfSkipMenuUpdateInMatch = ((BaseUnityPlugin)this).Config.Bind("Performance", "SkipMenuUpdateInMatch", true, "Skip MenuControllerHandler.Update during an active match (menu controller input routing isn't needed during gameplay). Modest CPU win, no visible change."); PerfBulletHitParticleCap = ((BaseUnityPlugin)this).Config.Bind("Performance", "BulletHitParticleCap", true, "Cap bullet-hit particle explosions at 2 per frame. In a heavy firefight (BombsAway / Echo / Mayhem) a single frame can spawn 20+ explosion bursts — the cap drops GC and render cost noticeably. Missed bursts are silent: the damage already registered, you just don't see every visual."); PerfClampObjectPoolInit = ((BaseUnityPlugin)this).Config.Bind("Performance", "ClampObjectPoolInit", true, "Clamp ObjectPool initial-spawn to 4 instances while in a match (lazy growth instead of pre-allocating 30+ up-front). Reduces frame stutter when new pools are constructed mid-game."); PerfPauseCardPickParticles = ((BaseUnityPlugin)this).Config.Bind("Performance", "PauseCardPickParticles", true, "Pause the player-skin particle system while the between-round card picker is up (8-12s per pick). Particles freeze in place, no visual gap. Saves CPU on long card-pick stretches."); TournamentTimezone = ((BaseUnityPlugin)this).Config.Bind("Tournaments", "Timezone", "Local", "Timezone used to display tournament times. One of: Local, UTC, PT, MT, CT, ET, UK, CET, EET, MSK, JST, AEST, or a system timezone ID."); TournamentDateFormat = ((BaseUnityPlugin)this).Config.Bind("Tournaments", "DateFormat", "ISO", "Date/time display format: ISO (2026-04-24 14:30), US (Sat 04/24 2:30 PM), or EU (Sat 24/04 14:30). All formats emit ASCII-only so any locale renders cleanly."); MutedChatNames = ((BaseUnityPlugin)this).Config.Bind("UI", "MutedChatNames", "", "Pipe-delimited list of display names whose chat messages are hidden from your in-game chat log. Use /mute name and /unmute name in chat."); DataConsent = ((BaseUnityPlugin)this).Config.Bind("Privacy", "DataConsent", "", "Consent to report match data to the leaderboard. Values: \"\" (unset — you'll be asked at launch), \"granted\", or \"denied\"."); Log.LogInfo((object)("Competitive ROUNDS v1.28.2 initializing (consent=" + (string.IsNullOrEmpty(DataConsent.Value) ? "unset" : DataConsent.Value) + ")...")); string text = Application.version ?? ""; if (!text.StartsWith("1.1.2")) { Log.LogError((object)("[COMPAT] ROUNDS version " + text + " is NOT supported! This mod requires vanilla ROUNDS v1.1.2.")); Log.LogError((object)"[COMPAT] Please switch to the 'Default Public Version' in Steam → ROUNDS → Properties → Betas."); Log.LogError((object)"[COMPAT] Mod DISABLED."); return; } Log.LogInfo((object)("[COMPAT] Game version OK: " + text)); try { HarmonyInstance = new Harmony("com.competitiverounds.mod"); int num = 0; int num2 = 0; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { object[] customAttributes = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true); if (customAttributes != null && customAttributes.Length != 0) { try { HarmonyInstance.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex2) { num2++; Log.LogError((object)("[HARMONY] Failed to patch " + type.Name + ": " + ex2.Message)); } } } Log.LogInfo((object)$"[HARMONY] Patches applied: {num} ok, {num2} failed"); } catch (Exception ex3) { Log.LogWarning((object)("Harmony patching bootstrap failed (mod will work without it): " + ex3.Message)); } if (!spawned) { GameObject val = new GameObject("CompetitiveRounds_Persistent") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); spawned = true; Log.LogInfo((object)"Created persistent GameObject with DontDestroyOnLoad"); } Log.LogInfo((object)"Competitive ROUNDS v1.28.2 loaded!"); GameObject val2 = new GameObject("CR_QueueJoiner") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val2); val2.AddComponent(); GameObject val3 = new GameObject("CR_TaskbarFlash") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val3); val3.AddComponent(); } } public class QueueRoomJoiner : MonoBehaviour { private enum JoinState { Idle, LeavingRoom, Connecting, WaitingForRoom } private JoinState state; private float stateTimer; private bool joinInitiated; private string targetRoom; private string targetRegion; private void Awake() { Plugin.Log.LogInfo((object)"[QUEUE-JOINER] Awake, DontDestroyOnLoad set"); } private void Update() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) string pendingRankedRoom = Plugin.PendingRankedRoom; if (string.IsNullOrEmpty(pendingRankedRoom)) { joinInitiated = false; state = JoinState.Idle; stateTimer = 0f; return; } stateTimer += Time.deltaTime; if (state != JoinState.Idle && stateTimer > 30f) { Plugin.Log.LogWarning((object)$"[QUEUE-JOINER] Timed out waiting for room join (state={state}, target='{targetRoom}'), resetting all queue state"); Plugin.ClearPendingRoom(); joinInitiated = false; state = JoinState.Idle; stateTimer = 0f; targetRoom = null; targetRegion = null; try { GameStateWatcher.LeavingForRanked = false; } catch { } CompetitiveUI.ShowNotification("Failed to join ranked room", new Color(1f, 0.4f, 0.4f)); return; } switch (state) { case JoinState.Idle: if (joinInitiated) { break; } if (PhotonNetwork.InRoom) { Room currentRoom2 = PhotonNetwork.CurrentRoom; string text2 = ((currentRoom2 != null) ? currentRoom2.Name : null) ?? ""; if (text2 == pendingRankedRoom) { OnJoinedRankedRoom(text2); break; } targetRoom = pendingRankedRoom; targetRegion = Plugin.PendingRankedRegion; joinInitiated = true; GameStateWatcher.LeavingForRanked = true; PhotonNetwork.LeaveRoom(true); Plugin.Log.LogInfo((object)"[QUEUE-JOINER] Leaving current room before ranked join..."); state = JoinState.LeavingRoom; stateTimer = 0f; } else { targetRoom = pendingRankedRoom; targetRegion = Plugin.PendingRankedRegion; StartNCHConnect(); } break; case JoinState.LeavingRoom: if (!PhotonNetwork.InRoom) { Plugin.Log.LogInfo((object)"[QUEUE-JOINER] Left room, starting NCH connect..."); StartNCHConnect(); } break; case JoinState.Connecting: if (PhotonNetwork.InRoom) { Room currentRoom3 = PhotonNetwork.CurrentRoom; string text3 = ((currentRoom3 != null) ? currentRoom3.Name : null) ?? ""; if (text3 == targetRoom) { OnJoinedRankedRoom(text3); } } break; case JoinState.WaitingForRoom: if (PhotonNetwork.InRoom) { Room currentRoom = PhotonNetwork.CurrentRoom; string text = ((currentRoom != null) ? currentRoom.Name : null) ?? ""; if (text == targetRoom) { OnJoinedRankedRoom(text); } } break; } } private void StartNCHConnect() { joinInitiated = true; NetworkConnectionHandler instance = NetworkConnectionHandler.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogError((object)"[QUEUE-JOINER] NetworkConnectionHandler.instance is null!"); return; } try { if (PhotonNetwork.IsConnected) { PhotonNetwork.Disconnect(); Plugin.Log.LogInfo((object)"[QUEUE-JOINER] Disconnecting from Photon..."); } try { CharacterCreatorHandler instance2 = CharacterCreatorHandler.instance; if (instance2 != null) { instance2.CloseMenus(); } } catch { } try { MainMenuHandler instance3 = MainMenuHandler.instance; if (instance3 != null) { instance3.Close(); } } catch { } if (!string.IsNullOrEmpty(targetRegion)) { RegionSelector.region = targetRegion; Plugin.Log.LogInfo((object)("[QUEUE-JOINER] Set RegionSelector.region = " + targetRegion)); } instance.m_ForceRegion = true; Plugin.Log.LogInfo((object)"[QUEUE-JOINER] Set m_ForceRegion = true"); try { TimeHandler.instance.gameStartTime = 1f; } catch { } try { LoadingScreen instance4 = LoadingScreen.instance; if (instance4 != null) { instance4.StartLoading(false); } } catch { } string capturedRoom = targetRoom; ((MonoBehaviour)instance).StartCoroutine(instance.DoActionWhenConnected((Action)delegate { //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_004c: Expected O, but got Unknown //IL_004d: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown try { Plugin.Log.LogInfo((object)("[QUEUE-JOINER] Connected! JoinOrCreate: " + capturedRoom)); bool flag = capturedRoom != null && capturedRoom.StartsWith("team_"); Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"C2", (object)capturedRoom); Hashtable val2 = val; if (flag) { val2[(object)"cr_ff"] = true; } RoomOptions val3 = new RoomOptions(); val3.MaxPlayers = (byte)(flag ? 4 : 2); val3.IsOpen = true; val3.IsVisible = true; val3.CustomRoomProperties = val2; val3.CustomRoomPropertiesForLobby = new string[1] { "C2" }; RoomOptions val4 = val3; TypedLobby val5 = new TypedLobby("RoomCodeLobby", (LobbyType)2); PhotonNetwork.JoinOrCreateRoom(capturedRoom, val4, val5, (string[])null); } catch (Exception ex2) { Plugin.Log.LogError((object)("[QUEUE-JOINER] JoinOrCreate failed: " + ex2.Message)); } })); Plugin.Log.LogInfo((object)("[QUEUE-JOINER] Started NCH connection sequence for room: " + targetRoom)); state = JoinState.Connecting; stateTimer = 0f; } catch (Exception ex) { Plugin.Log.LogError((object)("[QUEUE-JOINER] StartNCHConnect failed: " + ex.Message)); joinInitiated = false; } } private void OnJoinedRankedRoom(string roomName) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)("[QUEUE] In ranked room: " + roomName + "!")); Plugin.ClearPendingRoom(); joinInitiated = false; state = JoinState.Idle; stateTimer = 0f; try { NetworkConnectionHandler instance = NetworkConnectionHandler.instance; if ((Object)(object)instance != (Object)null) { instance.m_ForceRegion = false; } } catch { } CompetitiveUI.ShowNotification("In ranked match room!", Color.green, 5f); CompetitiveRoundsBehaviour.HideMainMenu(); string localSteamId = GameStateWatcher.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { ApiClient.LeaveQueue(localSteamId); } if (Plugin.Pending2v2Slot >= 0) { ((MonoBehaviour)this).StartCoroutine(Auto2v2SpawnCoroutine()); } } private IEnumerator Auto2v2SpawnCoroutine() { float deadline = Time.realtimeSinceStartup + 12f; int tickLogCount = 0; while (Time.realtimeSinceStartup < deadline) { if (Plugin.Pending2v2Slot < 0) { Plugin.Log.LogInfo((object)"[2v2] Auto-spawn aborted — Pending2v2Slot cleared mid-wait"); yield break; } if (!PhotonNetwork.InRoom) { Plugin.Log.LogInfo((object)"[2v2] Auto-spawn aborted — not in Photon room mid-wait"); yield break; } PlayerAssigner instance = PlayerAssigner.instance; if ((Object)(object)instance != (Object)null && !instance.hasCreatedLocalPlayer) { InputDevice val = null; try { if (InputManager.ActiveDevices != null && InputManager.ActiveDevices.Count > 0) { val = InputManager.ActiveDevices[0]; } } catch { } Plugin.Log.LogInfo((object)string.Format("[2v2] Auto-spawning local player (slot={0}, device={1})", Plugin.Pending2v2Slot, (val != null) ? "keyboard" : "null")); bool flag = false; try { instance.CreatePlayer(val, false); flag = true; } catch (Exception ex) { Plugin.Log.LogError((object)("[2v2] Auto-spawn CreatePlayer failed: " + ex.Message)); } if (flag) { try { string localSteamId = MatchTracker.LocalSteamId; string activeTeamSeriesId = ApiClient.ActiveTeamSeriesId; if (!string.IsNullOrEmpty(localSteamId) && !string.IsNullOrEmpty(activeTeamSeriesId)) { ApiClient.SendTeamSpawnConfirm(activeTeamSeriesId, localSteamId); } yield break; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[2v2] spawn-confirm send error: " + ex2.Message)); yield break; } } } else if (tickLogCount < 6) { string arg = (((Object)(object)instance == (Object)null) ? "PlayerAssigner.instance == null" : (instance.hasCreatedLocalPlayer ? "local player already exists" : "?")); Plugin.Log.LogInfo((object)$"[2v2] Auto-spawn waiting: {arg} (tick {tickLogCount})"); tickLogCount++; } yield return (object)new WaitForSeconds(0.5f); } if ((Object)(object)PlayerAssigner.instance == (Object)null || !PlayerAssigner.instance.hasCreatedLocalPlayer) { Plugin.Log.LogWarning((object)"[2v2] Auto-spawn timed out — PlayerAssigner never initialized or local player never spawned"); } } } public class CompetitiveRoundsBehaviour : MonoBehaviour { private bool initialized; private float startupTimer; private bool startupComplete; private static bool _initSteamRanFired; private void Awake() { ((Object)this).hideFlags = (HideFlags)61; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Plugin.Log.LogInfo((object)"[PERSIST] Behaviour Awake, DontDestroyOnLoad set"); } private void Update() { if (Plugin.modDisabled) { return; } try { MainMenuInjector.TryInject(); } catch { } if (!startupComplete) { startupTimer += Time.deltaTime; if (startupTimer >= 3f) { startupComplete = true; DoInitialize(); } } else { if (!initialized) { return; } try { CompetitiveUI.Tick(); } catch { } if (Input.GetKeyDown((KeyCode)286)) { CompetitiveUI.ToggleOverlay(); } try { GameStateWatcher.TickFrame(); } catch { } try { GameStateWatcher.Poll(); } catch (Exception ex) { Plugin.Log.LogError((object)("Poll error: " + ex.Message)); } if (ApiClient.IsQueuePolling) { try { ApiClient.UpdateQueuePoll(GameStateWatcher.LocalSteamId); } catch { } } if (ApiClient.IsTeamQueuePolling) { try { ApiClient.UpdateTeamQueuePoll(GameStateWatcher.LocalSteamId); } catch { } } if (NativeUI.IsOpen) { try { ApiClient.UpdateQueueCount(); } catch { } try { ApiClient.UpdateTeamQueueCount(); } catch { } try { NativeUI.MaybeRefreshLiveSeries(); } catch { } } } } private void DoInitialize() { Plugin.Log.LogInfo((object)"[PERSIST] Delayed initialization starting..."); try { Dictionary pluginInfos = Chainloader.PluginInfos; if (pluginInfos != null && pluginInfos.Count > 1) { List list = new List(); foreach (KeyValuePair item in pluginInfos) { if (item.Key != "com.competitiverounds.mod") { list.Add(item.Value.Metadata.Name + " (" + item.Key + ")"); } } if (list.Count > 0) { Plugin.Log.LogError((object)$"[COMPAT] {list.Count} other mod(s) detected! This mod requires vanilla ROUNDS with no other plugins."); foreach (string item2 in list) { Plugin.Log.LogError((object)("[COMPAT] - " + item2)); } Plugin.Log.LogError((object)"[COMPAT] Mod DISABLED to ensure competitive integrity."); Plugin.modDisabled = true; return; } } Plugin.Log.LogInfo((object)"[COMPAT] No other mods detected — OK"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[COMPAT] Could not check other mods: " + ex.Message)); } ApiClient.Initialize(Plugin.ApiBaseUrl.Value); GameStateWatcher.Initialize(); CardImageLoader.Initialize(); CompetitiveUI.CacheRaycasters(); initialized = true; try { UIFactory.InitTypes(); UIFactory.InitFont(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[UI] Type init deferred: " + ex2.Message)); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(InitWhenSteamReady()); ChatClient.OnMessage = NativeUI.OnChatMessage; if (Plugin.DataConsentGranted) { ChatClient.Connect(); } try { NametagFontRenderer.LogAvailableTmpFonts(); } catch { } Plugin.Log.LogInfo((object)"[PERSIST] All systems active! Press F5 for overlay."); } private IEnumerator InitWhenSteamReady() { float deadline = Time.unscaledTime + 30f; int tries = 0; while (!_initSteamRanFired && Time.unscaledTime < deadline) { tries++; string localSteamId = GameStateWatcher.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { _initSteamRanFired = true; Plugin.Log.LogInfo((object)$"[INIT] Steam resolved on try {tries} (sid={localSteamId}); firing one-shot init"); try { ApiClient.ToggleRanked(localSteamId, Plugin.RankedEnabled.Value); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[INIT] ToggleRanked failed: " + ex.Message)); } try { ApiClient.FetchPlayerStats(localSteamId); } catch { } try { ApiClient.FetchMatchHistory(localSteamId); } catch { } try { ApiClient.FetchBlockedPlayers(localSteamId); } catch { } try { ApiClient.CheckAdminStatus(localSteamId); yield break; } catch { yield break; } } yield return (object)new WaitForSeconds(0.5f); } if (!_initSteamRanFired) { Plugin.Log.LogWarning((object)$"[INIT] Steam ID never resolved after {tries} tries / 30s. Server-side ranked_enabled may be stale until next launch."); } } private void OnGUI() { if (initialized && !Plugin.modDisabled) { CompetitiveUI.DrawUI(); } } internal static void HideMainMenu() { //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) try { for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); Plugin.Log.LogInfo((object)$"[QUEUE] Loaded scene: {((Scene)(ref sceneAt)).name} (index {((Scene)(ref sceneAt)).buildIndex})"); } MainMenuHandler val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); Plugin.Log.LogInfo((object)"[QUEUE] Disabled MainMenuHandler"); } ListMenu[] array = Object.FindObjectsOfType(); ListMenu[] array2 = array; for (int j = 0; j < array2.Length; j++) { ((Component)array2[j]).gameObject.SetActive(false); } if (array.Length != 0) { Plugin.Log.LogInfo((object)$"[QUEUE] Disabled {array.Length} ListMenu objects"); } CharacterSelectionInstance val2 = Object.FindObjectOfType(); if ((Object)(object)val2 != (Object)null) { ((Component)((Component)val2).transform.root).gameObject.SetActive(false); Plugin.Log.LogInfo((object)"[QUEUE] Disabled character selection"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[QUEUE] HideMainMenu error: " + ex.Message)); } } private void OnDestroy() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002c: Expected O, but got Unknown Plugin.Log.LogWarning((object)"[PERSIST] Destroyed! Attempting respawn..."); MainMenuInjector.Reset(); try { GameObject val = new GameObject("CompetitiveRounds_Respawn") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); Plugin.Instance = val.AddComponent(); Plugin.Log.LogInfo((object)"[PERSIST] Respawned with DontDestroyOnLoad!"); } catch (Exception ex) { Plugin.Log.LogError((object)("[PERSIST] Respawn failed: " + ex.Message)); } } } [HarmonyPatch(typeof(GM_ArmsRace), "Awake")] internal class GMArmsRaceAwakePatch { private static void Postfix(GM_ArmsRace __instance) { Plugin.Log.LogInfo((object)"[HARMONY] GM_ArmsRace.Awake fired! Harmony is WORKING!"); CardRarityLookup.ScanAll(); if (CardRarityLookup.Count == 0) { Plugin.Log.LogInfo((object)"[HARMONY] No cards found yet — will retry on match start"); } } } [HarmonyPatch(typeof(GM_ArmsRace), "OnEnable")] internal class GMArmsRaceOnEnable_4Player_Patch { private static void Postfix(GM_ArmsRace __instance) { try { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).ContainsKey((object)"cr_ff")) { __instance.playersNeededToStart = 4; if ((Object)(object)PlayerAssigner.instance != (Object)null) { PlayerAssigner.instance.maxPlayers = 4; } Plugin.Log.LogInfo((object)"[2v2] Forced playersNeededToStart=4 (cr_ff room detected)"); } } catch (Exception ex) { Plugin.Log.LogError((object)("[2v2] OnEnable patch error: " + ex.Message)); } } } [HarmonyPatch(typeof(CharacterSelectionMenu), "PlayerJoined")] internal class CharacterSelectionMenu_PlayerJoined_2v2_Patch { private static bool Prefix(CharacterSelectionMenu __instance) { try { if ((Object)(object)__instance == (Object)null || ((Component)__instance).transform.childCount == 0) { return true; } int num = (((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null) ? (PlayerManager.instance.players.Count - 1) : (-1)); Transform child = ((Component)__instance).transform.GetChild(0); if (num < 0 || num >= child.childCount) { Plugin.Log.LogInfo((object)$"[2v2] CharacterSelectionMenu skipped (slot={num} >= children={child.childCount})"); return false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] CharacterSelectionMenu prefix error: " + ex.Message)); } return true; } } [HarmonyPatch(typeof(PlayerAssigner), "CreatePlayer")] internal class PlayerAssigner_CreatePlayer_2v2_Patch { private static float _lastSpawnGuardLog = -999f; private static bool Prefix(PlayerAssigner __instance, InputDevice inputDevice, bool isAI) { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown if (!PhotonNetwork.OfflineMode && (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)) { try { if (Time.unscaledTime - _lastSpawnGuardLog > 2f) { _lastSpawnGuardLog = Time.unscaledTime; Plugin.Log.LogWarning((object)("[SPAWN-GUARD] CreatePlayer suppressed — client not in a room " + $"(state={PhotonNetwork.NetworkClientState}). Will retry when connected.")); } } catch { } return false; } if (Plugin.Pending2v2Slot < 0) { return true; } if (PhotonNetwork.OfflineMode) { return true; } if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return true; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null || !((Dictionary)(object)customProperties).ContainsKey((object)"cr_ff")) { return true; } if (__instance.hasCreatedLocalPlayer) { return false; } int pending2v2Slot = Plugin.Pending2v2Slot; int num = pending2v2Slot / 2; int num2 = pending2v2Slot; try { typeof(PlayerAssigner).GetField("m_playerId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(__instance, pending2v2Slot); __instance.hasCreatedLocalPlayer = true; Hashtable val = new Hashtable(); val[(object)Player.VAR_PLAYERID] = num2; val[(object)Player.VAR_TEAMID] = num; try { string localSteamId = MatchTracker.LocalSteamId; if (!string.IsNullOrEmpty(localSteamId) && localSteamId != "unknown") { val[(object)"u_id"] = localSteamId; } } catch { } PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Vector3 val2 = Vector3.up * 100f; CharacterData component = PhotonNetwork.Instantiate(((Object)__instance.playerPrefab).name, val2, Quaternion.identity, (byte)0, (object[])null).GetComponent(); component.input.inputType = (InputType)1; component.playerActions = PlayerActions.CreateWithKeyboardBindings(); ((PlayerActionSet)component.playerActions).Device = inputDevice; __instance.players.Add(component); int num3 = num2; PlayerManager.RegisterPlayer(component.player, num3); component.player.AssignPlayerID(num2); component.player.AssignTeamID(num); try { Type typeFromHandle = typeof(Player); (string, object)[] array = new(string, object)[3] { ("AssignPlatform", null), ("AssignUserID", null), ("AssignUnityID", null) }; for (int i = 0; i < array.Length; i++) { (string, object) tuple = array[i]; string item = tuple.Item1; object item2 = tuple.Item2; MethodInfo method = typeFromHandle.GetMethod(item); if (method != null && item2 != null) { method.Invoke(component.player, new object[1] { item2 }); } } } catch { } try { PlayerSkinHandler componentInChildren = ((Component)component).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { for (int num4 = ((Component)componentInChildren).transform.childCount - 1; num4 >= 0; num4--) { Transform child = ((Component)componentInChildren).transform.GetChild(num4); if ((Object)(object)child != (Object)null) { Object.Destroy((Object)(object)((Component)child).gameObject); } } componentInChildren.inited = false; typeof(PlayerSkinHandler).GetMethod("Init", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(componentInChildren, null); Plugin.Log.LogInfo((object)$"[2v2] Re-baked local PlayerSkin for slot={pending2v2Slot} (post-AssignPlayerID)"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] PlayerSkin re-bake failed: " + ex.Message)); } Plugin.Log.LogInfo((object)$"[2v2] CreatePlayer override: slot={pending2v2Slot} team={num} pid={num2}"); return false; } catch (Exception ex2) { Plugin.Log.LogError((object)("[2v2] CreatePlayer override failed: " + ex2.Message + " — falling back to vanilla")); return true; } } } internal static class Diag2v2 { public static bool IsActive() { if (Plugin.Pending2v2Slot >= 0) { return true; } try { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).ContainsKey((object)"cr_ff")) { return true; } } } catch { } return false; } public static string ShortStack() { try { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); StringBuilder stringBuilder = new StringBuilder(); int num = Math.Min(stackTrace.FrameCount, 8); for (int i = 0; i < num; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase == null)) { stringBuilder.Append(methodBase.DeclaringType?.Name ?? "?").Append('.').Append(methodBase.Name); if (i < num - 1) { stringBuilder.Append(" <- "); } } } return stringBuilder.ToString(); } catch { return ""; } } public static string DescribeRoom() { try { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return "(not in room)"; } Room currentRoom = PhotonNetwork.CurrentRoom; int playerCount = currentRoom.PlayerCount; int maxPlayers = currentRoom.MaxPlayers; return $"room={currentRoom.Name} players={playerCount}/{maxPlayers}"; } catch { return "(room-describe failed)"; } } } public class Cr2v2DiagCallbacks : MonoBehaviour, IInRoomCallbacks, IConnectionCallbacks, IMatchmakingCallbacks { private void OnEnable() { try { PhotonNetwork.AddCallbackTarget((object)this); } catch { } } private void OnDisable() { try { PhotonNetwork.RemoveCallbackTarget((object)this); } catch { } } public void OnPlayerEnteredRoom(Player p) { try { if (CompetitiveRoomDetect.IsCompetitiveRoom()) { FacePublisher.PublishLocal(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POPUP] PlayerEntered face republish: " + ex.Message)); } if (!Diag2v2.IsActive()) { return; } try { int result = -1; int result2 = -1; if (p.CustomProperties != null) { if (((Dictionary)(object)p.CustomProperties).ContainsKey((object)"p_id")) { int.TryParse(p.CustomProperties[(object)"p_id"].ToString(), out result); } if (((Dictionary)(object)p.CustomProperties).ContainsKey((object)"t_id")) { int.TryParse(p.CustomProperties[(object)"t_id"].ToString(), out result2); } } Plugin.Log.LogInfo((object)$"[2v2-DIAG] PlayerEntered: nick='{p.NickName}' actor={p.ActorNumber} p_id={result} t_id={result2} {Diag2v2.DescribeRoom()}"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[2v2-DIAG] PlayerEntered log error: " + ex2.Message)); } } public void OnPlayerLeftRoom(Player p) { if (!Diag2v2.IsActive()) { return; } try { Plugin.Log.LogInfo((object)$"[2v2-DIAG] PlayerLeft: nick='{((p != null) ? p.NickName : null)}' actor={((p != null) ? new int?(p.ActorNumber) : ((int?)null))} {Diag2v2.DescribeRoom()}"); } catch { } try { if (p == null) { return; } string activeTeamSeriesId = ApiClient.ActiveTeamSeriesId; if (string.IsNullOrEmpty(activeTeamSeriesId)) { return; } if (!GameStateWatcher.IsInMatch) { Plugin.Log.LogInfo((object)("[2v2-DC] suppressed during assembly phase " + $"(IsInMatch=false), leaver='{((p != null) ? p.NickName : null)}' actor={((p != null) ? new int?(p.ActorNumber) : ((int?)null))}")); return; } string text = null; if (p.CustomProperties != null) { if (((Dictionary)(object)p.CustomProperties).ContainsKey((object)"u_id")) { text = p.CustomProperties[(object)"u_id"]?.ToString(); } if (string.IsNullOrEmpty(text) && ((Dictionary)(object)p.CustomProperties).ContainsKey((object)"unity_id")) { text = p.CustomProperties[(object)"unity_id"]?.ToString(); } } if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(p.UserId)) { text = p.UserId; } if (string.IsNullOrEmpty(text) || text.StartsWith("photon_")) { return; } string localSteamId = MatchTracker.LocalSteamId; if (string.IsNullOrEmpty(localSteamId) || !long.TryParse(localSteamId, out var result)) { return; } bool flag = true; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (val != null && val.ActorNumber != p.ActorNumber && !val.IsLocal) { string text2 = null; if (val.CustomProperties != null && ((Dictionary)(object)val.CustomProperties).ContainsKey((object)"u_id")) { text2 = val.CustomProperties[(object)"u_id"]?.ToString(); } if (!string.IsNullOrEmpty(text2) && !text2.StartsWith("photon_") && long.TryParse(text2, out var result2) && result2 < result) { flag = false; break; } } } if (flag) { int lastP1Points = GameStateWatcher.LastP1Points; int lastP2Points = GameStateWatcher.LastP2Points; ApiClient.ReportTeamSeriesDc(activeTeamSeriesId, localSteamId, text, lastP1Points, lastP2Points); Plugin.Log.LogInfo((object)$"[2v2-DC] reporter={localSteamId} dc={text} series={activeTeamSeriesId} pts={lastP1Points}/{lastP2Points}"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2-DC] report error: " + ex.Message)); } } public void OnPlayerPropertiesUpdate(Player target, Hashtable changedProps) { } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } public void OnMasterClientSwitched(Player newMasterClient) { if (!Diag2v2.IsActive()) { return; } try { Plugin.Log.LogInfo((object)$"[2v2-DIAG] MasterClientSwitched: new='{((newMasterClient != null) ? newMasterClient.NickName : null)}' actor={((newMasterClient != null) ? new int?(newMasterClient.ActorNumber) : ((int?)null))}"); } catch { } } public void OnConnected() { } public void OnConnectedToMaster() { } public void OnDisconnected(DisconnectCause cause) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Pending2v2Slot < 0) { return; } try { Plugin.Log.LogWarning((object)$"[2v2-DIAG] Disconnected: cause={cause} stack={Diag2v2.ShortStack()}"); } catch { } } public void OnRegionListReceived(RegionHandler regionHandler) { } public void OnCustomAuthenticationResponse(Dictionary data) { } public void OnCustomAuthenticationFailed(string debugMessage) { } public void OnFriendListUpdate(List friendList) { } public void OnCreatedRoom() { } public void OnCreateRoomFailed(short returnCode, string message) { if (Plugin.Pending2v2Slot >= 0) { Plugin.Log.LogWarning((object)$"[2v2-DIAG] CreateRoomFailed: code={returnCode} msg={message}"); } } public void OnJoinedRoom() { if (CompetitiveRoomDetect.IsCompetitiveRoom()) { try { FacePublisher.PublishLocal(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POPUP] Face publish hook error: " + ex.Message)); } if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(RepeatedCompetitiveCosmeticReapply()); } } if (!Diag2v2.IsActive()) { return; } try { ManualLogSource log = Plugin.Log; string arg = Diag2v2.DescribeRoom(); Player localPlayer = PhotonNetwork.LocalPlayer; log.LogInfo((object)$"[2v2-DIAG] JoinedRoom: {arg} masterClient={localPlayer != null && localPlayer.IsMasterClient}"); } catch { } try { GM_ArmsRace val = Object.FindObjectOfType(true); if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeInHierarchy) { ((Component)val).gameObject.SetActive(true); Plugin.Log.LogInfo((object)"[2v2] Force-activated GM_ArmsRace.gameObject (vanilla path missed late joiner)"); } } catch (Exception ex2) { Plugin.Log.LogError((object)("[2v2] GM_ArmsRace activate failed: " + ex2.Message)); } try { LoadingScreen instance = LoadingScreen.instance; if ((Object)(object)instance != (Object)null) { try { GeneralParticleSystem searchingSystem = instance.searchingSystem; if (searchingSystem != null) { searchingSystem.Stop(); } } catch { } try { GeneralParticleSystem matchFoundSystem = instance.matchFoundSystem; if (matchFoundSystem != null) { matchFoundSystem.Stop(); } } catch { } if (instance.playerNamesSystem != null) { GeneralParticleSystem[] playerNamesSystem = instance.playerNamesSystem; foreach (GeneralParticleSystem val2 in playerNamesSystem) { try { if (val2 != null) { val2.Stop(); } } catch { } } } try { if ((Object)(object)instance.m_cancelText != (Object)null) { instance.m_cancelText.SetActive(false); } } catch { } typeof(LoadingScreen).GetField("m_isLoading", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(instance, false); Plugin.Log.LogInfo((object)"[2v2] Cleared LoadingScreen searching overlay (late joiner)"); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[2v2] LoadingScreen clear failed: " + ex3.Message)); } if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Force2v2StartGameWhenReady()); ((MonoBehaviour)Plugin.Instance).StartCoroutine(Setup4PlayerCardBarsWhenReady()); ((MonoBehaviour)Plugin.Instance).StartCoroutine(PollAssemblyStateLoop()); } } private static IEnumerator PollAssemblyStateLoop() { yield return (object)new WaitForSeconds(3f); float deadline = Time.realtimeSinceStartup + 22f; while (Time.realtimeSinceStartup < deadline) { if (Plugin.Pending2v2Slot < 0 || !PhotonNetwork.InRoom) { break; } string activeTeamSeriesId = ApiClient.ActiveTeamSeriesId; if (string.IsNullOrEmpty(activeTeamSeriesId)) { break; } bool gotResponse = false; ApiClient.PollTeamSeriesState(activeTeamSeriesId, delegate(string status, string reason, int conf) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) gotResponse = true; if (status == "canceled" && reason == "assembly_timeout") { Plugin.Log.LogWarning((object)$"[2v2] Server canceled series (assembly_timeout, {conf}/4 confirmed) — leaving room"); try { CompetitiveUI.ShowNotification($"Match couldn't assemble — only {conf} of 4 connected. Returning to menu.", new Color(1f, 0.55f, 0.2f), 6f); } catch { } try { Plugin.ClearPending2v2Slot(); if (PhotonNetwork.InRoom) { PhotonNetwork.LeaveRoom(true); } return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] LeaveRoom on assembly cancel failed: " + ex.Message)); return; } } if (status == "active") { _ = 4; } }); float waitUntil = Time.realtimeSinceStartup + 1.5f; while (!gotResponse && Time.realtimeSinceStartup < waitUntil) { yield return null; } if (ApiClient.LastSeriesStateStatus == "canceled" || (ApiClient.LastSeriesStateStatus == "active" && ApiClient.LastSeriesStateConfirmations >= 4)) { break; } yield return (object)new WaitForSeconds(2f); } } private static IEnumerator RepeatedCompetitiveCosmeticReapply() { yield return (object)new WaitForSeconds(2f); float deadline = Time.realtimeSinceStartup + 12f; while (Time.realtimeSinceStartup < deadline && CompetitiveRoomDetect.IsCompetitiveRoom() && PhotonNetwork.InRoom) { try { Player[] playerList = PhotonNetwork.PlayerList; if (playerList != null) { Player[] array = playerList; foreach (Player val in array) { if (val != null && (PhotonNetwork.LocalPlayer == null || val.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)) { PlayerColorCosmetic.ReapplyForActor(val.ActorNumber); TrailCosmetic.ReattachForActor(val.ActorNumber); try { PlayerEffectCosmetic.ReapplyForActor(val.ActorNumber); } catch { } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POPUP] cosmetic reapply tick error: " + ex.Message)); } yield return (object)new WaitForSeconds(2f); } } private static IEnumerator Setup4PlayerCardBarsWhenReady() { float deadline = Time.realtimeSinceStartup + 15f; while (Time.realtimeSinceStartup < deadline) { if (Plugin.Pending2v2Slot < 0 || !PhotonNetwork.InRoom) { yield break; } CardBarHandler instance = CardBarHandler.instance; if ((Object)(object)instance == (Object)null || instance.cardBars == null || instance.cardBars.Length < 2) { yield return (object)new WaitForSeconds(0.5f); continue; } if (instance.cardBars.Length >= 4) { Plugin.Log.LogInfo((object)$"[2v2] CardBars already {instance.cardBars.Length} — no extension needed"); yield break; } try { CardBar[] componentsInChildren = ((Component)instance).GetComponentsInChildren(true); if (componentsInChildren != null && componentsInChildren.Length >= 4) { CardBar[] array = componentsInChildren; foreach (CardBar val in array) { if ((Object)(object)val != (Object)null && !((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } instance.cardBars = componentsInChildren; Plugin.Log.LogInfo((object)$"[2v2] CardBars: found {componentsInChildren.Length} in tree (incl. inactive), activated all"); yield break; } CardBar val2 = instance.cardBars[0]; CardBar val3 = instance.cardBars[1]; if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"[2v2] CardBars: original bar0/bar1 is null, skipping extension"); yield break; } GameObject val4 = Object.Instantiate(((Component)val2).gameObject, ((Component)val2).transform.parent); GameObject obj = Object.Instantiate(((Component)val3).gameObject, ((Component)val3).transform.parent); ((Object)val4).name = ((Object)((Component)val2).gameObject).name + "_2v2_p1"; ((Object)obj).name = ((Object)((Component)val3).gameObject).name + "_2v2_p3"; OffsetBar(val4.transform, new Vector2(0f, -180f)); OffsetBar(obj.transform, new Vector2(0f, -180f)); CardBar component = val4.GetComponent(); CardBar component2 = obj.GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Plugin.Log.LogWarning((object)"[2v2] CardBars: clone missing CardBar component"); yield break; } instance.cardBars = (CardBar[])(object)new CardBar[4] { val2, component, val3, component2 }; Plugin.Log.LogInfo((object)"[2v2] CardBars: cloned to 4 entries [team0_p0, team0_p1, team1_p2, team1_p3]"); yield break; } catch (Exception ex) { Plugin.Log.LogError((object)("[2v2] CardBar extension failed: " + ex.Message)); yield break; } } Plugin.Log.LogWarning((object)"[2v2] CardBar setup timed out — CardBarHandler.instance never appeared"); } private static void OffsetBar(Transform t, Vector2 offset) { //IL_0025: 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_003b: 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_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_0018: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null); if ((Object)(object)val != (Object)null) { val.anchoredPosition += offset; } else { t.localPosition += new Vector3(offset.x, offset.y, 0f); } } private static IEnumerator Force2v2StartGameWhenReady() { float deadline = Time.realtimeSinceStartup + 30f; while (Time.realtimeSinceStartup < deadline) { if (Plugin.Pending2v2Slot < 0 || !PhotonNetwork.InRoom) { yield break; } try { if ((Object)(object)GameManager.instance != (Object)null && GameManager.instance.isPlaying) { yield break; } } catch { } GM_ArmsRace instance = GM_ArmsRace.instance; if ((Object)(object)instance != (Object)null && ((Component)instance).gameObject.activeInHierarchy && (Object)(object)PlayerManager.instance != (Object)null) { int num = 0; foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player != (Object)null) { num++; } } if (num >= 4) { Plugin.Log.LogInfo((object)$"[2v2] Force-invoking GM_ArmsRace.StartGame (counted={num})"); try { instance.StartGame(); yield break; } catch (Exception ex) { Plugin.Log.LogError((object)("[2v2] StartGame invoke failed: " + ex.Message)); yield break; } } } yield return (object)new WaitForSeconds(0.5f); } Plugin.Log.LogWarning((object)"[2v2] Force-StartGame timed out — never reached 4 spawned players"); } public void OnJoinRoomFailed(short returnCode, string message) { if (Plugin.Pending2v2Slot >= 0) { Plugin.Log.LogWarning((object)$"[2v2-DIAG] JoinRoomFailed: code={returnCode} msg={message}"); } } public void OnJoinRandomFailed(short returnCode, string message) { } public void OnLeftRoom() { if (Plugin.Pending2v2Slot < 0) { return; } try { Plugin.Log.LogWarning((object)("[2v2-DIAG] LeftRoom (Photon callback) stack=" + Diag2v2.ShortStack())); } catch { } } } [HarmonyPatch(typeof(NetworkConnectionHandler), "OnJoinedRoom")] internal class NetworkConnectionHandler_OnJoinedRoom_RestyleNick_Patch { private static void Postfix() { try { if (CompetitiveRoomDetect.IsCompetitiveRoom()) { NametagStyler.PublishToPhoton(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[POPUP] OnJoinedRoom restyle failed: " + ex.Message)); } } } [HarmonyPatch(typeof(NetworkConnectionHandler), "NetworkRestart")] internal class NetworkConnectionHandler_NetworkRestart_Diag_Patch { private static void Prefix() { try { if (!CompetitiveRoomDetect.IsCompetitiveRoom()) { return; } } catch { return; } try { NetworkConnectionHandler instance = NetworkConnectionHandler.instance; bool flag = (Object)(object)instance != (Object)null && instance.m_restarting; Plugin.Log.LogWarning((object)$"[NCH-DIAG] NetworkRestart() entered (already_restarting={flag}) {Diag2v2.DescribeRoom()} stack={Diag2v2.ShortStack()}"); } catch { } } } [HarmonyPatch(typeof(PhotonNetwork), "LeaveRoom", new Type[] { typeof(bool) })] internal class PhotonNetwork_LeaveRoom_Diag_Patch { private static void Prefix(bool becomeInactive) { try { if (!CompetitiveRoomDetect.IsCompetitiveRoom()) { return; } } catch { return; } try { Plugin.Log.LogWarning((object)$"[NCH-DIAG] PhotonNetwork.LeaveRoom(becomeInactive={becomeInactive}) {Diag2v2.DescribeRoom()} stack={Diag2v2.ShortStack()}"); } catch { } } } [HarmonyPatch(typeof(GM_ArmsRace), "PlayerJoined")] internal class GMArmsRace_PlayerJoined_Diag_Patch { private static void Prefix(GM_ArmsRace __instance, Player player) { if (!Diag2v2.IsActive()) { return; } try { int num = 0; int num2 = 0; if ((Object)(object)PlayerManager.instance != (Object)null && PlayerManager.instance.players != null) { num2 = PlayerManager.instance.players.Count; foreach (Player player2 in PlayerManager.instance.players) { if ((Object)(object)player2 != (Object)null) { num++; } } } int playersNeededToStart = __instance.playersNeededToStart; Plugin.Log.LogInfo((object)$"[2v2-DIAG] GM_ArmsRace.PlayerJoined fired: counted={num} listSize={num2} playersNeededToStart={playersNeededToStart}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2-DIAG] GM_ArmsRace.PlayerJoined log error: " + ex.Message)); } } } [HarmonyPatch(typeof(GM_ArmsRace), "StartGame")] internal class GMArmsRace_StartGame_Diag_Patch { private static void Prefix() { if (!Diag2v2.IsActive()) { return; } try { Plugin.Log.LogInfo((object)("[2v2-DIAG] GM_ArmsRace.StartGame() fired " + Diag2v2.DescribeRoom())); } catch { } } } [HarmonyPatch(typeof(Player), "Start")] internal class Player_Start_Diag_Patch { private static void Postfix(Player __instance) { if (!Diag2v2.IsActive()) { return; } try { bool flag = false; int num = -1; try { CharacterData data = __instance.data; bool? obj; if (data == null) { obj = null; } else { PhotonView view = data.view; obj = ((view != null) ? new bool?(view.IsMine) : ((bool?)null)); } bool? flag2 = obj; flag = flag2 == true; } catch { } try { CharacterData data2 = __instance.data; int? obj3; if (data2 == null) { obj3 = null; } else { PhotonView view2 = data2.view; obj3 = ((view2 != null) ? new int?(view2.OwnerActorNr) : ((int?)null)); } num = obj3 ?? (-1); } catch { } Plugin.Log.LogInfo((object)$"[2v2-DIAG] Player.Start: pid={__instance.PlayerID} team={__instance.TeamID} isLocal={flag} actor={num}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2-DIAG] Player.Start log error: " + ex.Message)); } } } internal static class FacePublisher { public const string PROP_FACE = "cr_face"; public static void PublishLocal() { //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown try { CharacterCreatorHandler instance = CharacterCreatorHandler.instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogInfo((object)"[POPUP-DIAG] PublishLocal skipped: CharacterCreatorHandler.instance is null (game state not ready)"); return; } if (instance.selectedPlayerFaces == null || instance.selectedPlayerFaces.Length == 0) { Plugin.Log.LogInfo((object)"[POPUP-DIAG] PublishLocal skipped: selectedPlayerFaces empty"); return; } PlayerFace val = instance.selectedPlayerFaces[0]; if (val == null) { Plugin.Log.LogInfo((object)"[POPUP-DIAG] PublishLocal skipped: face[0] is null"); return; } if (PhotonNetwork.LocalPlayer == null) { Plugin.Log.LogInfo((object)"[POPUP-DIAG] PublishLocal skipped: LocalPlayer is null"); return; } if (val.eyeID == 0 && val.mouthID == 0 && val.detailID == 0 && val.detail2ID == 0) { Plugin.Log.LogInfo((object)"[2v2] FacePublisher: skipping publish (face is all-zero defaults — let vanilla RPC handle it)"); return; } string text = string.Join("|", val.eyeID.ToString(CultureInfo.InvariantCulture), val.eyeOffset.x.ToString("F3", CultureInfo.InvariantCulture), val.eyeOffset.y.ToString("F3", CultureInfo.InvariantCulture), val.mouthID.ToString(CultureInfo.InvariantCulture), val.mouthOffset.x.ToString("F3", CultureInfo.InvariantCulture), val.mouthOffset.y.ToString("F3", CultureInfo.InvariantCulture), val.detailID.ToString(CultureInfo.InvariantCulture), val.detailOffset.x.ToString("F3", CultureInfo.InvariantCulture), val.detailOffset.y.ToString("F3", CultureInfo.InvariantCulture), val.detail2ID.ToString(CultureInfo.InvariantCulture), val.detail2Offset.x.ToString("F3", CultureInfo.InvariantCulture), val.detail2Offset.y.ToString("F3", CultureInfo.InvariantCulture)); Hashtable val2 = new Hashtable(); val2[(object)"cr_face"] = text; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)("[2v2] Published local face to Photon: " + text)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] Face publish failed: " + ex.Message)); } } public static bool TryReadAndApply(int pickerActorNumber, GameObject visualizerRoot) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) try { Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == pickerActorNumber) { val = val2; break; } } if (val == null || val.CustomProperties == null) { Plugin.Log.LogInfo((object)string.Format("[POPUP-DIAG] Face apply skipped actor={0}: photonPlayer={1} props={2}", pickerActorNumber, (val == null) ? "null" : "found", (((val != null) ? val.CustomProperties : null) == null) ? "null" : "ok")); return false; } if (!((Dictionary)(object)val.CustomProperties).ContainsKey((object)"cr_face")) { Plugin.Log.LogInfo((object)$"[POPUP-DIAG] Face apply skipped actor={pickerActorNumber}: cr_face property not set on remote player (their client never published, or property not yet replicated)"); return false; } string text = val.CustomProperties[(object)"cr_face"]?.ToString() ?? ""; if (string.IsNullOrEmpty(text)) { Plugin.Log.LogInfo((object)$"[POPUP-DIAG] Face apply skipped actor={pickerActorNumber}: cr_face value is empty string"); return false; } string[] array = text.Split('|'); if (array.Length < 12) { Plugin.Log.LogInfo((object)$"[POPUP-DIAG] Face apply skipped actor={pickerActorNumber}: cr_face has {array.Length} parts (expected 12) — likely truncated"); return false; } CultureInfo invariantCulture = CultureInfo.InvariantCulture; int num = int.Parse(array[0], invariantCulture); float num2 = float.Parse(array[1], invariantCulture); float num3 = float.Parse(array[2], invariantCulture); int num4 = int.Parse(array[3], invariantCulture); float num5 = float.Parse(array[4], invariantCulture); float num6 = float.Parse(array[5], invariantCulture); int num7 = int.Parse(array[6], invariantCulture); float num8 = float.Parse(array[7], invariantCulture); float num9 = float.Parse(array[8], invariantCulture); int num10 = int.Parse(array[9], invariantCulture); float num11 = float.Parse(array[10], invariantCulture); float num12 = float.Parse(array[11], invariantCulture); if (num == 0 && num4 == 0 && num7 == 0 && num10 == 0) { return false; } PlayerFace val3 = PlayerFace.CreateFace(num, new Vector2(num2, num3), num4, new Vector2(num5, num6), num7, new Vector2(num8, num9), num10, new Vector2(num11, num12)); CharacterCreatorItemEquipper val4 = ((visualizerRoot != null) ? visualizerRoot.GetComponentInChildren(true) : null); if ((Object)(object)val4 == (Object)null) { return false; } val4.EquipFace(val3); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] Face read+apply failed: " + ex.Message)); return false; } } } internal static class CardPickBodyTinter { private static Color teamColor0 = new Color(0.95f, 0.45f, 0.32f); private static Color teamColor1 = new Color(0.45f, 0.62f, 0.95f); private static bool teamColorsResolved = false; public static Color TeamColor0 => teamColor0; public static Color TeamColor1 => teamColor1; public static void EnsureTeamColors() { TryResolveTeamColors(); } private static void TryResolveTeamColors() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (teamColorsResolved) { return; } try { Color? val = ResolveTeamColor(0); Color? val2 = ResolveTeamColor(1); if (val.HasValue && ColorSat(val.Value) > 0.12f) { teamColor0 = val.Value; } if (val2.HasValue && ColorSat(val2.Value) > 0.12f) { teamColor1 = val2.Value; } teamColorsResolved = true; Plugin.Log.LogInfo((object)("[CARDPICK-TINT] resolved team colors: t0=" + ColorHex(teamColor0) + " t1=" + ColorHex(teamColor1) + " (raw c0=" + (val.HasValue ? ColorHex(val.Value) : "null") + " c1=" + (val2.HasValue ? ColorHex(val2.Value) : "null") + ")")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARDPICK-TINT] resolve failed: " + ex.Message)); } } private static float ColorSat(Color c) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references) float num = Math.Max(c.r, Math.Max(c.g, c.b)); float num2 = Math.Min(c.r, Math.Min(c.g, c.b)); if (!(num <= 0.001f)) { return (num - num2) / num; } return 0f; } private static Color? ResolveTeamColor(int team) { //IL_0135: Unknown result type (might be due to invalid IL or missing references) try { Type typeFromHandle = typeof(PlayerSkinBank); MethodInfo method = typeFromHandle.GetMethod("GetPlayerSkinColors", BindingFlags.Static | BindingFlags.Public); object obj = null; if (method != null) { try { obj = method.Invoke(null, new object[1] { team }); } catch { } } if (obj == null) { PlayerSkinBank instance = PlayerSkinBank.instance; if ((Object)(object)instance == (Object)null) { return null; } if (!(typeFromHandle.GetField("skins", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance) is Array array) || array.Length <= team) { return null; } object value = array.GetValue(team); obj = (value?.GetType().GetField("currentPlayerSkin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(value); } if (obj == null) { return null; } FieldInfo field = obj.GetType().GetField("color", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field.FieldType != typeof(Color)) { return null; } return (Color)field.GetValue(obj); } catch { return null; } } private static string ColorHex(Color c) { //IL_0005: 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_0029: Unknown result type (might be due to invalid IL or missing references) return $"#{(int)(c.r * 255f):X2}{(int)(c.g * 255f):X2}{(int)(c.b * 255f):X2}"; } public static IEnumerator RetintAfterChildrenSpawn(GameObject visualizer, int pickerTeamID, int pickerID, float xOffset = float.NaN) { bool hasOffset = !float.IsNaN(xOffset); for (int i = 0; i < 10; i++) { if ((Object)(object)visualizer == (Object)null) { yield break; } if (hasOffset) { try { Transform transform = visualizer.transform; Vector3 localPosition = transform.localPosition; if (Math.Abs(localPosition.x - xOffset) > 0.01f) { transform.localPosition = new Vector3(xOffset, localPosition.y, localPosition.z); } } catch { } } yield return null; } if ((Object)(object)visualizer == (Object)null) { yield break; } TryResolveTeamColors(); Color val = ((pickerTeamID == 1) ? teamColor1 : teamColor0); Color b = ((pickerTeamID == 1) ? teamColor0 : teamColor1); int num = 0; int num2 = 0; int num3 = 0; try { SpriteRenderer[] componentsInChildren = visualizer.GetComponentsInChildren(true); foreach (SpriteRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && IsCloseHue(val2.color, b)) { val2.color = new Color(val.r, val.g, val.b, val2.color.a); num++; } } ParticleSystem[] componentsInChildren2 = visualizer.GetComponentsInChildren(true); foreach (ParticleSystem val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null)) { MainModule main = val3.main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; Color color = ((MinMaxGradient)(ref startColor)).color; if (IsCloseHue(color, b)) { ((MinMaxGradient)(ref startColor)).color = new Color(val.r, val.g, val.b, color.a); ((MainModule)(ref main)).startColor = startColor; num2++; } } } MonoBehaviour[] componentsInChildren3 = visualizer.GetComponentsInChildren(true); foreach (MonoBehaviour val4 in componentsInChildren3) { if ((Object)(object)val4 == (Object)null) { continue; } Type type = ((object)val4).GetType(); if (type.Name != "PlayerSkin" && type.Name != "PlayerSkinHandler") { continue; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType != typeof(Color)) { continue; } try { Color val5 = (Color)fieldInfo.GetValue(val4); if (IsCloseHue(val5, b)) { fieldInfo.SetValue(val4, (object)new Color(val.r, val.g, val.b, val5.a)); num3++; } } catch { } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARDPICK-TINT] retint failed: " + ex.Message)); } if (num > 0 || num2 > 0 || num3 > 0) { Plugin.Log.LogInfo((object)$"[CARDPICK-TINT] pickerID={pickerID} team={pickerTeamID} retinted: sprites={num} particles={num2} skinFields={num3}"); } } private static bool IsCloseHue(Color a, Color b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) float num = a.r - b.r; float num2 = a.g - b.g; float num3 = a.b - b.b; return Mathf.Sqrt(num * num + num2 * num2 + num3 * num3) < 0.35f; } } [HarmonyPatch(typeof(CardChoiceVisuals), "Show")] internal class CardChoiceVisuals_Show_Competitive_Patch { private static void Postfix(CardChoiceVisuals __instance, int pickerID) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) try { if (!CompetitiveRoomDetect.IsCompetitiveRoom()) { return; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null || pickerID < 0 || pickerID >= instance.players.Count) { return; } Player val = instance.players[pickerID]; if ((Object)(object)val == (Object)null) { return; } PhotonView component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null || component.Owner == null) { return; } if (val.IsLocal) { FacePublisher.PublishLocal(); } if (FacePublisher.TryReadAndApply(component.Owner.ActorNumber, ((Component)__instance).gameObject)) { Plugin.Log.LogInfo((object)$"[POPUP] CardChoiceVisuals: applied picker face from Photon (pickerID={pickerID}, actor={component.Owner.ActorNumber})"); } try { object? obj = typeof(CardChoiceVisuals).GetField("currentSkin", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); string text; if ((Object)(object)val2 == (Object)null) { text = "(null)"; } else { Vector3 localPosition = val2.transform.localPosition; Vector3 localScale = val2.transform.localScale; int childCount = val2.transform.childCount; text = $"name={((Object)val2).name} active={val2.activeInHierarchy} layer={val2.layer} children={childCount} localPos=({localPosition.x:F1},{localPosition.y:F1},{localPosition.z:F1}) localScale=({localScale.x:F2},{localScale.y:F2},{localScale.z:F2})"; if ((Object)(object)Plugin.Instance != (Object)null && (Object)(object)val2 != (Object)null) { float xOffset = ((float)pickerID - 1.5f) * 4f; ((MonoBehaviour)Plugin.Instance).StartCoroutine(CardPickBodyTinter.RetintAfterChildrenSpawn(val2, val.TeamID, pickerID, xOffset)); } } Plugin.Log.LogInfo((object)$"[CARDPICK-DIAG] pickerID={pickerID} actor={component.Owner.ActorNumber} pid={val.PlayerID} team={val.TeamID} isLocal={val.IsLocal} currentSkin: {text}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[CARDPICK-DIAG] log error: " + ex.Message)); } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[POPUP] CardChoiceVisuals.Show postfix error: " + ex2.Message)); } } } internal static class CompetitiveRoomDetect { public static bool IsCompetitiveRoom() { try { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return false; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties != null && ((Dictionary)(object)customProperties).ContainsKey((object)"cr_ff")) { return true; } string text = PhotonNetwork.CurrentRoom.Name ?? ""; return text.StartsWith("ranked_") || text.StartsWith("team_") || text.StartsWith("sct-"); } catch { return false; } } } [HarmonyPatch(typeof(PopUpHandler), "StartPicking")] internal class PopUpHandler_StartPicking_Competitive_Patch { private static bool Prefix(Player player, Action functionToCall) { try { if (!CompetitiveRoomDetect.IsCompetitiveRoom()) { return true; } Plugin.Log.LogInfo((object)"[POPUP] Auto-confirming Continue prompt (competitive room bypass)"); try { functionToCall?.Invoke((YesNo)0); } catch (Exception ex) { Plugin.Log.LogError((object)("[POPUP] Continue auto-invoke failed: " + ex.Message)); } return false; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[POPUP] StartPicking prefix error: " + ex2.Message)); return true; } } } [HarmonyPatch(typeof(MapManager), "GetSpawnPoints")] internal class MapManager_GetSpawnPoints_2v2_Patch { private static void Postfix(ref SpawnPoint[] __result) { try { if (__result != null && __result.Length >= 2 && Diag2v2.IsActive()) { Array.Sort(__result, (SpawnPoint a, SpawnPoint b) => (((Object)(object)a == (Object)null) ? 0f : a.localStartPos.x).CompareTo(((Object)(object)b == (Object)null) ? 0f : b.localStartPos.x)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2] SpawnPoint sort failed: " + ex.Message)); } } } [HarmonyPatch(typeof(PlayerSkinBank), "GetPlayerSkinColors")] internal class PlayerSkinBank_GetPlayerSkinColors_2v2_Patch { private static readonly HashSet _bodyCallers = new HashSet { "PlayerSkinHandler", "Player", "PlayerAssigner", "HealthHandler", "CharacterData", "Holdable", "DeathEffect", "PlayerSkinParticle", "DamageHandler", "CardChoiceVisuals" }; private static readonly HashSet _loggedKeys = new HashSet(); private static float _lastClear; private static void Prefix(ref int team) { try { if (!Diag2v2.IsActive() || team < 0 || team > 3) { return; } bool flag = false; try { StackTrace stackTrace = new StackTrace(1, fNeedFileInfo: false); int num = Math.Min(stackTrace.FrameCount, 6); for (int i = 0; i < num; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase == null)) { string item = methodBase.DeclaringType?.Name ?? ""; if (_bodyCallers.Contains(item)) { flag = true; break; } } } } catch { } if (flag) { int num2 = team; team /= 2; if (Time.realtimeSinceStartup - _lastClear > 5f) { _loggedKeys.Clear(); _lastClear = Time.realtimeSinceStartup; } string text = $"{num2}→{team}"; if (_loggedKeys.Add(text)) { Plugin.Log.LogInfo((object)("[2v2-COLOR] body-call mapped " + text)); } } } catch { } } } [HarmonyPatch(typeof(PlayerSkinHandler), "Init")] internal class PlayerSkinHandlerInitRebakeGuard { private static void Postfix(PlayerSkinHandler __instance) { try { if (Diag2v2.IsActive() && !((Object)(object)__instance == (Object)null) && !((Object)(object)Plugin.Instance == (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(VerifyAndRebake(__instance)); } } catch { } } private static IEnumerator VerifyAndRebake(PlayerSkinHandler psh) { for (int i = 0; i < 8; i++) { yield return null; } if ((Object)(object)psh == (Object)null) { yield break; } try { object obj = typeof(PlayerSkinHandler).GetField("data", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(psh); if (obj == null) { yield break; } object obj2 = obj.GetType().GetField("player", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 == null) { yield break; } PropertyInfo property = obj2.GetType().GetProperty("PlayerID", BindingFlags.Instance | BindingFlags.Public); if (property == null) { yield break; } int num = (int)property.GetValue(obj2); if (num < 0 || num > 3) { yield break; } int num2 = num / 2; SpriteRenderer componentInChildren = ((Component)psh).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { yield break; } CardPickBodyTinter.EnsureTeamColors(); Color teamColor = CardPickBodyTinter.TeamColor0; Color teamColor2 = CardPickBodyTinter.TeamColor1; Color b = ((num2 == 1) ? teamColor2 : teamColor); Color b2 = ((num2 == 1) ? teamColor : teamColor2); float num3 = ColorDist(componentInChildren.color, b); if (!(ColorDist(componentInChildren.color, b2) + 0.08f < num3)) { yield break; } FieldInfo field = typeof(PlayerSkinHandler).GetField("inited", BindingFlags.Instance | BindingFlags.NonPublic); for (int num4 = ((Component)psh).transform.childCount - 1; num4 >= 0; num4--) { Transform child = ((Component)psh).transform.GetChild(num4); if ((Object)(object)child != (Object)null) { Object.Destroy((Object)(object)((Component)child).gameObject); } } field?.SetValue(psh, false); typeof(PlayerSkinHandler).GetMethod("Init", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(psh, null); Plugin.Log.LogInfo((object)$"[2v2-COLOR] Re-baked skin for PlayerID={num} (expectedTeam={num2}, body matched wrong team)"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[2v2-COLOR] rebake guard error: " + ex.Message)); } } private static float ColorDist(Color a, Color b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) float num = a.r - b.r; float num2 = a.g - b.g; float num3 = a.b - b.b; return (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3); } } [HarmonyPatch(typeof(MapManager), "UnloadAfterSeconds")] internal class MapManager_UnloadAfterSeconds_Diag_Patch { private static Exception Finalizer(Exception __exception) { if (__exception != null && Diag2v2.IsActive()) { try { Plugin.Log.LogError((object)("[2v2-DIAG] MapManager.UnloadAfterSeconds threw: " + __exception.GetType().Name + ": " + __exception.Message)); } catch { } } return __exception; } } [HarmonyPatch(typeof(CardChoice), "Pick")] internal class CardChoicePickPatch { private static void Prefix(GameObject pickedCard, bool clear) { try { if ((Object)(object)pickedCard == (Object)null) { return; } CardInfo val = pickedCard.GetComponent(); if ((Object)(object)val == (Object)null) { val = pickedCard.GetComponentInChildren(); } if ((Object)(object)val == (Object)null) { return; } string text = null; try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(CardInfo).GetField("cardName", bindingAttr); if (field != null) { text = field.GetValue(val) as string; } } catch { } if (string.IsNullOrEmpty(text)) { text = ((Object)pickedCard).name.Replace("(Clone)", "").Trim(); } if (!string.IsNullOrEmpty(text)) { int num = -1; try { num = CardChoice.instance.pickrID; } catch { } Plugin.Log.LogInfo((object)$"[HARMONY-CARD] Local Pick: card={text}, pickerID={num}"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[HARMONY-CARD] Pick hook error: " + ex.Message)); } } } [HarmonyPatch(typeof(CardChoice), "RPCA_DoEndPick")] internal class CardChoiceEndPickPatch { private struct PendingPick { public string CardName; public string Rarity; public int PickId; } private static List pendingPicks = new List(); public static void FlushPendingPicks(int localTeam) { if (pendingPicks.Count == 0) { return; } foreach (PendingPick pendingPick in pendingPicks) { if (pendingPick.PickId != localTeam && !string.IsNullOrEmpty(pendingPick.CardName)) { Plugin.Log.LogInfo((object)("[HARMONY-CARD] Flushing pre-match opp card: " + pendingPick.CardName + " (" + pendingPick.Rarity + ")")); GameStateWatcher.OnOpponentCardPicked(pendingPick.CardName, pendingPick.Rarity); } } pendingPicks.Clear(); } public static void ClearPending() { pendingPicks.Clear(); } private static void Prefix(int[] cardIDs, int targetCardID, int theInt, int pickId) { try { int localTeamId = GameStateWatcher.LocalTeamId; string text = null; string text2 = "Unknown"; try { PhotonView val = PhotonView.Find(targetCardID); if ((Object)(object)val != (Object)null) { CardInfo val2 = ((Component)val).GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).GetComponentInChildren(); } if ((Object)(object)val2 != (Object)null) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(CardInfo).GetField("cardName", bindingAttr); if (field != null) { text = field.GetValue(val2) as string; } FieldInfo field2 = typeof(CardInfo).GetField("rarity", bindingAttr); if (field2 != null) { text2 = field2.GetValue(val2)?.ToString() ?? "Unknown"; } } if (string.IsNullOrEmpty(text)) { text = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); } } } catch { } if (!string.IsNullOrEmpty(text)) { text = CardRarityLookup.GetCanonicalName(text); } if (!string.IsNullOrEmpty(text) && text2 == "Unknown") { text2 = CardRarityLookup.GetRarity(text); } if (localTeamId < 0) { if (!string.IsNullOrEmpty(text)) { pendingPicks.Add(new PendingPick { CardName = text, Rarity = text2, PickId = pickId }); Plugin.Log.LogInfo((object)$"[HARMONY-CARD] Buffered pick: card={text}, pickId={pickId} (localTeam unknown)"); } return; } bool flag = pickId != localTeamId; Plugin.Log.LogInfo((object)string.Format("[HARMONY-CARD] EndPick: card={0}, pickId(player)={1}, localTeam={2}, isOpp={3}", text ?? "(unresolved)", pickId, localTeamId, flag)); if (flag && !string.IsNullOrEmpty(text)) { Plugin.Log.LogInfo((object)("[HARMONY-CARD] Opponent picked: " + text + " (" + text2 + ")")); GameStateWatcher.OnOpponentCardPicked(text, text2); } if (flag || cardIDs == null || cardIDs.Length == 0) { return; } int currentRound = GameStateWatcher.CurrentRound; int localOffersCount = GameStateWatcher.LocalOffersCount; BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field3 = typeof(CardInfo).GetField("cardName", bindingAttr2); foreach (int num in cardIDs) { try { PhotonView val3 = PhotonView.Find(num); if ((Object)(object)val3 == (Object)null) { continue; } string text3 = null; CardInfo val4 = ((Component)val3).GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val3).GetComponentInChildren(); } if ((Object)(object)val4 != (Object)null && field3 != null) { text3 = field3.GetValue(val4) as string; } if (string.IsNullOrEmpty(text3)) { text3 = ((Object)((Component)val3).gameObject).name.Replace("(Clone)", "").Trim(); } text3 = CardRarityLookup.GetCanonicalName(text3); if (!string.IsNullOrEmpty(text3)) { bool flag2 = num == targetCardID; GameStateWatcher.OnLocalCardOffered(text3, flag2, currentRound); if (flag2) { Plugin.Log.LogInfo((object)$"[HARMONY-CARD] offer marked picked: card={text3} cid={num} target={targetCardID} round={currentRound}"); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)$"[HARMONY-CARD] offer loop error on cid={num}: {ex.Message}"); } } int num2 = GameStateWatcher.LocalOffersCount - localOffersCount; if (!GameStateWatcher.LocalOffersPickedIn(localOffersCount)) { string lastLocalPickedCardName = GameStateWatcher.LastLocalPickedCardName; if (!string.IsNullOrEmpty(lastLocalPickedCardName)) { GameStateWatcher.OnLocalCardOffered(lastLocalPickedCardName, wasPicked: true, currentRound); Plugin.Log.LogInfo((object)$"[HARMONY-CARD] offer fallback picked: card={lastLocalPickedCardName} round={currentRound} (newOffers={num2}, no picked row in cardIDs[])"); } } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[HARMONY-CARD] EndPick error: " + ex2.Message)); } } } public static class MainMenuInjector { private static bool injected = false; private static float checkTimer = 0f; private static GameObject injectedButton = null; private static int retryCount = 0; private static int maxRetries = 30; private static bool loggedFirstInjection = false; private static Type cachedTmpType = null; public static void Reset() { injected = false; injectedButton = null; retryCount = 0; } public static void TryInject() { checkTimer += Time.deltaTime; if (checkTimer < 1f) { return; } checkTimer = 0f; if (injected && (Object)(object)injectedButton != (Object)null) { return; } if (injected && (Object)(object)injectedButton == (Object)null) { injected = false; retryCount = 0; } if (retryCount >= maxRetries) { return; } retryCount++; if (PhotonNetwork.InRoom) { return; } try { DoInject(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MENU] Injection failed: " + ex.Message)); } } private static void DoInject() { if (cachedTmpType == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { cachedTmpType = assemblies[i].GetType("TMPro.TMP_Text"); if (cachedTmpType != null) { break; } } if (cachedTmpType == null) { Plugin.Log.LogWarning((object)"[MENU] TMPro.TMP_Text not found"); return; } } PropertyInfo property = cachedTmpType.GetProperty("text", BindingFlags.Instance | BindingFlags.Public); if (property == null) { return; } ListMenuButton[] array = Object.FindObjectsOfType(); if (array == null || array.Length == 0) { return; } ListMenuButton val = null; ListMenuButton[] array2 = array; foreach (ListMenuButton val2 in array2) { try { Component componentInChildren = ((Component)val2).GetComponentInChildren(cachedTmpType, true); if ((Object)(object)componentInChildren == (Object)null || !(((property.GetValue(componentInChildren) as string) ?? "").Trim().ToUpper() == "QUIT")) { continue; } val = val2; break; } catch { } } if ((Object)(object)val == (Object)null) { if (!loggedFirstInjection) { Plugin.Log.LogWarning((object)"[MENU] Could not find QUIT button in main menu"); } return; } Transform transform = ((Component)val).transform; Transform parent = transform.parent; if (!loggedFirstInjection) { Plugin.Log.LogInfo((object)("[MENU] Found QUIT button at " + ((Object)transform).name + ", parent: " + ((Object)parent).name)); } GameObject val3 = Object.Instantiate(((Component)transform).gameObject, parent); ((Object)val3).name = "CompetitiveRoundsButton"; val3.transform.SetSiblingIndex(transform.GetSiblingIndex()); bool flag = false; try { Component componentInChildren2 = val3.GetComponentInChildren(cachedTmpType); if ((Object)(object)componentInChildren2 != (Object)null) { property.SetValue(componentInChildren2, "SID'S COMPETITIVE ROUNDS"); flag = true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MENU] TMP text change failed: " + ex.Message)); } if (!flag) { Plugin.Log.LogWarning((object)"[MENU] Could not set button text"); } try { QuitButton component = val3.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } catch { } try { GoBack component2 = val3.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } catch { } val3.AddComponent(); injectedButton = val3; injected = true; if (!loggedFirstInjection) { Plugin.Log.LogInfo((object)"[MENU] Competitive button injected into main menu!"); loggedFirstInjection = true; } } } public class CompetitiveMenuButton : MonoBehaviour { private const string BUTTON_TEXT = "SID'S COMPETITIVE ROUNDS"; private object cachedTmpComponent; private PropertyInfo cachedTextProp; private bool textEnforcementReady; private void Start() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown CacheTmpReferences(); try { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("UnityEngine.UI.Button"); if (type != null) { break; } } if (!(type != null)) { return; } Component component = ((Component)this).GetComponent(type); if (!((Object)(object)component != (Object)null)) { return; } PropertyInfo property = type.GetProperty("onClick", BindingFlags.Instance | BindingFlags.Public); if (property != null) { object value = property.GetValue(component); MethodInfo method = value.GetType().GetMethod("RemoveAllListeners"); if (method != null) { method.Invoke(value, null); } MethodInfo method2 = value.GetType().GetMethod("AddListener"); if (method2 != null) { UnityAction val = new UnityAction(OnButtonClick); method2.Invoke(value, new object[1] { val }); Plugin.Log.LogInfo((object)"[MENU] Button onClick wired successfully"); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MENU] Button wiring failed: " + ex.Message)); } } private void CacheTmpReferences() { try { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("TMPro.TMP_Text"); if (type != null) { break; } } if (!(type == null)) { cachedTmpComponent = ((Component)this).GetComponentInChildren(type); if (cachedTmpComponent != null) { cachedTextProp = type.GetProperty("text", BindingFlags.Instance | BindingFlags.Public); textEnforcementReady = cachedTextProp != null; } } } catch { } } private void LateUpdate() { if (!textEnforcementReady) { return; } try { if (cachedTextProp.GetValue(cachedTmpComponent) as string != "SID'S COMPETITIVE ROUNDS") { cachedTextProp.SetValue(cachedTmpComponent, "SID'S COMPETITIVE ROUNDS"); } } catch { } } private void OnButtonClick() { Plugin.Log.LogInfo((object)"[MENU] Competitive button clicked!"); CompetitiveUI.ToggleOverlay(); } } public static class CardRarityLookup { private static readonly Dictionary lookup = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary canonical = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary hardAliases = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "Leach", "Leech" }, { "Riccochet", "Ricochet" }, { "BombsAway", "Bombs Away" }, { "Glasscannon", "Glass Cannon" }, { "ShieldCharge", "Shield Charge" }, { "AbyssalCountdown", "Abyssal Countdown" }, { "ChillingPresence", "Chilling Presence" }, { "DrillAmmo", "Drill Ammo" }, { "RadarShot", "Radar Shot" }, { "TargetBounce", "Target Bounce" }, { "TasteOfBlood", "Taste Of Blood" }, { "Fastball", "Fast Ball" }, { "Poison Bullets", "Poison" }, { "PoisonBullets", "Poison" }, { "Prisitne Perseverence", "Pristine Perseverance" }, { "Pristine Perseverence", "Pristine Perseverance" }, { "PristinePerseverance", "Pristine Perseverance" }, { "PristinePerseverence", "Pristine Perseverance" } }; public static int Count => lookup.Count; public static void Register(string cardName, string rarity) { if (!string.IsNullOrEmpty(cardName)) { lookup[cardName] = rarity; if (!canonical.ContainsKey(cardName)) { canonical[cardName] = cardName; } } } public static string GetRarity(string cardName) { if (string.IsNullOrEmpty(cardName)) { return "Unknown"; } if (lookup.TryGetValue(cardName, out var value)) { return value; } string canonicalName = GetCanonicalName(cardName); if (canonicalName != cardName && lookup.TryGetValue(canonicalName, out value)) { return value; } return "Unknown"; } public static string GetCanonicalName(string name) { if (string.IsNullOrEmpty(name)) { return name; } if (hardAliases.TryGetValue(name, out var value)) { name = value; } if (canonical.TryGetValue(name, out var value2)) { return ToTitleCase(value2); } return name; } private static string ToTitleCase(string input) { if (string.IsNullOrEmpty(input)) { return input; } string[] array = input.ToLower().Split(' '); for (int i = 0; i < array.Length; i++) { if (array[i].Length > 0) { array[i] = char.ToUpper(array[i][0]) + array[i].Substring(1); } } return string.Join(" ", array); } public static void ScanAll() { if (lookup.Count > 0) { return; } try { Type? typeFromHandle = typeof(CardInfo); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeFromHandle.GetField("cardName", bindingAttr); FieldInfo field2 = typeFromHandle.GetField("rarity", bindingAttr); PropertyInfo property = typeFromHandle.GetProperty("CardName", bindingAttr); CardInfo[] array = Resources.FindObjectsOfTypeAll(); CardInfo[] array2 = array; foreach (CardInfo val in array2) { try { string text = null; if (field != null) { text = field.GetValue(val) as string; } else if (property != null) { text = property.GetValue(val) as string; } if (string.IsNullOrEmpty(text)) { text = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); } if (!string.IsNullOrEmpty(text)) { string text2 = "Unknown"; if (field2 != null) { text2 = field2.GetValue(val)?.ToString() ?? "Unknown"; } Register(text, text2); string text3 = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); if (!string.IsNullOrEmpty(text3)) { lookup[text3] = text2; canonical[text3] = text; } } } catch { } } foreach (KeyValuePair hardAlias in hardAliases) { if (lookup.TryGetValue(hardAlias.Value, out var value)) { lookup[hardAlias.Key] = value; canonical[hardAlias.Key] = hardAlias.Value; } } if (lookup.Count > 0) { Plugin.Log.LogInfo((object)$"[RARITY] Card rarity lookup built: {lookup.Count} entries ({array.Length} CardInfo objects scanned)"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[RARITY] Card scan failed: " + ex.Message)); } } public static string GetSampleEntries(int max) { List list = new List(); int num = 0; foreach (KeyValuePair item in lookup) { list.Add(item.Key + "=" + item.Value); if (++num >= max) { break; } } return string.Join(", ", list.ToArray()); } } public class TaskbarFlash : MonoBehaviour { private struct FLASHWINFO { public uint cbSize; public IntPtr hwnd; public uint dwFlags; public uint uCount; public uint dwTimeout; } private const uint FLASHW_STOP = 0u; private const uint FLASHW_ALL = 3u; private const uint FLASHW_TIMERNOFG = 12u; private bool shouldFlash; private bool isFlashing; private IntPtr gameWindowHandle = IntPtr.Zero; private static TaskbarFlash instance; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool FlashWindowEx(ref FLASHWINFO pwfi); [DllImport("user32.dll")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); private void Awake() { if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { instance = this; } } private void Update() { if (gameWindowHandle == IntPtr.Zero) { try { gameWindowHandle = Process.GetCurrentProcess().MainWindowHandle; } catch { } if (gameWindowHandle == IntPtr.Zero) { try { gameWindowHandle = FindWindow("UnityWndClass", null); } catch { } } if (gameWindowHandle == IntPtr.Zero) { return; } Plugin.Log.LogInfo((object)$"[FLASH] Window handle resolved: {gameWindowHandle}"); } bool isFocused = Application.isFocused; if (shouldFlash && !isFlashing && !isFocused) { StartFlashing(); } if (shouldFlash && isFocused) { shouldFlash = false; } if (isFlashing && (!shouldFlash || isFocused)) { StopFlashing(); } } public static void Flash() { if ((Object)(object)instance != (Object)null) { instance.shouldFlash = true; Plugin.Log.LogInfo((object)$"[FLASH] Flash requested (focused={Application.isFocused}, handle={instance.gameWindowHandle})"); } else { Plugin.Log.LogWarning((object)"[FLASH] Flash requested but no instance"); } } private void StartFlashing() { if (!isFlashing) { FLASHWINFO pwfi = default(FLASHWINFO); pwfi.cbSize = (uint)Marshal.SizeOf(pwfi); pwfi.hwnd = gameWindowHandle; pwfi.dwFlags = 15u; pwfi.uCount = uint.MaxValue; pwfi.dwTimeout = 0u; bool flag = FlashWindowEx(ref pwfi); isFlashing = true; shouldFlash = true; Plugin.Log.LogInfo((object)$"[FLASH] Started flashing (result={flag})"); } } private void StopFlashing() { if (isFlashing) { FLASHWINFO pwfi = default(FLASHWINFO); pwfi.cbSize = (uint)Marshal.SizeOf(pwfi); pwfi.hwnd = gameWindowHandle; pwfi.dwFlags = 0u; pwfi.uCount = 0u; pwfi.dwTimeout = 0u; FlashWindowEx(ref pwfi); isFlashing = false; shouldFlash = false; } } } [HarmonyPatch(typeof(Gun), "Attack")] internal class GunAttackBlockOnF5Patch { private static bool _postfixFirstFireLogged; private static bool _postfixFirstPvRejectLogged; private static bool _postfixFirstIsMineRejectLogged; private static bool Prefix(Gun __instance) { if (!NativeUI.IsOpen) { return true; } try { PhotonView val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); if ((Object)(object)val == (Object)null || !val.IsMine) { return true; } } catch { return true; } return false; } private static void Postfix(Gun __instance) { if (!_postfixFirstFireLogged) { _postfixFirstFireLogged = true; Plugin.Log.LogInfo((object)$"[GUN-POST] Attack Postfix first invocation (gun={((__instance != null) ? ((Object)__instance).name : null)}, uiOpen={NativeUI.IsOpen})"); } if (NativeUI.IsOpen) { return; } try { PhotonView val = null; try { Player val2 = __instance?.player; if ((Object)(object)val2 != (Object)null) { val = val2.data?.view ?? ((Component)val2).GetComponent(); } } catch { } if ((Object)(object)val == (Object)null) { val = ((__instance != null) ? ((Component)__instance).GetComponentInParent() : null); } if ((Object)(object)val == (Object)null) { if (!_postfixFirstPvRejectLogged) { _postfixFirstPvRejectLogged = true; Plugin.Log.LogInfo((object)("[GUN-POST] first pv-null reject on gun=" + ((__instance != null) ? ((Object)__instance).name : null))); } } else if (!val.IsMine) { if (!_postfixFirstIsMineRejectLogged) { _postfixFirstIsMineRejectLogged = true; ManualLogSource log = Plugin.Log; Player owner = val.Owner; log.LogInfo((object)("[GUN-POST] first !IsMine reject (pv.owner=" + ((owner != null) ? owner.NickName : null) + ")")); } } else { int projectiles = 1; try { projectiles = Math.Max(1, __instance.numberOfProjectiles); } catch { } GameStateWatcher.OnLocalBulletFired(projectiles); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[GUN-POST] exception: " + ex.Message)); } } } [HarmonyPatch(typeof(Block), "TryBlock")] internal class BlockTryBlockOnF5Patch { private static bool Prefix(Block __instance) { if (!NativeUI.IsOpen) { return true; } try { PhotonView val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); if ((Object)(object)val == (Object)null || !val.IsMine) { return true; } } catch { return true; } return false; } } [HarmonyPatch] internal class HealthHandlerTakeDamageCounterPatch { private static int _takeDamageFirstLogRemaining = 5; private static int _ffDiagRemaining = 8; private static int _ffDiagLastResetRound = -1; private static MethodBase TargetMethod() { Type? typeFromHandle = typeof(HealthHandler); MethodInfo result = null; int num = -1; MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "TakeDamage")) { int num2 = methodInfo.GetParameters().Length; if (num2 > num) { num = num2; result = methodInfo; } } } return result; } private static void Postfix(HealthHandler __instance, Vector2 damage, GameObject damagingWeapon, Player damagingPlayer) { try { if ((Object)(object)damagingPlayer == (Object)null || ((Vector2)(ref damage)).magnitude <= 0.01f) { return; } try { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null && ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties != null && ((Dictionary)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).ContainsKey((object)"cr_ff") && _ffDiagRemaining > 0) { CharacterData val = (((Object)(object)damagingPlayer != (Object)null) ? ((Component)damagingPlayer).GetComponent() : null); CharacterData val2 = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); FieldInfo field = typeof(CharacterData).GetField("teamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = (((Object)(object)val != (Object)null && field != null) ? ((int)field.GetValue(val)) : (-1)); int num2 = (((Object)(object)val2 != (Object)null && field != null) ? ((int)field.GetValue(val2)) : (-1)); bool flag = num >= 0 && num == num2; _ffDiagRemaining--; Plugin.Log.LogInfo((object)string.Format("[FF-DIAG] dmg={0:F1} src_team={1} tgt_team={2} same_team={3} weapon='{4}'", ((Vector2)(ref damage)).magnitude, num, num2, flag, ((Object)(object)damagingWeapon != (Object)null) ? ((Object)damagingWeapon).name : "(null)")); } } catch { } PhotonView val3 = damagingPlayer.data?.view ?? ((Component)damagingPlayer).GetComponent(); PhotonView val4 = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); try { if ((Object)(object)val4 != (Object)null && val4.IsMine && (Object)(object)val3 != (Object)null && !val3.IsMine) { GameStateWatcher.OnLocalPlayerHit(((Vector2)(ref damage)).magnitude); } } catch { } if ((Object)(object)val3 == (Object)null || !val3.IsMine || ((Object)(object)val4 != (Object)null && val4.IsMine)) { return; } if (_takeDamageFirstLogRemaining > 0) { _takeDamageFirstLogRemaining--; string arg = (((Object)(object)damagingWeapon != (Object)null) ? ((Object)damagingWeapon).name : "(null)"); string arg2 = ""; if ((Object)(object)damagingWeapon != (Object)null) { try { Component[] components = damagingWeapon.GetComponents(); List list = new List(); Component[] array = components; foreach (Component val5 in array) { if ((Object)(object)val5 != (Object)null) { list.Add(((object)val5).GetType().Name); } } arg2 = string.Join(",", list); } catch { } } Plugin.Log.LogInfo((object)$"[HIT-DIAG] damage={((Vector2)(ref damage)).magnitude:F1} weapon='{arg}' components=[{arg2}]"); } GameStateWatcher.OnLocalBulletHit(); } catch { } } } [HarmonyPatch(typeof(Block), "TryBlock")] internal class BlockTryBlockCounterPatch { private static FieldInfo _fCounter; private static FieldInfo _fCooldown; private static bool _fieldsResolved; private static float _lastDiagLogTime; private static void ResolveFields() { if (!_fieldsResolved) { try { Type? typeFromHandle = typeof(Block); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; _fCounter = typeFromHandle.GetField("counter", bindingAttr); _fCooldown = typeFromHandle.GetField("cooldown", bindingAttr); } catch { } _fieldsResolved = true; } } private static void Prefix(Block __instance, out bool __state) { __state = false; try { ResolveFields(); if (_fCounter == null || _fCooldown == null) { __state = true; return; } float num = (float)_fCounter.GetValue(__instance); float num2 = (float)_fCooldown.GetValue(__instance); __state = num >= num2; } catch { __state = true; } } private static void Postfix(Block __instance, bool __state) { if (NativeUI.IsOpen) { return; } try { PhotonView val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); if ((Object)(object)val == (Object)null || !val.IsMine) { return; } try { if (CompetitiveRoomDetect.IsCompetitiveRoom() && !_diagThrottled()) { Player componentInParent = ((Component)__instance).GetComponentInParent(); int num = -1; int num2 = -1; try { num = (((Object)(object)componentInParent != (Object)null) ? componentInParent.TeamID : (-1)); } catch { } try { num2 = (((Object)(object)componentInParent != (Object)null) ? componentInParent.PlayerID : (-1)); } catch { } int num3 = -1; bool flag = false; try { num3 = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)); } catch { } try { flag = PhotonNetwork.IsMasterClient; } catch { } Plugin.Log.LogInfo((object)$"[BLOCK-TEAM] tryBlock ready={__state} team={num} playerID={num2} actor={num3} isMaster={flag}"); } } catch { } if (__state) { GameStateWatcher.OnLocalBlockActivated(); } } catch { } } private static bool _diagThrottled() { float unscaledTime = Time.unscaledTime; if (unscaledTime - _lastDiagLogTime < 0.5f) { return true; } _lastDiagLogTime = unscaledTime; return false; } } [HarmonyPatch] internal class BlockDoBlockCounterPatch { private static bool _firstEntry; private static MethodBase TargetMethod() { Type? typeFromHandle = typeof(Block); MethodInfo result = null; int num = -1; MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "DoBlock")) { int num2 = methodInfo.GetParameters().Length; if (num2 > num) { num = num2; result = methodInfo; } } } return result; } private static void Postfix(Block __instance) { if (!_firstEntry) { _firstEntry = true; Plugin.Log.LogInfo((object)"[BLOCK] DoBlock Postfix first invocation (patch attached)"); } try { PhotonView val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent() : null); if (!((Object)(object)val == (Object)null) && val.IsMine) { GameStateWatcher.OnLocalBlockSuccessful(); } } catch { } } } internal class NCHConnectToRegionDiagPatch { private static IEnumerable TargetMethods() { HashSet seen = new HashSet(); Type[] array = new Type[2] { typeof(NetworkConnectionHandler), typeof(PhotonNetwork) }; foreach (Type type in array) { if (type == null) { continue; } List list; try { list = AccessTools.GetDeclaredMethods(type); } catch { list = null; } if (list == null) { continue; } foreach (MethodInfo item in list) { if (item != null && item.Name == "ConnectToRegion" && seen.Add(item)) { yield return item; } } } } private static void Prefix(object[] __args) { try { if (!CompetitiveRoomDetect.IsCompetitiveRoom()) { return; } string text = "?"; if (__args != null) { for (int i = 0; i < __args.Length; i++) { if (__args[i] is string text2) { text = text2; break; } } } string arg = "(none)"; try { Room currentRoom = PhotonNetwork.CurrentRoom; arg = ((currentRoom != null) ? currentRoom.Name : null) ?? "(none)"; } catch { } StackTrace stackTrace = new StackTrace(1, fNeedFileInfo: false); StringBuilder stringBuilder = new StringBuilder(); int num = Math.Min(stackTrace.FrameCount, 12); for (int j = 0; j < num; j++) { MethodBase methodBase = stackTrace.GetFrame(j)?.GetMethod(); if (!(methodBase == null)) { stringBuilder.Append(" at ").Append(methodBase.DeclaringType?.FullName ?? "?").Append('.') .Append(methodBase.Name) .Append('\n'); } } Plugin.Log.LogWarning((object)("[NCH-DIAG] ConnectToRegion('" + text + "') called " + $"while in comp room='{arg}'. Stack:\n{stringBuilder}")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NCH-DIAG] log error: " + ex.Message)); } } } [HarmonyPatch(typeof(BlockTrigger), "DoBlock")] internal class BlockTriggerDoBlockNullSafetyPatch { private static bool Prefix(BlockTrigger __instance, BlockTriggerType triggerType) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { string arg = "?"; try { arg = "(GameObject destroyed)"; } catch { } Plugin.Log.LogWarning((object)($"[BLOCK-SAFETY] DoBlock skipped: triggerType={triggerType} owner={arg}. " + "If a player's block isn't proccing this round, this is the cause — main BlockTrigger was destroyed.")); return false; } return true; } private static Exception Finalizer(Exception __exception, BlockTrigger __instance, BlockTriggerType triggerType) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (__exception is NullReferenceException || __exception is MissingReferenceException) { string arg = "alive"; try { if ((Object)(object)__instance == (Object)null) { arg = "destroyed"; } } catch { arg = "introspection-failed"; } Plugin.Log.LogWarning((object)("[BLOCK-SAFETY] NRE inside vanilla DoBlock " + $"(triggerType={triggerType} instance={arg}) — swallowed so iterator continues. " + "Stack: " + (__exception.StackTrace ?? "(none)").Replace("\n", " | "))); return null; } return __exception; } } internal static class BlockReflect { private static FieldInfo _fCounter; private static FieldInfo _fCooldown; private static bool _resolved; private static readonly Dictionary _delFieldCache = new Dictionary(); private static void Resolve() { if (!_resolved) { try { Type? typeFromHandle = typeof(Block); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; _fCounter = typeFromHandle.GetField("counter", bindingAttr); _fCooldown = typeFromHandle.GetField("cooldown", bindingAttr); } catch { } _resolved = true; } } public static int ScrubDeadDelegateFields(Component c) { if ((Object)(object)c == (Object)null) { return 0; } int num = 0; try { Type type = ((object)c).GetType(); FieldInfo[] fields; if (!_delFieldCache.TryGetValue(type, out var value)) { List list = new List(); BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; Type type2 = type; while (type2 != null && type2 != typeof(MonoBehaviour) && type2 != typeof(Behaviour) && type2 != typeof(object)) { fields = type2.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { list.Add(fieldInfo); } } type2 = type2.BaseType; } value = list.ToArray(); _delFieldCache[type] = value; } fields = value; foreach (FieldInfo fieldInfo2 in fields) { if (!(fieldInfo2.GetValue(c) is Delegate obj)) { continue; } Delegate[] invocationList = obj.GetInvocationList(); Delegate obj2 = null; int num2 = 0; Delegate[] array = invocationList; foreach (Delegate obj3 in array) { object? target = obj3.Target; Object val = (Object)((target is Object) ? target : null); if (val != null && val == (Object)null) { num2++; } else { obj2 = Delegate.Combine(obj2, obj3); } } if (num2 > 0) { fieldInfo2.SetValue(c, obj2); num += num2; } } } catch { } return num; } public static int ScrubPlayerDelegates(Player p) { int num = 0; try { if ((Object)(object)p == (Object)null || (Object)(object)p.data == (Object)null) { return 0; } num += ScrubDeadDelegateFields((Component)(object)p.data); num += ScrubDeadDelegateFields((Component)(object)p.data.block); num += ScrubDeadDelegateFields((Component)(object)p.data.healthHandler); num += ScrubDeadDelegateFields((Component)(object)p.data.stats); if ((Object)(object)p.data.weaponHandler != (Object)null) { num += ScrubDeadDelegateFields((Component)(object)p.data.weaponHandler.gun); } num += ScrubDeadDelegateFields((Component)(object)((Component)p).GetComponent()); num += ScrubDeadDelegateFields((Component)(object)((Component)p).GetComponent()); } catch { } return num; } public static void ForceReady(Block b) { if ((Object)(object)b == (Object)null) { return; } Resolve(); try { if (_fCounter != null && _fCooldown != null) { float num = (float)_fCooldown.GetValue(b); _fCounter.SetValue(b, num); } } catch { } } } [HarmonyPatch(typeof(Block), "RPCA_DoBlock")] internal class BlockRpcaDoBlockZombieScrubPatch { private static void Prefix(Block __instance) { int num = BlockReflect.ScrubDeadDelegateFields((Component)(object)__instance); try { CharacterData component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null) { if ((Object)(object)component.weaponHandler != (Object)null) { num += BlockReflect.ScrubDeadDelegateFields((Component)(object)component.weaponHandler.gun); } num += BlockReflect.ScrubDeadDelegateFields((Component)(object)component.healthHandler); } } catch { } if (num > 0) { Plugin.Log.LogWarning((object)$"[BLOCK-DBG] ZOMBIE-SCRUB removed {num} dead delegate entry(ies) at block time (an earlier card OnDestroy aborted mid-teardown)"); } } } [HarmonyPatch(typeof(GM_ArmsRace), "StartGame")] internal class GMArmsRaceStartGameBlockResetPatch { private static void Postfix() { try { int num = 0; int num2 = 0; PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance != (Object)null && instance.players != null) { foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { num += BlockReflect.ScrubPlayerDelegates(player); num2++; } } } bool flag = CompetitiveRoomDetect.IsCompetitiveRoom(); if (flag) { Block[] array = Object.FindObjectsOfType(); if (array != null) { Block[] array2 = array; for (int i = 0; i < array2.Length; i++) { BlockReflect.ForceReady(array2[i]); } } } Plugin.Log.LogInfo((object)$"[BLOCK-RESET] StartGame v2: scrubbed {num} zombie delegate entry(ies) across {num2} player(s) (competitive={flag})"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[BLOCK-RESET] error: " + ex.Message)); } } } [HarmonyPatch(typeof(ArtHandler), "Awake")] internal class ArtHandlerAwakePatch { private static void Postfix(ArtHandler __instance) { try { if (__instance.arts == null) { return; } FieldInfo field = typeof(ArtInstance).GetField("profile", BindingFlags.Instance | BindingFlags.Public); for (int i = 0; i < __instance.arts.Length; i++) { ArtInstance val = __instance.arts[i]; if (val != null) { object? obj = field?.GetValue(val); string arg = ""; Object val2 = (Object)((obj is Object) ? obj : null); if (val2 != null) { arg = val2.name; } Plugin.Log.LogInfo((object)$"[MAPCOLOR] arts[{i}] profile.name = '{arg}'"); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MAPCOLOR] Awake log failed: " + ex.Message)); } } } internal static class MapColorState { public static string CurrentSku; public static string ToastText = ""; public static float ToastUntil = -999f; public static void ShowToast(string name) { try { ToastText = name ?? ""; ToastUntil = Time.unscaledTime + 2.5f; } catch { } } } [HarmonyPatch(typeof(Map), "Start")] internal class MapPhysicalColorPatch { private static readonly Dictionary _matCache = new Dictionary(); private static bool _loggedTypes; private static readonly Dictionary _vanillaPSColorCache = new Dictionary(512); public static float LastMapStartTime = -999f; public const float MapTransitionGuardSec = 2f; private static bool _loggedScenePaths; private static Color GetCachedVanillaColor(ParticleSystem ps) { //IL_000a: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_003c: Unknown result type (might be due to invalid IL or missing references) int instanceID; try { instanceID = ((Object)ps).GetInstanceID(); } catch { return Color.white; } if (_vanillaPSColorCache.TryGetValue(instanceID, out var value)) { return value; } Color val; try { MainModule main = ps.main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; val = ((MinMaxGradient)(ref startColor)).color; } catch { val = Color.white; } _vanillaPSColorCache[instanceID] = val; return val; } private static Color SaturateColor(Color c, float mult) { //IL_0000: 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_0019: 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_0039: 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_005a: 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) float num = c.r * 0.299f + c.g * 0.587f + c.b * 0.114f; return new Color(Mathf.Clamp01(num + (c.r - num) * mult), Mathf.Clamp01(num + (c.g - num) * mult), Mathf.Clamp01(num + (c.b - num) * mult), c.a); } private static void Postfix(Map __instance) { LastMapStartTime = Time.time; string text = MapColorState.CurrentSku; if (string.IsNullOrEmpty(text)) { text = ApiClient.CachedPlayerStats?.active_color_sku; } if (!string.IsNullOrEmpty(text) && CustomMapColors.IsCustomSku(text)) { ScheduleDeferredTints(text); } } public static void ScheduleDeferredTints(string sku) { if (!string.IsNullOrEmpty(sku) && CustomMapColors.IsCustomSku(sku)) { CompetitiveRoundsBehaviour instance = Plugin.Instance; if ((Object)(object)instance != (Object)null) { ((MonoBehaviour)instance).StartCoroutine(DelayedApplyTints(sku)); } } } private static IEnumerator DelayedApplyTints(string sku) { yield return (object)new WaitForSeconds(2f); ApplyPhysicalTintsForSku(null, sku); } public static void ApplyPhysicalTintsForSku(Map mapInstance, string sku) { //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: 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_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mapInstance == (Object)null) { mapInstance = Object.FindObjectOfType(); if ((Object)(object)mapInstance == (Object)null) { return; } } try { if (string.IsNullOrEmpty(sku) || !CustomMapColors.IsCustomSku(sku)) { return; } Color? mapBlockColor = CustomMapColors.GetMapBlockColor(sku); if (!mapBlockColor.HasValue) { Plugin.Log.LogInfo((object)("[MAPCOLOR] Map.Start sku=" + sku + " but no MapBlockColor → SpriteRenderer-only path")); } Color val = (Color)(((??)mapBlockColor) ?? Color.white); if (!mapBlockColor.HasValue) { return; } List list = new List(); ParticleSystem[] array = Object.FindObjectsOfType(); foreach (ParticleSystem val2 in array) { if (!((Object)(object)val2 == (Object)null) && GetTransformPath(((Component)val2).transform).StartsWith("OutOfBounds/", StringComparison.OrdinalIgnoreCase)) { list.Add(val2); } } list.Sort((ParticleSystem a, ParticleSystem b) => string.CompareOrdinal(GetTransformPath(((Component)a).transform), GetTransformPath(((Component)b).transform))); int num = 0; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (ParticleSystem item in list) { string text = GetTransformPath(((Component)item).transform).Substring("OutOfBounds/".Length); int num2 = text.IndexOf('/'); hashSet.Add((num2 >= 0) ? text.Substring(0, num2) : text); } bool flag = hashSet.Count < 2; Color val5 = default(Color); for (int num3 = 0; num3 < list.Count; num3++) { ParticleSystem val3 = list[num3]; try { string transformPath = GetTransformPath(((Component)val3).transform); bool flag2; if (flag) { Vector3 position = ((Component)val3).transform.position; flag2 = ((Mathf.FloorToInt(position.x / 14f) + Mathf.FloorToInt(position.y / 14f)) % 2 + 2) % 2 == 0; } else { string text2 = transformPath.Substring("OutOfBounds/".Length); int num4 = text2.IndexOf('/'); flag2 = StablePathParity((num4 >= 0) ? text2.Substring(0, num4) : text2) == 0; } Color c = (flag2 ? val : CustomMapColors.GetSecondaryColor(sku)); Color cachedVanillaColor = GetCachedVanillaColor(val3); float num5 = cachedVanillaColor.r * 0.299f + cachedVanillaColor.g * 0.587f + cachedVanillaColor.b * 0.114f; Color val4 = SaturateColor(c, 1.35f); float num6 = 1.05f + 0.55f * Mathf.Clamp01(num5); ((Color)(ref val5))..ctor(val4.r * num6, val4.g * num6, val4.b * num6, cachedVanillaColor.a); MainModule main = val3.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(val5); ParticleSystemRenderer component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { component.sortingFudge = -0.1f - (float)num3 * 0.05f; } val3.Clear(true); } catch { } num++; } int num7 = 0; try { Color val6 = Color.Lerp(new Color(0.5f, 0.5f, 0.5f), val, 0.72f); string baseArt = CustomMapColors.GetBaseArt(sku); ArtHandler instance = ArtHandler.instance; if ((Object)(object)instance != (Object)null && instance.arts != null) { FieldInfo field = typeof(ArtInstance).GetField("parts", BindingFlags.Instance | BindingFlags.Public); FieldInfo field2 = typeof(ArtInstance).GetField("profile", BindingFlags.Instance | BindingFlags.Public); ArtInstance[] arts = instance.arts; Color val10 = default(Color); foreach (ArtInstance val7 in arts) { if (val7 == null || !(field?.GetValue(val7) is ParticleSystem[] array2)) { continue; } bool flag3 = false; try { object? obj2 = field2?.GetValue(val7); Object val8 = (Object)((obj2 is Object) ? obj2 : null); flag3 = val8 != (Object)null && !string.IsNullOrEmpty(baseArt) && string.Equals(val8.name, baseArt, StringComparison.OrdinalIgnoreCase); } catch { } if (!flag3) { try { val7.TogglePart(false); } catch { } continue; } foreach (ParticleSystem val9 in array2) { if (!((Object)(object)val9 == (Object)null)) { try { Color cachedVanillaColor2 = GetCachedVanillaColor(val9); float num9 = cachedVanillaColor2.r * 0.299f + cachedVanillaColor2.g * 0.587f + cachedVanillaColor2.b * 0.114f; float num10 = 0.36f + 0.52f * Mathf.Clamp01(num9); ((Color)(ref val10))..ctor(val6.r * num10, val6.g * num10, val6.b * num10, cachedVanillaColor2.a); MainModule main2 = val9.main; ((MainModule)(ref main2)).startColor = new MinMaxGradient(val10); val9.Clear(true); } catch { } num7++; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MAPCOLOR] art-particle tint failed: " + ex.Message)); } Plugin.Log.LogInfo((object)string.Format("[MAPCOLOR] sku={0}: two-tone walls ({1} systems, keying={2}, groups={3}) + {4} primary bg particles; non-base arts off", sku, num, flag ? "spatial-cells" : "path-groups", hashSet.Count, num7)); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[MAPCOLOR] Map tint failed: " + ex2.Message)); } } private static int StablePathParity(string s) { uint num = 2166136261u; for (int i = 0; i < s.Length; i++) { num ^= s[i]; num *= 16777619; } return (int)(num & 1); } private static string GetTransformPath(Transform t) { if ((Object)(object)t == (Object)null) { return ""; } StringBuilder stringBuilder = new StringBuilder(((Object)t).name); Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, ((Object)parent).name + "/"); parent = parent.parent; } return stringBuilder.ToString(); } } [HarmonyPatch(typeof(ArtHandler), "NextArt")] internal class ArtHandlerNextArtPatch { private static readonly Dictionary SKU_TO_ART = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "mapcolor_default", "" }, { "mapcolor_sweden", "Sweden" }, { "mapcolor_sky", "Sky" }, { "mapcolor_poison", "Poison" }, { "mapcolor_gold", "Gold" }, { "mapcolor_soviet", "Soviet" }, { "mapcolor_rainbow", "Rainbow" } }; private static int _cycleIndex = 0; private static int _cycleLastListHash = 0; private static List _lastEquippedFiltered; private static bool Prefix(ArtHandler __instance) { try { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; List list = cachedPlayerStats?.active_color_skus; List list2 = null; if (list != null && list.Count > 0) { list2 = new List(list.Count); for (int i = 0; i < list.Count; i++) { string text = list[i]; if (!string.IsNullOrEmpty(text)) { list2.Add(text); } } } if ((list2 == null || list2.Count == 0) && _lastEquippedFiltered != null) { list2 = _lastEquippedFiltered; Plugin.Log.LogInfo((object)$"[MAPCOLOR] Live equipped empty/null, reusing last-known list ({list2.Count} skus)"); } else if (list2 != null && list2.Count > 0) { _lastEquippedFiltered = list2; } string text2 = null; if (list2 != null && list2.Count > 0) { int num = 0; for (int j = 0; j < list2.Count; j++) { num = num * 31 + (list2[j]?.GetHashCode() ?? 0); } if (num != _cycleLastListHash) { _cycleIndex = 0; _cycleLastListHash = num; } bool flag = false; try { flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); } catch { } if (flag) { _cycleIndex = (_cycleIndex + 1) % list2.Count; } text2 = list2[_cycleIndex % list2.Count]; Plugin.Log.LogInfo((object)string.Format("[MAPCOLOR] {0} → {1} (index {2}/{3})", flag ? "Shift cycle" : "auto-keep", text2, _cycleIndex, list2.Count)); if (flag) { MapColorState.ShowToast(CustomMapColors.FriendlyName(text2)); } } if (string.IsNullOrEmpty(text2)) { text2 = cachedPlayerStats?.active_color_sku; } if (string.IsNullOrEmpty(text2)) { Plugin.Log.LogInfo((object)"[MAPCOLOR] No custom sku resolved — falling through to vanilla NextArt"); return true; } MapColorState.CurrentSku = text2; if (CustomMapColors.IsCustomSku(text2)) { string baseArt = CustomMapColors.GetBaseArt(text2); if (string.IsNullOrEmpty(baseArt)) { return true; } try { if (__instance.arts != null) { ArtInstance[] arts = __instance.arts; foreach (ArtInstance obj2 in arts) { if (obj2 != null) { obj2.TogglePart(false); } } } } catch { } __instance.SetSpecificArt(baseArt); PostProcessProfile val = (((Object)(object)__instance.volume != (Object)null) ? __instance.volume.profile : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("[MAPCOLOR] sku=" + text2 + " — volume.profile null after SetSpecificArt(" + baseArt + ")")); return false; } PostProcessProfile val2 = CustomMapColors.BuildOrGetClone(text2, val); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)("[MAPCOLOR] sku=" + text2 + " — clone build failed, leaving base art active")); return false; } __instance.ApplyPost(val2); try { if ((Object)(object)__instance.volume != (Object)null) { __instance.volume.weight = 1f; } } catch { } bool flag2 = Time.time - MapPhysicalColorPatch.LastMapStartTime < 2f; if (flag2) { MapPhysicalColorPatch.ScheduleDeferredTints(text2); } else { MapPhysicalColorPatch.ApplyPhysicalTintsForSku(null, text2); } Plugin.Log.LogInfo((object)$"[MAPCOLOR] applied custom sku={text2} on base='{baseArt}' (deferParticles={flag2})"); return false; } if (!SKU_TO_ART.TryGetValue(text2, out var value)) { Plugin.Log.LogWarning((object)("[MAPCOLOR] Unknown sku '" + text2 + "' — not in CustomMapColors presets, not in vanilla SKU_TO_ART. Equipped but not renderable; falling through to vanilla.")); return true; } if (string.IsNullOrEmpty(value)) { return true; } bool flag3 = false; if (__instance.arts != null) { FieldInfo field = typeof(ArtInstance).GetField("profile", BindingFlags.Instance | BindingFlags.Public); ArtInstance[] arts = __instance.arts; foreach (ArtInstance val3 in arts) { if (val3 != null) { object? obj5 = field?.GetValue(val3); Object val4 = (Object)((obj5 is Object) ? obj5 : null); if (val4 != (Object)null && val4.name == value) { flag3 = true; break; } } } } if (!flag3) { Plugin.Log.LogWarning((object)("[MAPCOLOR] sku=" + text2 + " mapped to art='" + value + "' but no matching art on this ArtHandler — falling through to vanilla random")); return true; } __instance.SetSpecificArt(value); return false; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[MAPCOLOR] NextArt prefix failed: " + ex.Message)); return true; } } } internal static class TrailCosmetic { private const string PROP_SKU = "cr_trail_sku"; private const string PROP_COLOR = "cr_trail_color"; private const string PROP_PRICE = "cr_trail_price"; private static readonly Dictionary attached = new Dictionary(); public static void PublishLocalProps() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown try { if (PhotonNetwork.IsConnected && PhotonNetwork.LocalPlayer != null) { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; Hashtable val = new Hashtable(); val[(object)"cr_trail_sku"] = cachedPlayerStats?.active_trail_sku ?? ""; val[(object)"cr_trail_color"] = cachedPlayerStats?.active_trail_color ?? ""; val[(object)"cr_trail_price"] = cachedPlayerStats?.active_trail_price ?? 0; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)string.Format("[TRAIL] Published local props sku={0} color={1} price={2}", val[(object)"cr_trail_sku"], val[(object)"cr_trail_color"], val[(object)"cr_trail_price"])); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL] PublishLocalProps failed: " + ex.Message)); } } public static void OnMatchStart() { try { if (Plugin.ShowTrails != null && !Plugin.ShowTrails.Value) { Plugin.Log.LogInfo((object)"[TRAIL] Skipped — ShowTrails is off"); } else { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedAttachAll()); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL] OnMatchStart error: " + ex.Message)); } } public static void OnPlayerPropertiesChanged(Player target, Hashtable changed) { if (target != null && changed != null && (((Dictionary)(object)changed).ContainsKey((object)"cr_trail_sku") || ((Dictionary)(object)changed).ContainsKey((object)"cr_trail_color") || ((Dictionary)(object)changed).ContainsKey((object)"cr_trail_price")) && (PhotonNetwork.LocalPlayer == null || target.ActorNumber != PhotonNetwork.LocalPlayer.ActorNumber)) { ReattachForActor(target.ActorNumber); } } public static void ReattachForActor(int actor) { try { if (Plugin.ShowTrails != null && !Plugin.ShowTrails.Value) { return; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null || instance.players.Count == 0) { return; } Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == actor) { val = val2; break; } } if (val == null || val.CustomProperties == null) { return; } Hashtable customProperties = val.CustomProperties; string text = ((!((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_sku")) ? "" : (customProperties[(object)"cr_trail_sku"]?.ToString() ?? "")); string hexColor = ((!((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_color")) ? "" : (customProperties[(object)"cr_trail_color"]?.ToString() ?? "")); int price = 0; if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_price")) { try { price = Convert.ToInt32(customProperties[(object)"cr_trail_price"]); } catch { } } if (string.IsNullOrEmpty(text)) { return; } foreach (Player player in instance.players) { if (!((Object)(object)player == (Object)null)) { PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.OwnerActorNr == actor) { AttachTrail(((Component)player).transform, actor, text, hexColor, price); Plugin.Log.LogInfo((object)$"[TRAIL] Re-attached for actor={actor} (late props) sku={text}"); break; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL] ReattachForActor failed: " + ex.Message)); } } public static void OnMatchEnd() { try { foreach (KeyValuePair item in attached) { if ((Object)(object)item.Value != (Object)null) { Object.Destroy((Object)(object)item.Value); } } attached.Clear(); Plugin.Log.LogInfo((object)"[TRAIL] All detached"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL] OnMatchEnd error: " + ex.Message)); } } private static IEnumerator DelayedAttachAll() { for (int i = 0; i < 30; i++) { yield return null; } PlayerManager instance = PlayerManager.instance; if ((Object)(object)instance == (Object)null || instance.players == null) { yield break; } foreach (Player player in instance.players) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } int ownerActorNr = component.OwnerActorNr; Player val = null; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val2 in playerList) { if (val2 != null && val2.ActorNumber == ownerActorNr) { val = val2; break; } } string text = ""; string hexColor = ""; int price = 0; if (component.IsMine) { ApiClient.PlayerStatsData cachedPlayerStats = ApiClient.CachedPlayerStats; text = cachedPlayerStats?.active_trail_sku ?? ""; hexColor = cachedPlayerStats?.active_trail_color ?? ""; price = cachedPlayerStats?.active_trail_price ?? 0; } else if (val != null && val.CustomProperties != null) { Hashtable customProperties = val.CustomProperties; if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_sku")) { text = customProperties[(object)"cr_trail_sku"]?.ToString() ?? ""; } if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_color")) { hexColor = customProperties[(object)"cr_trail_color"]?.ToString() ?? ""; } if (((Dictionary)(object)customProperties).ContainsKey((object)"cr_trail_price")) { try { price = Convert.ToInt32(customProperties[(object)"cr_trail_price"]); } catch { price = 0; } } } if (!string.IsNullOrEmpty(text)) { AttachTrail(((Component)player).transform, ownerActorNr, text, hexColor, price); } } } private static void AttachTrail(Transform playerT, int actor, string sku, string hexColor, int price) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)playerT == (Object)null)) { if (attached.TryGetValue(actor, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } GameObject val = new GameObject($"CR_Trail_{actor}_{sku}"); val.transform.SetParent(playerT, false); val.transform.localPosition = Vector3.zero; TrailRenderer val2 = val.AddComponent(); float num = 0.35f; if (price >= 10000) { num = 0.9f; } else if (price >= 5000) { num = 0.6f; } else if (price >= 3000) { num = 0.35f; } val2.time = num; val2.startWidth = 0.5f; val2.endWidth = 0f; val2.minVertexDistance = 0.05f; val2.autodestruct = false; val2.emitting = true; Material val3 = new Material(Shader.Find("Sprites/Default")); Color white = Color.white; if (!string.IsNullOrEmpty(hexColor)) { ColorUtility.TryParseHtmlString(hexColor, ref white); } Gradient val4 = BuildGradientForSku(sku, white); val3.color = ((val4 != null) ? Color.white : white); ((Renderer)val2).material = val3; if (val4 != null) { val2.colorGradient = val4; } else { val2.startColor = white; val2.endColor = new Color(white.r, white.g, white.b, 0f); } attached[actor] = val; if (sku == "trail_prism") { val.AddComponent().Target = val2; } switch (sku) { case "trail_phoenix": case "trail_void": case "trail_prism": case "trail_tride": AttachParticles(val.transform, sku); break; } Plugin.Log.LogInfo((object)string.Format("[TRAIL] Attached actor={0} sku={1} color={2} len={3:F2}s gradient={4}", actor, sku, hexColor, num, (val4 != null) ? "yes" : "no")); } } private static void AttachParticles(Transform parent, string sku) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_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_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: 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_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Expected O, but got Unknown //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Expected O, but got Unknown //IL_047d: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("CR_TrailFX_" + sku); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; ParticleSystem val2 = val.AddComponent(); val2.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = val2.main; ((MainModule)(ref main)).duration = 1f; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit((sku == "trail_void") ? 0.7f : 0.5f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit((sku == "trail_void") ? 0.6f : 1.4f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit((sku == "trail_void") ? 0.18f : 0.12f); ((MainModule)(ref main)).maxParticles = 80; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)1; Color val3 = default(Color); switch (sku) { case "trail_phoenix": ((Color)(ref val3))..ctor(1f, 0.65f, 0.15f, 1f); break; case "trail_void": ((Color)(ref val3))..ctor(0.6f, 0.25f, 0.95f, 1f); break; case "trail_tride": ((Color)(ref val3))..ctor(0.95f, 0.78f, 0.87f, 1f); break; default: ((Color)(ref val3))..ctor(1f, 1f, 1f, 1f); break; } ((MainModule)(ref main)).startColor = new MinMaxGradient(val3); EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit((sku == "trail_void") ? 14f : 22f); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.25f; ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val4 = new Gradient(); if (sku == "trail_prism") { val4.SetKeys((GradientColorKey[])(object)new GradientColorKey[6] { new GradientColorKey(Color.red, 0f), new GradientColorKey(Color.yellow, 0.2f), new GradientColorKey(Color.green, 0.4f), new GradientColorKey(Color.cyan, 0.6f), new GradientColorKey(new Color(0.55f, 0.4f, 1f), 0.8f), new GradientColorKey(new Color(1f, 0.4f, 0.85f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.95f, 0f), new GradientAlphaKey(0f, 1f) }); } else if (sku == "trail_tride") { val4.SetKeys((GradientColorKey[])(object)new GradientColorKey[3] { new GradientColorKey(ParseHex("#55CDFC"), 0f), new GradientColorKey(ParseHex("#F7A8B8"), 0.5f), new GradientColorKey(Color.white, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.95f, 0f), new GradientAlphaKey(0f, 1f) }); } else { val4.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(val3, 0f), new GradientColorKey(val3, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.95f, 0f), new GradientAlphaKey(0f, 1f) }); } ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val4); SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; AnimationCurve val5 = new AnimationCurve((Keyframe[])(object)new Keyframe[2] { new Keyframe(0f, 1f), new Keyframe(1f, 0f) }); ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val5); ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Material val6 = new Material(Shader.Find("Sprites/Default")); val6.color = Color.white; ((Renderer)component).material = val6; ((Renderer)component).sortingOrder = 1; } val2.Play(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL] AttachParticles failed for " + sku + ": " + ex.Message)); } } private static Gradient BuildGradientForSku(string sku, Color baseColor) { //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) return (Gradient)(sku switch { "trail_phoenix" => MakeGradient((Color[])(object)new Color[3] { new Color(1f, 0.95f, 0.2f), new Color(1f, 0.55f, 0.1f), new Color(0.9f, 0.15f, 0.05f) }, new float[3] { 0f, 0.5f, 1f }), "trail_void" => MakeGradient((Color[])(object)new Color[3] { new Color(0.75f, 0.35f, 1f), new Color(0.35f, 0.05f, 0.6f), new Color(0f, 0f, 0f) }, new float[3] { 0f, 0.55f, 1f }), "trail_colossus" => MakeGradient((Color[])(object)new Color[2] { ParseHex("#4CADD0"), ParseHex("#E3ECEC") }, new float[2] { 0f, 1f }), "trail_ascendant" => MakeGradient((Color[])(object)new Color[2] { ParseHex("#71FF9E"), ParseHex("#376655") }, new float[2] { 0f, 1f }), "trail_sovereign" => MakeGradient((Color[])(object)new Color[2] { ParseHex("#8E4CD0"), ParseHex("#B2F9FF") }, new float[2] { 0f, 1f }), "trail_titan" => MakeGradient((Color[])(object)new Color[2] { ParseHex("#FF4848"), ParseHex("#CC9AAB") }, new float[2] { 0f, 1f }), "trail_tride" => MakeGradient((Color[])(object)new Color[5] { ParseHex("#5BCEFA"), ParseHex("#F5A9B8"), ParseHex("#5BCEFA"), ParseHex("#F5A9B8"), ParseHex("#5BCEFA") }, new float[5] { 0f, 0.25f, 0.5f, 0.75f, 1f }), "trail_prism" => null, _ => null, }); } private static Color ParseHex(string hex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) Color white = Color.white; ColorUtility.TryParseHtmlString(hex, ref white); return white; } private static Gradient MakeGradient(Color[] colors, float[] times) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0020: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); GradientColorKey[] array = (GradientColorKey[])(object)new GradientColorKey[colors.Length]; GradientAlphaKey[] array2 = (GradientAlphaKey[])(object)new GradientAlphaKey[colors.Length]; for (int i = 0; i < colors.Length; i++) { array[i] = new GradientColorKey(colors[i], times[i]); float num = Mathf.Lerp(1f, 0f, times[i]); array2[i] = new GradientAlphaKey(num, times[i]); } val.SetKeys(array, array2); return val; } } internal class TrailPhotonCallbacks : MonoBehaviour, IInRoomCallbacks { private void OnEnable() { try { PhotonNetwork.AddCallbackTarget((object)this); } catch { } } private void OnDisable() { try { PhotonNetwork.RemoveCallbackTarget((object)this); } catch { } } public void OnPlayerPropertiesUpdate(Player target, Hashtable changedProps) { try { TrailCosmetic.OnPlayerPropertiesChanged(target, changedProps); } catch { } try { PlayerColorCosmetic.OnPlayerPropertiesChanged(target, changedProps); } catch { } try { PlayerEffectCosmetic.OnPlayerPropertiesChanged(target, changedProps); } catch { } } public void OnPlayerEnteredRoom(Player newPlayer) { } public void OnPlayerLeftRoom(Player otherPlayer) { } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } public void OnMasterClientSwitched(Player newMasterClient) { } } internal class PrismaticHueCycle : MonoBehaviour { public TrailRenderer Target; private float t; private void Update() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Target == (Object)null)) { t += Time.deltaTime * 0.6f; if (t > 1f) { t -= 1f; } Color val = Color.HSVToRGB(t, 0.85f, 1f); Target.startColor = val; Target.endColor = new Color(val.r, val.g, val.b, 0f); } } } internal static class TrailPreview { private static GameObject canvasGO; private static GameObject previewGO; private static string activeSku = ""; public static string ActiveSku => activeSku; public static bool IsActive => (Object)(object)previewGO != (Object)null; public static void Toggle(string sku, string hexColor, int price) { if (string.IsNullOrEmpty(sku)) { Stop(); return; } if (activeSku == sku && (Object)(object)previewGO != (Object)null) { Stop(); return; } Stop(); Start(sku, hexColor, price); } public static void Start(string sku, string hexColor, int price) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) try { Stop(); EnsureCanvas(); if (!((Object)(object)canvasGO == (Object)null)) { previewGO = new GameObject("CR_TrailPreviewUI_" + sku); previewGO.transform.SetParent(canvasGO.transform, false); previewGO.AddComponent(); Color white = Color.white; if (!string.IsNullOrEmpty(hexColor)) { ColorUtility.TryParseHtmlString(hexColor, ref white); } float num = 0.45f; if (price >= 10000) { num = 0.9f; } else if (price >= 5000) { num = 0.6f; } CursorTrailUI cursorTrailUI = previewGO.AddComponent(); cursorTrailUI.lifetime = num; cursorTrailUI.dotSizeStart = 26f; cursorTrailUI.dotSizeEnd = 4f; cursorTrailUI.maxDots = 36; ConfigureColorsForSku(cursorTrailUI, sku, white); activeSku = sku; Plugin.Log.LogInfo((object)$"[TRAIL-PREVIEW] Started sku={sku} lifetime={num:F2}s (uGUI)"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL-PREVIEW] Start failed: " + ex.Message)); Stop(); } } public static void Stop() { if ((Object)(object)previewGO != (Object)null) { try { Object.Destroy((Object)(object)previewGO); } catch { } previewGO = null; } activeSku = ""; } private static void EnsureCanvas() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if ((Object)(object)canvasGO != (Object)null) { return; } try { canvasGO = new GameObject("CR_TrailPreviewCanvas"); ((Object)canvasGO).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)canvasGO); if (UIFactory.tCanvas != null) { Component obj = canvasGO.AddComponent(UIFactory.tCanvas); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; PropertyInfo property = UIFactory.tCanvas.GetProperty("renderMode", bindingAttr); property?.SetValue(obj, Enum.ToObject(property.PropertyType, 0)); UIFactory.tCanvas.GetProperty("sortingOrder", bindingAttr)?.SetValue(obj, 30001); } if (UIFactory.tCanvasScaler != null) { Component obj2 = canvasGO.AddComponent(UIFactory.tCanvasScaler); BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public; PropertyInfo property2 = UIFactory.tCanvasScaler.GetProperty("uiScaleMode", bindingAttr2); if (property2 != null) { property2.SetValue(obj2, Enum.ToObject(property2.PropertyType, 0)); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[TRAIL-PREVIEW] Canvas create failed: " + ex.Message)); } } private static void ConfigureColorsForSku(CursorTrailUI fx, string sku, Color baseColor) { //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_0542: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0215: 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_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) switch (sku) { case "trail_phoenix": fx.startColor = new Color(1f, 0.95f, 0.2f); fx.midColor = new Color(1f, 0.55f, 0.1f); fx.endColor = new Color(0.9f, 0.15f, 0.05f, 0f); break; case "trail_void": fx.startColor = new Color(0.75f, 0.35f, 1f); fx.midColor = new Color(0.35f, 0.05f, 0.6f); fx.endColor = new Color(0f, 0f, 0f, 0f); break; case "trail_colossus": fx.startColor = Hex("#4CADD0"); fx.midColor = Color.Lerp(Hex("#4CADD0"), Hex("#E3ECEC"), 0.5f); fx.endColor = new Color(Hex("#E3ECEC").r, Hex("#E3ECEC").g, Hex("#E3ECEC").b, 0f); break; case "trail_ascendant": fx.startColor = Hex("#71FF9E"); fx.midColor = Color.Lerp(Hex("#71FF9E"), Hex("#376655"), 0.5f); fx.endColor = new Color(Hex("#376655").r, Hex("#376655").g, Hex("#376655").b, 0f); break; case "trail_sovereign": fx.startColor = Hex("#8E4CD0"); fx.midColor = Color.Lerp(Hex("#8E4CD0"), Hex("#B2F9FF"), 0.5f); fx.endColor = new Color(Hex("#B2F9FF").r, Hex("#B2F9FF").g, Hex("#B2F9FF").b, 0f); break; case "trail_titan": fx.startColor = Hex("#FF4848"); fx.midColor = Color.Lerp(Hex("#FF4848"), Hex("#CC9AAB"), 0.5f); fx.endColor = new Color(Hex("#CC9AAB").r, Hex("#CC9AAB").g, Hex("#CC9AAB").b, 0f); break; case "trail_tride": fx.cycleColors = (Color[])(object)new Color[16] { Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#5BCEFA"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8"), Hex("#F5A9B8") }; fx.preserveSpawnColor = true; fx.startColor = Hex("#5BCEFA"); fx.midColor = Hex("#F5A9B8"); fx.endColor = new Color(0f, 0f, 0f, 0f); break; case "trail_prism": fx.cyclePrismatic = true; fx.startColor = Color.red; fx.midColor = Color.white; fx.endColor = new Color(1f, 0f, 1f, 0f); break; default: fx.startColor = baseColor; fx.midColor = baseColor; fx.endColor = new Color(baseColor.r, baseColor.g, baseColor.b, 0f); break; } } private static Color Hex(string h) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) Color white = Color.white; ColorUtility.TryParseHtmlString(h, ref white); return white; } } internal class CursorTrailUI : MonoBehaviour { private struct DotEntry { public GameObject go; public RectTransform rt; public Component img; public float spawnedAt; public Color spawnColor; public bool active; } public Color startColor = Color.white; public Color midColor = Color.white; public Color endColor = new Color(1f, 1f, 1f, 0f); public float lifetime = 0.5f; public float dotSizeStart = 28f; public float dotSizeEnd = 4f; public int maxDots = 120; public bool cyclePrismatic; public Color[] cycleColors; public bool preserveSpawnColor; private const float SAMPLE_STEP = 3f; private const float MAX_FILL_DOTS = 30f; private DotEntry[] dots; private int nextSlot; private int spawnIndex; private Vector2 lastSpawnPos = new Vector2(float.NegativeInfinity, float.NegativeInfinity); private float prismT; private static PropertyInfo s_imgColorProp; private static PropertyInfo s_imgSpriteProp; private static PropertyInfo s_imgRayProp; private static Sprite s_dotSprite; private void Awake() { EnsureSprite(); dots = new DotEntry[maxDots]; for (int i = 0; i < maxDots; i++) { dots[i] = MakeDot(i); } } private static void EnsureSprite() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_dotSprite != (Object)null) { return; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Color32[] array = (Color32[])(object)new Color32[4096]; float num = 31.5f; float num2 = 31.5f; float num3 = 32f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num4 = (float)j - num; float num5 = (float)i - num2; float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5) / num3; float num7 = Mathf.Clamp01(1f - num6); num7 *= num7; array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num7 * 255f)); } } val.SetPixels32(array); val.Apply(false, true); s_dotSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); ((Object)s_dotSprite).hideFlags = (HideFlags)61; } private DotEntry MakeDot(int i) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"d{i}"); val.transform.SetParent(((Component)this).transform, false); RectTransform val2 = val.AddComponent(); val2.sizeDelta = new Vector2(dotSizeStart, dotSizeStart); DotEntry result = new DotEntry { go = val, rt = val2, active = false }; if (UIFactory.tImage != null) { Component obj = (result.img = val.AddComponent(UIFactory.tImage)); if (s_imgColorProp == null) { s_imgColorProp = UIFactory.tImage.GetProperty("color", BindingFlags.Instance | BindingFlags.Public); } if (s_imgSpriteProp == null) { s_imgSpriteProp = UIFactory.tImage.GetProperty("sprite", BindingFlags.Instance | BindingFlags.Public); } if (s_imgRayProp == null) { s_imgRayProp = UIFactory.tImage.GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public); } s_imgRayProp?.SetValue(obj, false); s_imgSpriteProp?.SetValue(obj, s_dotSprite); s_imgColorProp?.SetValue(obj, (object)new Color(1f, 1f, 1f, 0f)); } val.SetActive(false); return result; } private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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_0064: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(Input.mousePosition); if (cyclePrismatic) { prismT += Time.unscaledDeltaTime * 0.6f; if (prismT > 1f) { prismT -= 1f; } } if (float.IsNegativeInfinity(lastSpawnPos.x)) { lastSpawnPos = val; } int num = Mathf.Min(Mathf.FloorToInt(Vector2.Distance(lastSpawnPos, val) / 3f), 30); for (int i = 1; i <= num; i++) { float num2 = (float)i / (float)num; Vector2 pos = Vector2.Lerp(lastSpawnPos, val, num2); SpawnDot(pos); } if (num > 0) { lastSpawnPos = val; } for (int j = 0; j < dots.Length; j++) { if (!dots[j].active) { continue; } float num3 = (Time.unscaledTime - dots[j].spawnedAt) / lifetime; if (num3 >= 1f) { dots[j].active = false; dots[j].go.SetActive(false); continue; } Color val2; if (preserveSpawnColor) { val2 = dots[j].spawnColor; val2.a = Mathf.Lerp(dots[j].spawnColor.a, 0f, num3); } else { val2 = ((num3 < 0.5f) ? Color.Lerp(dots[j].spawnColor, midColor, num3 * 2f) : Color.Lerp(midColor, endColor, (num3 - 0.5f) * 2f)); } s_imgColorProp?.SetValue(dots[j].img, val2); float num4 = Mathf.Lerp(dotSizeStart, dotSizeEnd, num3); dots[j].rt.sizeDelta = new Vector2(num4, num4); } } private void SpawnDot(Vector2 pos) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_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_006d: 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) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00dd: Unknown result type (might be due to invalid IL or missing references) Color val = ((cycleColors != null && cycleColors.Length != 0) ? cycleColors[spawnIndex % cycleColors.Length] : ((!cyclePrismatic) ? startColor : Color.HSVToRGB(prismT, 0.85f, 1f))); DotEntry dotEntry = dots[nextSlot]; ((Transform)dotEntry.rt).position = new Vector3(pos.x, pos.y, 0f); dotEntry.rt.sizeDelta = new Vector2(dotSizeStart, dotSizeStart); dotEntry.spawnedAt = Time.unscaledTime; dotEntry.spawnColor = val; dotEntry.active = true; dotEntry.go.SetActive(true); s_imgColorProp?.SetValue(dotEntry.img, val); dots[nextSlot] = dotEntry; nextSlot = (nextSlot + 1) % dots.Length; spawnIndex++; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }