using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using IAYBLeaderboard.Steam;
using IAYBLeaderboard.UI;
using Microsoft.CodeAnalysis;
using Progress;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 IAYBLeaderboard
{
public static class Log
{
public static Action<string> MsgSink = delegate
{
};
public static Action<string> ErrorSink = delegate
{
};
public static void Msg(string message)
{
MsgSink(message);
}
public static void Error(string message)
{
ErrorSink(message);
}
}
public class Mod
{
public const string Name = "Leaderboard";
public const string Version = "1.1.0";
public const string Author = "Draxi";
public const string Guid = "com.draxi.iaybleaderboard";
private LeaderboardPanel _panel;
private WorldPanel _worldPanel;
public static Mod Instance { get; private set; }
public SteamLeaderboardManager LeaderboardManager { get; private set; }
public bool SteamAvailable { get; private set; }
public LeaderboardPanel Panel => EnsurePanel();
public WorldPanel WorldPanel => EnsureWorldPanel();
private LeaderboardPanel EnsurePanel()
{
if (_panel == null)
{
_panel = new LeaderboardPanel();
}
return _panel;
}
private WorldPanel EnsureWorldPanel()
{
if (_worldPanel == null)
{
_worldPanel = new WorldPanel();
}
return _worldPanel;
}
public void Initialize()
{
Instance = this;
LeaderboardManager = new SteamLeaderboardManager();
try
{
SteamAvailable = SteamAPI.IsSteamRunning();
}
catch
{
SteamAvailable = false;
}
Log.Msg("Leaderboard mod loaded!");
}
public void OnSceneWasLoaded()
{
if (_panel != null && _panel.IsVisible)
{
_panel.Hide();
}
if (_worldPanel != null && _worldPanel.IsVisible)
{
_worldPanel.Hide();
}
}
public void OnUpdate()
{
if (SteamAvailable)
{
try
{
SteamAPI.RunCallbacks();
}
catch
{
}
}
LeaderboardManager?.ProcessQueue();
if (_panel != null && _panel.IsVisible && _panel.CurrentCacheKey != null && LeaderboardManager.IsCacheDirtyByKey(_panel.CurrentCacheKey))
{
LeaderboardManager.ClearDirtyByKey(_panel.CurrentCacheKey);
if ((Object)(object)_panel.CurrentLevelInfo != (Object)null)
{
_panel.RefreshForLevel(_panel.CurrentLevelInfo, _panel.CurrentCategory, _panel.CurrentLevelId);
}
}
if (_worldPanel != null && _worldPanel.IsVisible && _worldPanel.CurrentWorldCacheKey != null && LeaderboardManager.IsCacheDirtyByKey(_worldPanel.CurrentWorldCacheKey))
{
LeaderboardManager.ClearDirtyByKey(_worldPanel.CurrentWorldCacheKey);
if ((Object)(object)_worldPanel.CurrentLevelInfo != (Object)null)
{
_worldPanel.RefreshForLevel(_worldPanel.CurrentLevelInfo, _worldPanel.CurrentCategory, _worldPanel.CurrentLevelId);
}
}
}
public void Shutdown()
{
_panel?.Destroy();
_worldPanel?.Destroy();
}
}
}
namespace IAYBLeaderboard.UI
{
public static class GradeHelper
{
private static readonly string[] GradeLetters = new string[5] { "D", "C", "B", "A", "S" };
public static int GetGradeIndex(LevelInformation levelInfo, float time)
{
for (int num = 4; num >= 0; num--)
{
if (time <= levelInfo.GetTimeForGrade(num))
{
return num;
}
}
return 0;
}
public static int GetHordeGradeIndex(LevelInformation levelInfo, int score)
{
int[] hordeScoreThresholds = levelInfo.GetHordeScoreThresholds();
if (hordeScoreThresholds == null || hordeScoreThresholds.Length == 0)
{
return 0;
}
int num = 0;
for (int i = 0; i < hordeScoreThresholds.Length; i++)
{
if (score >= hordeScoreThresholds[i])
{
num = i + 1;
}
}
return Mathf.Clamp(num, 0, 4);
}
public static string GetGradeLetter(int gradeIndex)
{
return GradeLetters[Mathf.Clamp(gradeIndex, 0, 4)];
}
public static string GetGradeLetter(LevelInformation levelInfo, float time)
{
return GetGradeLetter(GetGradeIndex(levelInfo, time));
}
public static bool IsHorde(LevelInformation levelInfo)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Invalid comparison between Unknown and I4
if ((Object)(object)levelInfo != (Object)null)
{
return (int)levelInfo.GetLevelType() == 1;
}
return false;
}
public static bool IsGameplayLevel(LevelInformation levelInfo)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: 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_0017: Invalid comparison between Unknown and I4
if ((Object)(object)levelInfo == (Object)null)
{
return false;
}
LevelType levelType = levelInfo.GetLevelType();
if ((int)levelType != 0)
{
return (int)levelType == 1;
}
return true;
}
}
public class LeaderboardPanel
{
private GameObject _root;
private RectTransform _panelRect;
private GameObject _contentParent;
private GameObject _emptyStateObj;
private TextMeshProUGUI _emptyText;
private readonly List<GameObject> _rowObjects = new List<GameObject>();
private string _currentCategory;
private int _currentLevelId;
private LevelInformation _currentLevelInfo;
private string _currentCacheKey;
private static readonly Vector2 LevelSelectPos = new Vector2(-25.5f, -96f);
private static readonly Vector2 LevelCompletePos = new Vector2(-25.5f, -321f);
public static LeaderboardPanel Instance { get; private set; }
private bool IsCurrentHorde => GradeHelper.IsHorde(_currentLevelInfo);
public bool IsVisible
{
get
{
if ((Object)(object)_root != (Object)null)
{
return _root.activeSelf;
}
return false;
}
}
public string CurrentCategory => _currentCategory;
public int CurrentLevelId => _currentLevelId;
public LevelInformation CurrentLevelInfo => _currentLevelInfo;
public string CurrentCacheKey => _currentCacheKey;
public LeaderboardPanel()
{
Instance = this;
UIHelper.EnsureAssetsLoaded();
CreateUI();
}
private void CreateUI()
{
//IL_0022: 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_006b: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
Canvas val = UIHelper.CreatePanelCanvas("FriendsLeaderboardCanvas");
_root = ((Component)val).gameObject;
GameObject val2 = UIHelper.CreatePanelObject(_root.transform, LevelSelectPos);
_panelRect = val2.GetComponent<RectTransform>();
UIHelper.CreateHeader(val2.transform, "FRIENDS");
_contentParent = UIHelper.CreateContentParent(val2.transform);
_emptyStateObj = new GameObject("EmptyState");
_emptyStateObj.transform.SetParent(_contentParent.transform, false);
_emptyStateObj.AddComponent<RectTransform>();
LayoutElement obj = _emptyStateObj.AddComponent<LayoutElement>();
obj.preferredHeight = 40f;
obj.flexibleHeight = 0f;
_emptyText = UIHelper.CreateTMPText(_emptyStateObj, "", 12f, new Color(0.5f, 0.5f, 0.5f), (TextAlignmentOptions)514, (FontStyles)0);
Hide();
}
public void Show(LevelInformation levelInfo, string category, int levelId)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
SetLevel(levelInfo, category, levelId);
_panelRect.anchoredPosition = LevelSelectPos;
_root.SetActive(true);
ShowLoading();
Mod.Instance.LeaderboardManager.DownloadFriendScores(category, levelId, GradeHelper.IsHorde(levelInfo), OnScoresReceived);
}
public void RefreshForLevel(LevelInformation levelInfo, string category, int levelId)
{
SetLevel(levelInfo, category, levelId);
if (!_root.activeSelf)
{
_root.SetActive(true);
}
ShowLoading();
Mod.Instance.LeaderboardManager.DownloadFriendScores(category, levelId, GradeHelper.IsHorde(levelInfo), OnScoresReceived);
}
public void ShowForLevelComplete(LevelInformation levelInfo, string category, int levelId)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
SetLevel(levelInfo, category, levelId);
_panelRect.anchoredPosition = LevelCompletePos;
_root.SetActive(true);
ShowLoading();
Mod.Instance.LeaderboardManager.DownloadFriendScores(category, levelId, GradeHelper.IsHorde(levelInfo), OnScoresReceived);
}
public void Hide()
{
_root.SetActive(false);
_currentLevelInfo = null;
_currentCategory = null;
_currentLevelId = -1;
_currentCacheKey = null;
}
public void ShowEmptyState(string message)
{
ClearRows();
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = message;
_root.SetActive(true);
}
private void ShowLoading()
{
ClearRows();
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = "...";
}
private void SetLevel(LevelInformation levelInfo, string category, int levelId)
{
_currentLevelInfo = levelInfo;
_currentCategory = category;
_currentLevelId = levelId;
_currentCacheKey = $"{category}_{levelId}";
}
private void OnScoresReceived(List<FriendScore> scores)
{
ClearRows();
if (scores == null || scores.Count == 0)
{
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = "No friends have played this level";
return;
}
_emptyStateObj.SetActive(false);
if (IsCurrentHorde)
{
scores.Sort((FriendScore a, FriendScore b) => b.ScoreCentiseconds.CompareTo(a.ScoreCentiseconds));
}
else
{
scores.Sort((FriendScore a, FriendScore b) => a.ScoreCentiseconds.CompareTo(b.ScoreCentiseconds));
}
for (int num = 0; num < scores.Count && num < 8; num++)
{
CreateRow(scores[num], num);
}
}
private void CreateRow(FriendScore score, int index)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
//IL_00cf: 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_00ec: 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_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: 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_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Expected O, but got Unknown
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Expected O, but got Unknown
GameObject val = new GameObject($"Row_{index}");
val.transform.SetParent(_contentParent.transform, false);
_rowObjects.Add(val);
val.AddComponent<RectTransform>();
Image val2 = val.AddComponent<Image>();
LayoutElement obj = val.AddComponent<LayoutElement>();
obj.preferredHeight = 30f;
obj.flexibleHeight = 0f;
obj.minHeight = 30f;
HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj2).padding = new RectOffset(6, 8, 3, 3);
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f;
((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
if (score.IsLocalPlayer && index == 0)
{
((Graphic)val2).color = new Color(0.5f, 0.55f, 0.45f, 0.2f);
}
else if (score.IsLocalPlayer)
{
((Graphic)val2).color = UIHelper.BlueTransparent;
}
else if (index == 0)
{
((Graphic)val2).color = UIHelper.GoldTransparent;
}
else
{
((Graphic)val2).color = Color.clear;
}
int num = 0;
string letter = "?";
if ((Object)(object)_currentLevelInfo != (Object)null)
{
num = (IsCurrentHorde ? GradeHelper.GetHordeGradeIndex(_currentLevelInfo, score.ScoreCentiseconds) : GradeHelper.GetGradeIndex(_currentLevelInfo, score.TimeSeconds));
letter = GradeHelper.GetGradeLetter(num);
}
UIHelper.CreateGradeBadge(val.transform, letter, num);
GameObject val3 = new GameObject("Name");
val3.transform.SetParent(val.transform, false);
UIHelper.CreateTMPText(val3, score.IsLocalPlayer ? "You" : score.PlayerName, 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1);
val3.AddComponent<LayoutElement>().flexibleWidth = 1f;
string text = (IsCurrentHorde ? score.ScoreCentiseconds.ToString() : score.TimeSeconds.ToString("F2"));
GameObject val4 = new GameObject("Score");
val4.transform.SetParent(val.transform, false);
UIHelper.CreateTMPText(val4, text, 13f, Color.white, (TextAlignmentOptions)4100, (FontStyles)1);
val4.AddComponent<LayoutElement>().preferredWidth = 55f;
}
private void ClearRows()
{
foreach (GameObject rowObject in _rowObjects)
{
Object.Destroy((Object)(object)rowObject);
}
_rowObjects.Clear();
}
public void Destroy()
{
if ((Object)(object)_root != (Object)null)
{
Object.Destroy((Object)(object)_root);
}
}
}
public static class UIHelper
{
public static readonly Color GoldColor = new Color(0.832f, 0.659f, 0.141f, 1f);
public static readonly Color GoldTransparent = new Color(0.832f, 0.659f, 0.141f, 0.15f);
public static readonly Color BlueTransparent = new Color(0.3f, 0.5f, 0.8f, 0.2f);
public static readonly Color PureBg = new Color(0f, 0f, 0f, 1f);
public static readonly Color BadgeBg = new Color(0f, 0f, 0f, 1f);
public static readonly Color BorderWhite = new Color(0.7f, 0.7f, 0.7f, 1f);
public const float PanelWidth = 315f;
public const float HeaderHeight = 61.5f;
public const float RowHeight = 30f;
public const float BottomPadding = 20f;
public const int MaxRows = 8;
public static readonly float PanelHeight = 328.5f;
private static bool _assetsLoaded;
public static TMP_FontAsset GameFont { get; private set; }
public static Sprite BgSprite { get; private set; }
public static void EnsureAssetsLoaded()
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
if (_assetsLoaded)
{
return;
}
_assetsLoaded = true;
TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
foreach (TMP_Text val in array)
{
if ((Object)(object)val.font != (Object)null)
{
GameFont = val.font;
Log.Msg("[UIHelper] Found game font: " + ((Object)GameFont).name);
break;
}
}
Sprite[] array2 = Resources.FindObjectsOfTypeAll<Sprite>();
foreach (Sprite val2 in array2)
{
if (((Object)val2).name == "UI_MilitarySquare")
{
BgSprite = val2;
Log.Msg($"[UIHelper] Found UI_MilitarySquare sprite (border: {val2.border})");
break;
}
}
}
public static TextMeshProUGUI CreateTMPText(GameObject obj, string text, float fontSize, Color color, TextAlignmentOptions alignment = (TextAlignmentOptions)4097, FontStyles style = (FontStyles)0)
{
//IL_0016: 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_0025: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI val = obj.AddComponent<TextMeshProUGUI>();
((TMP_Text)val).text = text;
((TMP_Text)val).fontSize = fontSize;
((Graphic)val).color = color;
((TMP_Text)val).alignment = alignment;
((TMP_Text)val).fontStyle = style;
if ((Object)(object)GameFont != (Object)null)
{
((TMP_Text)val).font = GameFont;
}
return val;
}
public static void CreateGradeBadge(Transform parent, string letter, int gradeIdx)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: 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_0068: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: 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_00b6: 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_00cf: 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_00ef: 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_010f: Expected O, but got Unknown
//IL_0115: 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_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: 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_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("GradeBadge");
val.transform.SetParent(parent, false);
LayoutElement obj = val.AddComponent<LayoutElement>();
obj.preferredWidth = 24f;
obj.preferredHeight = 20f;
Image val2 = val.AddComponent<Image>();
GameObject val3 = new GameObject("Inner");
val3.transform.SetParent(val.transform, false);
RectTransform obj2 = val3.AddComponent<RectTransform>();
obj2.anchorMin = Vector2.zero;
obj2.anchorMax = Vector2.one;
obj2.offsetMin = new Vector2(1f, 1f);
obj2.offsetMax = new Vector2(-1f, -1f);
Image val4 = val3.AddComponent<Image>();
((Graphic)val4).color = BadgeBg;
GameObject val5 = new GameObject("Label");
val5.transform.SetParent(val.transform, false);
RectTransform obj3 = val5.AddComponent<RectTransform>();
obj3.anchorMin = Vector2.zero;
obj3.anchorMax = Vector2.one;
obj3.offsetMin = Vector2.zero;
obj3.offsetMax = Vector2.zero;
TextMeshProUGUI val6 = CreateTMPText(val5, letter, 11f, Color.white, (TextAlignmentOptions)514, (FontStyles)1);
if (gradeIdx >= 4)
{
((Graphic)val2).color = GoldColor;
((Graphic)val4).color = GoldColor;
((Graphic)val6).color = Color.black;
}
else if (gradeIdx >= 3)
{
((Graphic)val2).color = GoldColor;
((Graphic)val4).color = BadgeBg;
((Graphic)val6).color = GoldColor;
}
else
{
((Graphic)val2).color = BorderWhite;
((Graphic)val4).color = BadgeBg;
((Graphic)val6).color = Color.white;
}
}
public static Canvas CreatePanelCanvas(string name)
{
//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_000c: Expected O, but got Unknown
//IL_000c: 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)
GameObject val = new GameObject(name);
Object.DontDestroyOnLoad((Object)val);
Canvas val2 = val.AddComponent<Canvas>();
val2.renderMode = (RenderMode)0;
val2.sortingOrder = 100;
CanvasScaler obj = val.AddComponent<CanvasScaler>();
obj.uiScaleMode = (ScaleMode)1;
obj.referenceResolution = new Vector2(1920f, 1080f);
obj.matchWidthOrHeight = 0.5f;
return val2;
}
public static GameObject CreatePanelObject(Transform parent, Vector2 position)
{
//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_0017: 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_003d: 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_005d: 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_0077: 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_00ce: Expected O, but got Unknown
//IL_009c: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
GameObject val = new GameObject("Panel");
val.transform.SetParent(parent, false);
RectTransform obj = val.AddComponent<RectTransform>();
obj.anchorMin = new Vector2(1f, 1f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(1f, 1f);
obj.anchoredPosition = position;
obj.sizeDelta = new Vector2(315f, PanelHeight);
Image val2 = val.AddComponent<Image>();
if ((Object)(object)BgSprite != (Object)null)
{
val2.sprite = BgSprite;
val2.type = (Type)((BgSprite.border != Vector4.zero) ? 1 : 0);
((Graphic)val2).color = PureBg;
return val;
}
((Graphic)val2).color = PureBg;
return val;
}
public static GameObject CreateHeader(Transform parent, string title)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0029: 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_005e: 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_0082: 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_0096: 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_00af: 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_00c5: 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_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Expected O, but got Unknown
GameObject val = new GameObject("Header");
val.transform.SetParent(parent, false);
RectTransform obj = val.AddComponent<RectTransform>();
obj.anchorMin = new Vector2(0f, 1f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(0.5f, 1f);
obj.anchoredPosition = Vector2.zero;
obj.sizeDelta = new Vector2(0f, 61.5f);
((Graphic)val.AddComponent<Image>()).color = Color.clear;
GameObject val2 = new GameObject("Title");
val2.transform.SetParent(val.transform, false);
RectTransform obj2 = val2.AddComponent<RectTransform>();
obj2.anchorMin = Vector2.zero;
obj2.anchorMax = Vector2.one;
obj2.offsetMin = Vector2.zero;
obj2.offsetMax = Vector2.zero;
CreateTMPText(val2, title, 24f, Color.white, (TextAlignmentOptions)514, (FontStyles)1);
return val;
}
public static GameObject CreateContentParent(Transform parent)
{
//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_0017: 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_003d: 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_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Expected O, but got Unknown
GameObject val = new GameObject("Content");
val.transform.SetParent(parent, false);
RectTransform obj = val.AddComponent<RectTransform>();
obj.anchorMin = new Vector2(0f, 0f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(0.5f, 1f);
obj.offsetMin = new Vector2(0f, 20f);
obj.offsetMax = new Vector2(0f, -61.5f);
VerticalLayoutGroup obj2 = val.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
((LayoutGroup)obj2).childAlignment = (TextAnchor)0;
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 1f;
return val;
}
}
public class WorldPanel
{
private GameObject _root;
private RectTransform _panelRect;
private GameObject _contentParent;
private GameObject _emptyStateObj;
private TextMeshProUGUI _emptyText;
private readonly List<GameObject> _rowObjects = new List<GameObject>();
private string _currentCategory;
private int _currentLevelId;
private LevelInformation _currentLevelInfo;
private string _currentWorldCacheKey;
private static readonly Vector2 LevelSelectPos = new Vector2(-25.5f, -96f - UIHelper.PanelHeight - 6f);
private static readonly Vector2 LevelCompletePos = new Vector2(-25.5f, -321f - UIHelper.PanelHeight - 6f);
private const float SeparatorHeight = 10f;
public static WorldPanel Instance { get; private set; }
private bool IsCurrentHorde => GradeHelper.IsHorde(_currentLevelInfo);
public bool IsVisible
{
get
{
if ((Object)(object)_root != (Object)null)
{
return _root.activeSelf;
}
return false;
}
}
public string CurrentCategory => _currentCategory;
public int CurrentLevelId => _currentLevelId;
public LevelInformation CurrentLevelInfo => _currentLevelInfo;
public string CurrentWorldCacheKey => _currentWorldCacheKey;
public WorldPanel()
{
Instance = this;
UIHelper.EnsureAssetsLoaded();
CreateUI();
}
private void CreateUI()
{
//IL_0022: 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_006b: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
Canvas val = UIHelper.CreatePanelCanvas("WorldLeaderboardCanvas");
_root = ((Component)val).gameObject;
GameObject val2 = UIHelper.CreatePanelObject(_root.transform, LevelSelectPos);
_panelRect = val2.GetComponent<RectTransform>();
UIHelper.CreateHeader(val2.transform, "WORLD");
_contentParent = UIHelper.CreateContentParent(val2.transform);
_emptyStateObj = new GameObject("EmptyState");
_emptyStateObj.transform.SetParent(_contentParent.transform, false);
_emptyStateObj.AddComponent<RectTransform>();
LayoutElement obj = _emptyStateObj.AddComponent<LayoutElement>();
obj.preferredHeight = 40f;
obj.flexibleHeight = 0f;
_emptyText = UIHelper.CreateTMPText(_emptyStateObj, "", 12f, new Color(0.5f, 0.5f, 0.5f), (TextAlignmentOptions)514, (FontStyles)0);
Hide();
}
public void Show(LevelInformation levelInfo, string category, int levelId, bool isLevelComplete)
{
//IL_001a: 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)
SetLevel(levelInfo, category, levelId);
_panelRect.anchoredPosition = (isLevelComplete ? LevelCompletePos : LevelSelectPos);
_root.SetActive(true);
ShowLoading();
Mod.Instance.LeaderboardManager.DownloadWorldScores(category, levelId, GradeHelper.IsHorde(levelInfo), OnScoresReceived);
}
public void RefreshForLevel(LevelInformation levelInfo, string category, int levelId)
{
SetLevel(levelInfo, category, levelId);
if (!_root.activeSelf)
{
_root.SetActive(true);
}
ShowLoading();
Mod.Instance.LeaderboardManager.DownloadWorldScores(category, levelId, GradeHelper.IsHorde(levelInfo), OnScoresReceived);
}
public void Hide()
{
_root.SetActive(false);
_currentLevelInfo = null;
_currentCategory = null;
_currentLevelId = -1;
_currentWorldCacheKey = null;
}
public void ShowEmptyState(string message)
{
ClearRows();
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = message;
_root.SetActive(true);
}
private void ShowLoading()
{
ClearRows();
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = "...";
}
private void SetLevel(LevelInformation levelInfo, string category, int levelId)
{
_currentLevelInfo = levelInfo;
_currentCategory = category;
_currentLevelId = levelId;
_currentWorldCacheKey = $"world_{category}_{levelId}";
}
private void OnScoresReceived(List<FriendScore> scores)
{
ClearRows();
if (scores == null || scores.Count == 0)
{
_emptyStateObj.SetActive(true);
((TMP_Text)_emptyText).text = "No global scores yet";
return;
}
_emptyStateObj.SetActive(false);
int num = 0;
for (int i = 0; i < scores.Count; i++)
{
if (num >= 8)
{
break;
}
if (scores[i].Rank == -1)
{
CreateSeparator();
continue;
}
CreateRow(scores[i]);
num++;
}
}
private void CreateSeparator()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0060: 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_0077: 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_0089: 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_009e: 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_00d1: Expected O, but got Unknown
GameObject val = new GameObject("Separator");
val.transform.SetParent(_contentParent.transform, false);
_rowObjects.Add(val);
val.AddComponent<RectTransform>();
LayoutElement obj = val.AddComponent<LayoutElement>();
obj.preferredHeight = 10f;
obj.flexibleHeight = 0f;
obj.minHeight = 10f;
GameObject val2 = new GameObject("Dots");
val2.transform.SetParent(val.transform, false);
RectTransform obj2 = val2.AddComponent<RectTransform>();
obj2.anchorMin = Vector2.zero;
obj2.anchorMax = Vector2.one;
obj2.offsetMin = Vector2.zero;
obj2.offsetMax = Vector2.zero;
UIHelper.CreateTMPText(val2, "...", 8f, new Color(0.4f, 0.4f, 0.4f), (TextAlignmentOptions)514, (FontStyles)0);
}
private void CreateRow(FriendScore score)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_00da: 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_00fd: 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_0176: 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_018d: 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_01b8: Expected O, but got Unknown
//IL_01fa: 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_0211: 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_0229: Expected O, but got Unknown
GameObject val = new GameObject($"Row_{score.Rank}");
val.transform.SetParent(_contentParent.transform, false);
_rowObjects.Add(val);
val.AddComponent<RectTransform>();
Image val2 = val.AddComponent<Image>();
LayoutElement obj = val.AddComponent<LayoutElement>();
obj.preferredHeight = 30f;
obj.flexibleHeight = 0f;
obj.minHeight = 30f;
HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj2).padding = new RectOffset(6, 8, 3, 3);
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 4f;
((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
if (score.IsLocalPlayer && score.Rank == 1)
{
((Graphic)val2).color = new Color(0.5f, 0.55f, 0.45f, 0.2f);
}
else if (score.IsLocalPlayer)
{
((Graphic)val2).color = UIHelper.BlueTransparent;
}
else if (score.Rank == 1)
{
((Graphic)val2).color = UIHelper.GoldTransparent;
}
else
{
((Graphic)val2).color = Color.clear;
}
CreateRankBadge(val.transform, score.Rank);
int num = 0;
string letter = "?";
if ((Object)(object)_currentLevelInfo != (Object)null)
{
num = (IsCurrentHorde ? GradeHelper.GetHordeGradeIndex(_currentLevelInfo, score.ScoreCentiseconds) : GradeHelper.GetGradeIndex(_currentLevelInfo, score.TimeSeconds));
letter = GradeHelper.GetGradeLetter(num);
}
UIHelper.CreateGradeBadge(val.transform, letter, num);
GameObject val3 = new GameObject("Name");
val3.transform.SetParent(val.transform, false);
UIHelper.CreateTMPText(val3, score.IsLocalPlayer ? "You" : score.PlayerName, 12f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1);
val3.AddComponent<LayoutElement>().flexibleWidth = 1f;
string text = (IsCurrentHorde ? score.ScoreCentiseconds.ToString() : score.TimeSeconds.ToString("F2"));
GameObject val4 = new GameObject("Score");
val4.transform.SetParent(val.transform, false);
UIHelper.CreateTMPText(val4, text, 12f, Color.white, (TextAlignmentOptions)4100, (FontStyles)1);
val4.AddComponent<LayoutElement>().preferredWidth = 50f;
}
private void CreateRankBadge(Transform parent, int rank)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_003e: 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)
//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_0076: 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_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: 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_00d4: 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_00e6: 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_00fb: 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_0109: 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_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Expected O, but got Unknown
GameObject val = new GameObject("RankBadge");
val.transform.SetParent(parent, false);
val.AddComponent<LayoutElement>().preferredWidth = 28f;
val.GetComponent<LayoutElement>().preferredHeight = 20f;
((Graphic)val.AddComponent<Image>()).color = UIHelper.BorderWhite;
GameObject val2 = new GameObject("Inner");
val2.transform.SetParent(val.transform, false);
RectTransform obj = val2.AddComponent<RectTransform>();
obj.anchorMin = Vector2.zero;
obj.anchorMax = Vector2.one;
obj.offsetMin = new Vector2(1f, 1f);
obj.offsetMax = new Vector2(-1f, -1f);
((Graphic)val2.AddComponent<Image>()).color = UIHelper.BadgeBg;
GameObject val3 = new GameObject("Label");
val3.transform.SetParent(val.transform, false);
RectTransform obj2 = val3.AddComponent<RectTransform>();
obj2.anchorMin = Vector2.zero;
obj2.anchorMax = Vector2.one;
obj2.offsetMin = Vector2.zero;
obj2.offsetMax = Vector2.zero;
UIHelper.CreateTMPText(color: (rank == 1) ? UIHelper.GoldColor : Color.white, obj: val3, text: "#" + rank, fontSize: 9f, alignment: (TextAlignmentOptions)514, style: (FontStyles)1);
}
private void ClearRows()
{
foreach (GameObject rowObject in _rowObjects)
{
Object.Destroy((Object)(object)rowObject);
}
_rowObjects.Clear();
}
public void Destroy()
{
if ((Object)(object)_root != (Object)null)
{
Object.Destroy((Object)(object)_root);
}
}
}
}
namespace IAYBLeaderboard.Steam
{
public struct FriendScore
{
public CSteamID SteamId;
public string PlayerName;
public int ScoreCentiseconds;
public int Rank;
public bool IsLocalPlayer;
public float TimeSeconds => (float)ScoreCentiseconds / 100f;
}
public class SteamLeaderboardManager
{
private readonly Dictionary<string, List<FriendScore>> _cache = new Dictionary<string, List<FriendScore>>();
private readonly HashSet<string> _dirtyKeys = new HashSet<string>();
private List<FriendScore> _worldTopEntry;
private string _pendingWorldKey;
private readonly Dictionary<string, SteamLeaderboard_t> _boardHandles = new Dictionary<string, SteamLeaderboard_t>();
private readonly Queue<Action> _pendingOperations = new Queue<Action>();
private bool _operationInProgress;
private string _pendingDownloadKey;
private CallResult<LeaderboardFindResult_t> _findResult;
private CallResult<LeaderboardScoreUploaded_t> _uploadResult;
private CallResult<LeaderboardScoresDownloaded_t> _downloadResult;
private Action<SteamLeaderboard_t> _pendingBoardCallback;
private Action<List<FriendScore>> _currentDownloadCallback;
private string _currentCacheKey;
public static SteamLeaderboardManager Instance { get; private set; }
public SteamLeaderboardManager()
{
Instance = this;
_findResult = CallResult<LeaderboardFindResult_t>.Create((APIDispatchDelegate<LeaderboardFindResult_t>)OnLeaderboardFound);
_uploadResult = CallResult<LeaderboardScoreUploaded_t>.Create((APIDispatchDelegate<LeaderboardScoreUploaded_t>)OnScoreUploaded);
_downloadResult = CallResult<LeaderboardScoresDownloaded_t>.Create((APIDispatchDelegate<LeaderboardScoresDownloaded_t>)OnScoresDownloaded);
}
private static string MakeBoardName(string category, int levelId, bool isHorde)
{
if (!isHorde)
{
return $"iayb_friends_{category}_{levelId}";
}
return $"iayb_horde_{category}_{levelId}";
}
private static string MakeCacheKey(string category, int levelId)
{
return $"{category}_{levelId}";
}
private static void GetBoardSettings(bool isHorde, out ELeaderboardSortMethod sortMethod, out ELeaderboardDisplayType displayType)
{
sortMethod = (ELeaderboardSortMethod)((!isHorde) ? 1 : 2);
displayType = (ELeaderboardDisplayType)(isHorde ? 1 : 2);
}
public void UploadScore(string category, int levelId, float timeSeconds)
{
int num = (int)(timeSeconds * 100f);
UploadRawScore(category, levelId, num, isHorde: false, $"{num}cs ({timeSeconds:F2}s)");
}
public void UploadHordeScore(string category, int levelId, int score)
{
UploadRawScore(category, levelId, score, isHorde: true, $"{score}pts");
}
private void UploadRawScore(string category, int levelId, int score, bool isHorde, string displayStr)
{
string boardName = MakeBoardName(category, levelId, isHorde);
string cacheKey = MakeCacheKey(category, levelId);
Log.Msg("Queueing upload: " + boardName + " = " + displayStr);
GetBoardSettings(isHorde, out var sortMethod, out var displayType);
EnqueueOperation(delegate
{
//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)
_currentCacheKey = cacheKey;
FindOrCreateBoard(boardName, sortMethod, displayType, delegate(SteamLeaderboard_t handle)
{
//IL_0000: 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_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: 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)
SteamAPICall_t val = SteamUserStats.UploadLeaderboardScore(handle, (ELeaderboardUploadScoreMethod)1, score, (int[])null, 0);
if (val == SteamAPICall_t.Invalid)
{
Log.Error("[Upload] UploadLeaderboardScore returned invalid handle for " + boardName);
FinishOperation();
}
else
{
_uploadResult.Set(val, (APIDispatchDelegate<LeaderboardScoreUploaded_t>)null);
}
});
});
}
public void DownloadFriendScores(string category, int levelId, bool isHorde, Action<List<FriendScore>> callback)
{
string cacheKey = MakeCacheKey(category, levelId);
if (_cache.ContainsKey(cacheKey) && !_dirtyKeys.Contains(cacheKey))
{
Log.Msg($"[Download] Using cached scores for {cacheKey} ({_cache[cacheKey].Count} entries)");
callback?.Invoke(_cache[cacheKey]);
return;
}
if (_pendingDownloadKey == cacheKey)
{
Log.Msg("[Download] Already pending for " + cacheKey + ", skipping duplicate");
return;
}
string boardName = MakeBoardName(category, levelId, isHorde);
Log.Msg("[Download] Enqueueing download for " + boardName);
_pendingDownloadKey = cacheKey;
GetBoardSettings(isHorde, out var sortMethod, out var displayType);
EnqueueOperation(delegate
{
//IL_002f: 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)
_currentDownloadCallback = callback;
_currentCacheKey = cacheKey;
FindOrCreateBoard(boardName, sortMethod, displayType, delegate(SteamLeaderboard_t handle)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
Log.Msg("[Download] Calling DownloadLeaderboardEntries for " + boardName);
SteamAPICall_t val = SteamUserStats.DownloadLeaderboardEntries(handle, (ELeaderboardDataRequest)2, 0, 100);
if (val == SteamAPICall_t.Invalid)
{
Log.Error("[Download] DownloadLeaderboardEntries returned invalid handle for " + boardName);
_pendingDownloadKey = null;
FinishOperation();
}
else
{
_downloadResult.Set(val, (APIDispatchDelegate<LeaderboardScoresDownloaded_t>)null);
}
});
});
}
public void DownloadWorldScores(string category, int levelId, bool isHorde, Action<List<FriendScore>> callback)
{
string cacheKey = "world_" + MakeCacheKey(category, levelId);
if (_cache.ContainsKey(cacheKey) && !_dirtyKeys.Contains(cacheKey))
{
Log.Msg($"[World] Using cached scores for {cacheKey} ({_cache[cacheKey].Count} entries)");
callback?.Invoke(_cache[cacheKey]);
return;
}
if (_pendingWorldKey == cacheKey)
{
Log.Msg("[World] Already pending for " + cacheKey + ", skipping duplicate");
return;
}
string boardName = MakeBoardName(category, levelId, isHorde);
Log.Msg("[World] Enqueueing world download for " + boardName);
_pendingWorldKey = cacheKey;
GetBoardSettings(isHorde, out var sortMethod, out var displayType);
_worldTopEntry = null;
EnqueueOperation(delegate
{
//IL_0043: 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)
_currentCacheKey = null;
_currentDownloadCallback = delegate(List<FriendScore> topScores)
{
_worldTopEntry = topScores;
Log.Msg("[World] Got top entry: " + ((topScores != null && topScores.Count > 0) ? topScores[0].PlayerName : "none"));
};
FindOrCreateBoard(boardName, sortMethod, displayType, delegate(SteamLeaderboard_t handle)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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)
SteamAPICall_t val = SteamUserStats.DownloadLeaderboardEntries(handle, (ELeaderboardDataRequest)0, 1, 1);
if (val == SteamAPICall_t.Invalid)
{
Log.Error("[World] DownloadLeaderboardEntries (top) returned invalid handle");
_pendingWorldKey = null;
FinishOperation();
}
else
{
_downloadResult.Set(val, (APIDispatchDelegate<LeaderboardScoresDownloaded_t>)null);
}
});
});
EnqueueOperation(delegate
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
_currentCacheKey = cacheKey;
_currentDownloadCallback = delegate(List<FriendScore> aroundScores)
{
List<FriendScore> list = MergeWorldScores(_worldTopEntry, aroundScores);
_worldTopEntry = null;
_cache[cacheKey] = list;
_dirtyKeys.Remove(cacheKey);
_pendingWorldKey = null;
Log.Msg($"[World] Merged {list.Count} entries for {cacheKey}");
callback?.Invoke(list);
};
FindOrCreateBoard(boardName, sortMethod, displayType, delegate(SteamLeaderboard_t handle)
{
//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_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
SteamAPICall_t val = SteamUserStats.DownloadLeaderboardEntries(handle, (ELeaderboardDataRequest)1, -3, 3);
if (val == SteamAPICall_t.Invalid)
{
Log.Error("[World] DownloadLeaderboardEntries (around) returned invalid handle");
_pendingWorldKey = null;
FinishOperation();
}
else
{
_downloadResult.Set(val, (APIDispatchDelegate<LeaderboardScoresDownloaded_t>)null);
}
});
});
}
private List<FriendScore> MergeWorldScores(List<FriendScore> topScores, List<FriendScore> aroundScores)
{
List<FriendScore> list = new List<FriendScore>();
FriendScore? friendScore = null;
if (topScores != null && topScores.Count > 0)
{
friendScore = topScores[0];
}
if (aroundScores == null)
{
aroundScores = new List<FriendScore>();
}
bool flag = false;
if (friendScore.HasValue)
{
foreach (FriendScore aroundScore in aroundScores)
{
if (aroundScore.Rank == friendScore.Value.Rank)
{
flag = true;
break;
}
}
}
if (friendScore.HasValue && !flag)
{
list.Add(friendScore.Value);
list.Add(new FriendScore
{
Rank = -1,
PlayerName = "---"
});
}
list.AddRange(aroundScores);
return list;
}
public void InvalidateCache(string category, int levelId)
{
string text = MakeCacheKey(category, levelId);
_dirtyKeys.Add(text);
_dirtyKeys.Add("world_" + text);
}
public bool IsCacheDirtyByKey(string key)
{
return _dirtyKeys.Contains(key);
}
public void ClearDirtyByKey(string key)
{
_dirtyKeys.Remove(key);
}
private void FindOrCreateBoard(string boardName, ELeaderboardSortMethod sortMethod, ELeaderboardDisplayType displayType, Action<SteamLeaderboard_t> onFound)
{
//IL_0055: 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_0057: 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_0063: 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)
if (_boardHandles.ContainsKey(boardName))
{
Log.Msg("[FindBoard] Cache hit for " + boardName + ", calling onFound synchronously");
onFound(_boardHandles[boardName]);
return;
}
Log.Msg("[FindBoard] Cache miss for " + boardName + ", calling FindOrCreateLeaderboard");
_pendingBoardCallback = onFound;
SteamAPICall_t val = SteamUserStats.FindOrCreateLeaderboard(boardName, sortMethod, displayType);
_findResult.Set(val, (APIDispatchDelegate<LeaderboardFindResult_t>)null);
}
private void OnLeaderboardFound(LeaderboardFindResult_t result, bool ioFailure)
{
//IL_0003: 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_0028: 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_003b: 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_0062: Unknown result type (might be due to invalid IL or missing references)
if (ioFailure || result.m_bLeaderboardFound == 0)
{
Log.Error($"Failed to find/create leaderboard (ioFailure={ioFailure})");
FinishOperation();
return;
}
string leaderboardName = SteamUserStats.GetLeaderboardName(result.m_hSteamLeaderboard);
_boardHandles[leaderboardName] = result.m_hSteamLeaderboard;
Log.Msg("Leaderboard ready: " + leaderboardName);
try
{
_pendingBoardCallback?.Invoke(result.m_hSteamLeaderboard);
}
catch (Exception arg)
{
Log.Error($"Exception in board callback: {arg}");
FinishOperation();
}
_pendingBoardCallback = null;
}
private void OnScoreUploaded(LeaderboardScoreUploaded_t result, bool ioFailure)
{
//IL_0003: 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)
if (ioFailure || result.m_bSuccess == 0)
{
Log.Error($"Score upload failed (ioFailure={ioFailure})");
}
else
{
Log.Msg($"Score uploaded: {result.m_nScore}cs (changed={result.m_bScoreChanged})");
if (_currentCacheKey != null)
{
_dirtyKeys.Add(_currentCacheKey);
}
}
FinishOperation();
}
private void OnScoresDownloaded(LeaderboardScoresDownloaded_t result, bool ioFailure)
{
//IL_0011: 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_0037: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0063: 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_0094: 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_00c0: 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_00d5: 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)
List<FriendScore> list = new List<FriendScore>();
Log.Msg($"[OnScoresDownloaded] ioFailure={ioFailure}, entryCount={result.m_cEntryCount}, cacheKey={_currentCacheKey}");
if (!ioFailure)
{
CSteamID steamID = SteamUser.GetSteamID();
LeaderboardEntry_t val = default(LeaderboardEntry_t);
for (int i = 0; i < result.m_cEntryCount; i++)
{
SteamUserStats.GetDownloadedLeaderboardEntry(result.m_hSteamLeaderboardEntries, i, ref val, (int[])null, 0);
string friendPersonaName = SteamFriends.GetFriendPersonaName(val.m_steamIDUser);
bool flag = val.m_steamIDUser == steamID;
Log.Msg($"[OnScoresDownloaded] #{i}: {friendPersonaName} = {val.m_nScore}cs (rank={val.m_nGlobalRank}, isLocal={flag})");
list.Add(new FriendScore
{
SteamId = val.m_steamIDUser,
PlayerName = friendPersonaName,
ScoreCentiseconds = val.m_nScore,
Rank = val.m_nGlobalRank,
IsLocalPlayer = flag
});
}
}
else
{
Log.Error("[OnScoresDownloaded] Failed to download leaderboard entries");
}
if (_currentCacheKey != null)
{
_cache[_currentCacheKey] = list;
_dirtyKeys.Remove(_currentCacheKey);
}
_pendingDownloadKey = null;
Log.Msg($"[OnScoresDownloaded] Invoking callback with {list.Count} scores");
_currentDownloadCallback?.Invoke(list);
_currentDownloadCallback = null;
FinishOperation();
}
private void EnqueueOperation(Action op)
{
_pendingOperations.Enqueue(op);
TryProcessNext();
}
private void TryProcessNext()
{
if (!_operationInProgress && _pendingOperations.Count != 0)
{
_operationInProgress = true;
Log.Msg($"[Queue] Starting next operation ({_pendingOperations.Count} remaining after this)");
_pendingOperations.Dequeue()();
}
}
public void ProcessQueue()
{
TryProcessNext();
}
private void FinishOperation()
{
_operationInProgress = false;
}
}
}
namespace IAYBLeaderboard.Patches
{
[HarmonyPatch(typeof(GameManager), "Initialize")]
public static class InitPatches
{
[HarmonyPostfix]
public static void Postfix(GameManager __instance)
{
if ((Object)(object)__instance != (Object)(object)GameManager.instance || GameManager.instance.IsDRMFree())
{
return;
}
try
{
if (!SteamAPI.IsSteamRunning())
{
return;
}
}
catch
{
return;
}
Log.Msg("Bulk uploading existing scores to Steam leaderboards...");
ProgressManager progressManager = GameManager.instance.progressManager;
LevelCollection[] allCollections = progressManager.GetAllCollections();
int num = 0;
LevelCollection[] array = allCollections;
foreach (LevelCollection val in array)
{
LevelInformation[] allLevels = val.GetAllLevels();
foreach (LevelInformation val2 in allLevels)
{
if ((Object)(object)val2 == (Object)null || val2.GetLevelNumber() < 0 || !GradeHelper.IsGameplayLevel(val2))
{
continue;
}
LevelData levelData = progressManager.GetLevelData(val2);
if (levelData == null || !levelData.GetLevelCompleted())
{
continue;
}
string saveName = val.GetSaveName();
int levelNumber = val2.GetLevelNumber();
if (GradeHelper.IsHorde(val2))
{
int hordeScore = levelData.GetHordeScore();
if (hordeScore > 0)
{
Mod.Instance.LeaderboardManager.UploadHordeScore(saveName, levelNumber, hordeScore);
num++;
}
}
else
{
float bestTime = levelData.GetBestTime();
if (bestTime > 0f && bestTime < 999f)
{
Mod.Instance.LeaderboardManager.UploadScore(saveName, levelNumber, bestTime);
num++;
}
}
}
}
Log.Msg($"Queued {num} score uploads.");
}
}
[HarmonyPatch(typeof(UILevelCompleteScreen), "DisplayMenu")]
public static class LevelCompletePatches
{
[HarmonyPostfix]
public static void Postfix()
{
if (Mod.Instance == null)
{
return;
}
try
{
if (!SteamAPI.IsSteamRunning())
{
return;
}
}
catch
{
return;
}
LevelController levelController = GameManager.instance.levelController;
LevelInformation information = levelController.GetInformationSetter().GetInformation();
if (!((Object)(object)information == (Object)null) && information.GetLevelNumber() >= 0 && GradeHelper.IsGameplayLevel(information))
{
string levelCategoryName = information.GetLevelCategoryName();
int levelNumber = information.GetLevelNumber();
if (GradeHelper.IsHorde(information))
{
int score = levelController.GetHordeManager().GetScore();
Log.Msg($"Level complete (horde): {levelCategoryName}/{levelNumber} score={score} — uploading");
Mod.Instance.LeaderboardManager.UploadHordeScore(levelCategoryName, levelNumber, score);
}
else
{
float time = levelController.GetCombatTimer().GetTime(true);
Log.Msg($"Level complete: {levelCategoryName}/{levelNumber} in {time:F2}s — uploading");
Mod.Instance.LeaderboardManager.UploadScore(levelCategoryName, levelNumber, time);
}
Mod.Instance.LeaderboardManager.InvalidateCache(levelCategoryName, levelNumber);
Mod.Instance.Panel.ShowForLevelComplete(information, levelCategoryName, levelNumber);
Mod.Instance.WorldPanel.Show(information, levelCategoryName, levelNumber, isLevelComplete: true);
}
}
}
[HarmonyPatch(typeof(UILevelSelectFeature), "Refresh")]
public static class LevelSelectFeatureRefreshPatch
{
[HarmonyPostfix]
public static void Postfix(UILevelSelectFeature __instance, SceneInformation info)
{
LeaderboardPanel leaderboardPanel = Mod.Instance?.Panel;
WorldPanel worldPanel = Mod.Instance?.WorldPanel;
if (leaderboardPanel == null)
{
return;
}
try
{
if (!SteamAPI.IsSteamRunning())
{
leaderboardPanel.Hide();
worldPanel?.Hide();
return;
}
}
catch
{
leaderboardPanel.Hide();
worldPanel?.Hide();
return;
}
if (!((Object)(object)info == (Object)null))
{
LevelInformation val = (LevelInformation)(object)((info is LevelInformation) ? info : null);
if (val != null)
{
if (!GradeHelper.IsGameplayLevel(val))
{
leaderboardPanel.Hide();
worldPanel?.Hide();
return;
}
if (val.GetLevelNumber() < 0)
{
leaderboardPanel.Hide();
worldPanel?.Hide();
return;
}
string levelCategoryName = val.GetLevelCategoryName();
int levelNumber = val.GetLevelNumber();
LevelData levelData = GameManager.instance.progressManager.GetLevelData(val);
if (levelData == null || !levelData.GetLevelCompleted())
{
leaderboardPanel.ShowEmptyState("Complete this level to see rankings");
worldPanel?.ShowEmptyState("");
}
else
{
leaderboardPanel.Show(val, levelCategoryName, levelNumber);
worldPanel?.Show(val, levelCategoryName, levelNumber, isLevelComplete: false);
}
return;
}
}
leaderboardPanel.Hide();
worldPanel?.Hide();
}
}
[HarmonyPatch(typeof(UILevelSelectionRoot), "SelectCategory")]
public static class LevelSelectCategoryPatch
{
[HarmonyPostfix]
public static void Postfix(UILevelSelectionRoot __instance)
{
LeaderboardPanel leaderboardPanel = Mod.Instance?.Panel;
WorldPanel worldPanel = Mod.Instance?.WorldPanel;
if (leaderboardPanel == null)
{
return;
}
try
{
if (!SteamAPI.IsSteamRunning())
{
return;
}
}
catch
{
return;
}
SceneInformation featured = __instance.GetFeatured();
LevelInformation val = (LevelInformation)(object)((featured is LevelInformation) ? featured : null);
if (val != null && GradeHelper.IsGameplayLevel(val) && val.GetLevelNumber() >= 0)
{
LevelData levelData = GameManager.instance.progressManager.GetLevelData(val);
if (levelData != null && levelData.GetLevelCompleted())
{
string levelCategoryName = val.GetLevelCategoryName();
int levelNumber = val.GetLevelNumber();
leaderboardPanel.RefreshForLevel(val, levelCategoryName, levelNumber);
worldPanel?.RefreshForLevel(val, levelCategoryName, levelNumber);
}
else
{
leaderboardPanel.ShowEmptyState("Complete this level to see rankings");
worldPanel?.ShowEmptyState("");
}
}
}
}
[HarmonyPatch(typeof(UILevelSelectionRoot), "OpenCategoryList")]
public static class LevelSelectOpenCategoryPatch
{
[HarmonyPostfix]
public static void Postfix()
{
Mod.Instance?.Panel?.Hide();
Mod.Instance?.WorldPanel?.Hide();
}
}
}
namespace IAYBLeaderboard.Loaders
{
[BepInPlugin("com.draxi.iaybleaderboard", "Leaderboard", "1.1.0")]
[BepInProcess("I Am Your Beast.exe")]
public class BepInExEntry : BaseUnityPlugin
{
private Mod _mod;
private Harmony _harmony;
private void Awake()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: 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_0095: Expected O, but got Unknown
Log.MsgSink = ((BaseUnityPlugin)this).Logger.LogInfo;
Log.ErrorSink = ((BaseUnityPlugin)this).Logger.LogError;
_mod = new Mod();
_mod.Initialize();
_harmony = new Harmony("com.draxi.iaybleaderboard");
_harmony.PatchAll(typeof(BepInExEntry).Assembly);
SceneManager.sceneLoaded += OnSceneLoaded;
GameObject val = new GameObject("IAYBLeaderboard.Runner")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<BepInExRunner>().Mod = _mod;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_mod.OnSceneWasLoaded();
}
}
internal sealed class BepInExRunner : MonoBehaviour
{
public Mod Mod;
private void Update()
{
Mod.OnUpdate();
}
private void OnApplicationQuit()
{
Mod.Shutdown();
}
}
}