using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalCasinoTracker.Patches; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace LethalCasinoTracker { public enum CasinoGameType { Unknown, Blackjack, Roulette, Slots, Wheel } public static class CasinoGameNames { public static string Display(CasinoGameType t) { return t switch { CasinoGameType.Blackjack => "Blackjack", CasinoGameType.Roulette => "Roulette", CasinoGameType.Slots => "Slots", CasinoGameType.Wheel => "The Wheel", _ => "Casino", }; } public static CasinoGameType FromTypeName(string typeName) { return typeName switch { "Blackjack" => CasinoGameType.Blackjack, "Roulette" => CasinoGameType.Roulette, "SlotMachine" => CasinoGameType.Slots, "TheWheel" => CasinoGameType.Wheel, _ => CasinoGameType.Unknown, }; } } public static class CasinoHooks { public struct ScrapCapture { public bool valid; public GrabbableObject grab; public int before; } public static readonly string[] GameTypeNames = new string[4] { "Blackjack", "Roulette", "SlotMachine", "TheWheel" }; private static readonly Dictionary _fieldCache = new Dictionary(); private static readonly Dictionary _lastValue = new Dictionary(); public static void ResetValueTracking() { _lastValue.Clear(); } public static void ScrapPrefix(NetworkBehaviourReference item, out ScrapCapture __state) { __state = default(ScrapCapture); try { GrabbableObject val = default(GrabbableObject); if (((NetworkBehaviourReference)(ref item)).TryGet(ref val, (NetworkManager)null) && (Object)(object)val != (Object)null) { __state.valid = true; __state.grab = val; __state.before = val.scrapValue; } } catch { } } public static void ScrapPostfix(object __instance, int newValue, ScrapCapture __state) { if (!__state.valid || (Object)(object)__state.grab == (Object)null || !TrackerManager.IsServer()) { return; } try { GrabbableObject grab = __state.grab; int scrapValue = grab.scrapValue; if (!_lastValue.TryGetValue(grab, out var value)) { value = __state.before; } int num = scrapValue - value; _lastValue[grab] = scrapValue; string name = __instance.GetType().Name; if (Plugin.VerboseLogging) { Plugin.Log.LogInfo((object)("[bet] " + name + " baseline=" + value + " after=" + scrapValue + " newArg=" + newValue + " orig=" + ReadOriginal(grab) + " delta=" + num)); } if (num == 0) { return; } CasinoGameType game = CasinoGameNames.FromTypeName(name); PlayerControllerB val = ResolveOwner(__instance, name, grab); if ((Object)(object)val == (Object)null) { if (Plugin.VerboseLogging) { Plugin.Log.LogWarning((object)("Could not resolve owner for a " + name + " payout of " + num)); } return; } int num2 = 0; Object val2 = (Object)((__instance is Object) ? __instance : null); if (val2 != (Object)null) { num2 = val2.GetInstanceID(); } ulong playerClientId = val.playerClientId; string playerUsername = val.playerUsername; if ((Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.RecordResolution(playerClientId, playerUsername, num, game, num2); } NetworkSync.BroadcastDelta(playerClientId, playerUsername, num, game, num2); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Casino capture error: " + ex.Message)); } } private static PlayerControllerB ResolveOwner(object inst, string typeName, GrabbableObject grab) { Type type = inst.GetType(); switch (typeName) { case "Blackjack": { List[] array = GetField(type, "gambledScrap").GetValue(inst) as List[]; PlayerControllerB[] array2 = GetField(type, "gamblingPlayers").GetValue(inst) as PlayerControllerB[]; if (array == null || array2 == null) { return null; } int num = Math.Min(array.Length, array2.Length); for (int i = 0; i < num; i++) { if (array[i] != null && array[i].Contains(grab)) { return array2[i]; } } return null; } case "Roulette": { if (GetField(type, "gambledScrapOwners").GetValue(inst) is Dictionary dictionary && dictionary.TryGetValue(grab, out var value2)) { return value2; } return null; } case "SlotMachine": case "TheWheel": { FieldInfo field = GetField(type, "gamblingPlayer"); if (!(field == null)) { object? value = field.GetValue(inst); return (PlayerControllerB)((value is PlayerControllerB) ? value : null); } return null; } default: return null; } } private static int ReadOriginal(GrabbableObject grab) { try { Type type = AccessTools.TypeByName("LethalCasino.Custom.CustomScrapController"); if (type == null) { return -1; } Component component = ((Component)grab).GetComponent(type); if ((Object)(object)component == (Object)null) { return -1; } FieldInfo field = GetField(type, "originalScrapValue"); if (field == null) { return -1; } object value = field.GetValue(component); return (value is int) ? ((int)value) : (-1); } catch { return -1; } } private static FieldInfo GetField(Type t, string name) { string key = t.FullName + "." + name; if (!_fieldCache.TryGetValue(key, out var value)) { value = AccessTools.Field(t, name); _fieldCache[key] = value; } return value; } public static void ApplyPatches(Harmony h) { //IL_00a8: 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_00bb: Expected O, but got Unknown //IL_00bb: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(CasinoHooks), "ScrapPrefix", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(CasinoHooks), "ScrapPostfix", (Type[])null, (Type[])null); for (int i = 0; i < GameTypeNames.Length; i++) { string text = "LethalCasino.Custom." + GameTypeNames[i]; Type type = AccessTools.TypeByName(text); if (type == null) { Plugin.Log.LogWarning((object)("Casino type not found: " + text)); continue; } MethodInfo methodInfo3 = AccessTools.Method(type, "UpdateScrapValueClientRpc", (Type[])null, (Type[])null); if (methodInfo3 == null) { Plugin.Log.LogWarning((object)("UpdateScrapValueClientRpc not found on " + text)); continue; } try { h.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo), new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Patched " + GameTypeNames[i] + ".UpdateScrapValueClientRpc")); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to patch " + text + ": " + ex.Message)); } } } } public class ChalkboardController : MonoBehaviour { private Type _buildingType; private Component _building; private float _nextSearch; private GameObject _board; private TextMeshProUGUI _text; private bool _dirty = true; private void Start() { _buildingType = AccessTools.TypeByName("LethalCasino.Custom.CasinoBuilding"); if (_buildingType == null) { Plugin.Log.LogWarning((object)"CasinoBuilding type not found; chalkboard disabled."); } } private void Update() { //IL_00d0: 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_00e0: 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_00f4: 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_00ff: 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_010e: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0165: 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_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) if (!Plugin.ChalkboardEnabled() || _buildingType == null) { return; } if ((Object)(object)_building == (Object)null && Time.realtimeSinceStartup >= _nextSearch) { _nextSearch = Time.realtimeSinceStartup + 1.5f; ref Component building = ref _building; Object obj = Object.FindObjectOfType(_buildingType); building = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)_building != (Object)null && (Object)(object)_board == (Object)null) { BuildBoard(); } } if ((Object)(object)_building == (Object)null) { if ((Object)(object)_board != (Object)null) { Object.Destroy((Object)(object)_board); _board = null; } } else if (!((Object)(object)_board == (Object)null)) { Transform transform = _building.transform; _board.transform.position = transform.position + transform.right * Plugin.ChalkOffsetX() + Vector3.up * Plugin.ChalkOffsetY() + transform.forward * Plugin.ChalkOffsetZ(); Vector3 forward = transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } _board.transform.rotation = Quaternion.AngleAxis(Plugin.ChalkYaw(), Vector3.up) * Quaternion.LookRotation(((Vector3)(ref forward)).normalized, Vector3.up); TrackerManager instance = TrackerManager.Instance; if ((Object)(object)instance != (Object)null && (instance.RecordsDirty || _dirty)) { RefreshText(instance); instance.RecordsDirty = false; _dirty = false; } } } private void OnDestroy() { if ((Object)(object)_board != (Object)null) { Object.Destroy((Object)(object)_board); } } private void BuildBoard() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001b: 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_0054: 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_00b7: 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_00ec: 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_0118: 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_0169: Unknown result type (might be due to invalid IL or missing references) //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) _board = new GameObject("LCCasinoChalkboard"); _board.transform.localScale = Vector3.one * Plugin.ChalkScale(); Canvas val = _board.AddComponent(); val.renderMode = (RenderMode)2; RectTransform component = ((Component)val).GetComponent(); component.sizeDelta = new Vector2(520f, 360f); Image val2 = LCStyle.Panel(_board.transform, new Color(0.05f, 0.08f, 0.06f, 0.96f)); LCStyle.Stretch(((Graphic)val2).rectTransform, 0f, 0f); Image val3 = LCStyle.Panel(((Component)val2).transform, new Color(0.4f, 0.52f, 0.36f, 0.5f)); RectTransform rectTransform = ((Graphic)val3).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.sizeDelta = new Vector2(0f, 3f); rectTransform.anchoredPosition = Vector2.zero; _text = LCStyle.Text(_board.transform, "Text", 22f, (TextAlignmentOptions)257, nativeGlow: false); ((Graphic)_text).color = new Color(0.88f, 0.93f, 0.83f); LCStyle.Stretch(((TMP_Text)_text).rectTransform, 26f, 22f); _dirty = true; ManualLogSource log = Plugin.Log; Vector3 position = _building.transform.position; log.LogInfo((object)("Chalkboard spawned at casino " + ((Vector3)(ref position)).ToString("F1"))); } private void RefreshText(TrackerManager tm) { //IL_001b: 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_007e: 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_011c: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_0153: 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) if (!((Object)(object)_text == (Object)null)) { List recordsSorted = tm.GetRecordsSorted(); string value = LCStyle.Tag("------------------------------", LCStyle.Rule); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(LCStyle.Tag("ALL-TIME CASINO RECORDS", LCStyle.Header)).Append('\n'); stringBuilder.Append(value).Append('\n'); Color c = default(Color); ((Color)(ref c))..ctor(0.88f, 0.93f, 0.83f); FindExtremes(recordsSorted, out var biggestWin, out var biggestLoss); stringBuilder.Append(LCStyle.Tag("BIGGEST WIN", LCStyle.Dim)).Append(""); if (biggestWin != null && biggestWin.biggestSingleWin > 0) { stringBuilder.Append(LCStyle.Tag(Trunc(biggestWin.username, 11), c)).Append("").Append(LCStyle.Tag("+" + biggestWin.biggestSingleWin.ToString("N0"), LCStyle.Up)); } else { stringBuilder.Append(LCStyle.Tag("-", LCStyle.Dim)); } stringBuilder.Append('\n'); stringBuilder.Append(LCStyle.Tag("BIGGEST LOSS", LCStyle.Dim)).Append(""); if (biggestLoss != null && biggestLoss.biggestSingleLoss > 0) { stringBuilder.Append(LCStyle.Tag(Trunc(biggestLoss.username, 11), c)).Append("").Append(LCStyle.Tag("-" + biggestLoss.biggestSingleLoss.ToString("N0"), LCStyle.Down)); } else { stringBuilder.Append(LCStyle.Tag("-", LCStyle.Dim)); } stringBuilder.Append('\n'); stringBuilder.Append(value).Append('\n'); stringBuilder.Append(LCStyle.Tag("TOTAL GAMES", LCStyle.Dim)).Append("").Append(tm.TotalGames()); ((TMP_Text)_text).text = stringBuilder.ToString(); } } private static void FindExtremes(List recs, out PlayerRunRecord biggestWin, out PlayerRunRecord biggestLoss) { biggestWin = null; biggestLoss = null; for (int i = 0; i < recs.Count; i++) { PlayerRunRecord playerRunRecord = recs[i]; if (biggestWin == null || playerRunRecord.biggestSingleWin > biggestWin.biggestSingleWin) { biggestWin = playerRunRecord; } if (biggestLoss == null || playerRunRecord.biggestSingleLoss > biggestLoss.biggestSingleLoss) { biggestLoss = playerRunRecord; } } } private static string Trunc(string s, int max) { if (string.IsNullOrEmpty(s)) { return ""; } if (s.Length > max) { return s.Substring(0, max); } return s; } } public class HUDController : MonoBehaviour { private GameObject _root; private RectTransform _panel; private RawImage _scan; private TextMeshProUGUI _text; private bool _built; private void Build() { //IL_0043: 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_0084: 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_00c3: Unknown result type (might be due to invalid IL or missing references) if (LCStyle.Ready) { Canvas val = LCStyle.OverlayCanvas("LCCT_HUD", 800); _root = ((Component)val).gameObject; Image val2 = LCStyle.SoftPanel(_root.transform, new Color(0.02f, 0.04f, 0.03f, 0.5f)); _panel = ((Graphic)val2).rectTransform; _panel.anchorMin = new Vector2(1f, 1f); _panel.anchorMax = new Vector2(1f, 1f); _panel.pivot = new Vector2(1f, 1f); _scan = LCStyle.Scanlines(((Component)val2).transform, new Color(0f, 0f, 0f, 0.18f)); LCStyle.Stretch(((Graphic)_scan).rectTransform, 3f, 3f); _text = LCStyle.Text(((Component)val2).transform, "Text", Plugin.HudFontSize(), (TextAlignmentOptions)257, nativeGlow: true); LCStyle.Stretch(((TMP_Text)_text).rectTransform, 16f, 12f); _built = true; } } private void Update() { //IL_00ab: 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_00fe: Unknown result type (might be due to invalid IL or missing references) if (!_built) { Build(); if (!_built) { return; } } TrackerManager instance = TrackerManager.Instance; StartOfRound instance2 = StartOfRound.Instance; bool flag = Plugin.HudEnabled() && (Object)(object)instance != (Object)null && (Object)(object)instance2 != (Object)null && instance2.shipHasLanded && !instance2.shipIsLeaving && IsGordion(instance2); if (_root.activeSelf != flag) { _root.SetActive(flag); } if (flag) { List crew = GetCrew(instance2); float num = (float)Plugin.HudFontSize() * 1.34f; float num2 = (float)(crew.Count + 4) * num + 22f; _panel.sizeDelta = new Vector2((float)Plugin.HudWidth(), num2); _panel.anchoredPosition = new Vector2((float)(-Plugin.HudMarginX()), (float)(-Plugin.HudMarginY())); if ((Object)(object)_scan != (Object)null) { _scan.uvRect = new Rect(0f, 0f, 1f, num2 / 3f); } ((TMP_Text)_text).text = BuildText(instance, crew); } } private static string BuildText(TrackerManager tm, List crew) { //IL_0005: 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_0125: 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_012a: 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_011e: 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_015d: 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_00b0: 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_00d0: Unknown result type (might be due to invalid IL or missing references) string value = LCStyle.Tag("------------------------", LCStyle.Rule); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(LCStyle.Tag("SESSION", LCStyle.Header)).Append('\n'); stringBuilder.Append(value).Append('\n'); for (int i = 0; i < crew.Count; i++) { PlayerControllerB val = crew[i]; string s = (string.IsNullOrEmpty(val.playerUsername) ? ("Player " + val.playerClientId) : val.playerUsername); stringBuilder.Append(LCStyle.Tag(Trunc(s, 12), LCStyle.Ink)); if (tm.TryGetSessionDelta(val.playerClientId, out var delta) && delta != 0) { Color c = ((delta > 0) ? LCStyle.Up : LCStyle.Down); stringBuilder.Append("").Append(LCStyle.Tag(LCStyle.Signed(delta), c)); } stringBuilder.Append('\n'); } stringBuilder.Append(value).Append('\n'); int num = tm.CrewNet(); Color c2 = ((num > 0) ? LCStyle.Up : ((num < 0) ? LCStyle.Down : LCStyle.Ink)); stringBuilder.Append(LCStyle.Tag("CREW", LCStyle.Dim)).Append("").Append(LCStyle.Tag((num == 0) ? "0" : LCStyle.Signed(num), c2)); return stringBuilder.ToString(); } private static bool IsGordion(StartOfRound sor) { SelectableLevel currentLevel = sor.currentLevel; if ((Object)(object)currentLevel == (Object)null || string.IsNullOrEmpty(currentLevel.PlanetName)) { return false; } return currentLevel.PlanetName.IndexOf("Gordion", StringComparison.OrdinalIgnoreCase) >= 0; } private static List GetCrew(StartOfRound sor) { List list = new List(); PlayerControllerB[] allPlayerScripts = sor.allPlayerScripts; if (allPlayerScripts == null) { return list; } foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && (val.isPlayerControlled || val.isPlayerDead)) { list.Add(val); } } return list; } private static string Trunc(string s, int max) { if (string.IsNullOrEmpty(s)) { return ""; } if (s.Length > max) { return s.Substring(0, max); } return s; } private void OnDestroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } } public static class LCStyle { public static readonly Color Ink = new Color(0.74f, 0.85f, 0.7f); public static readonly Color Dim = new Color(0.46f, 0.55f, 0.44f); public static readonly Color Up = new Color(0.56f, 0.96f, 0.52f); public static readonly Color Down = new Color(0.95f, 0.46f, 0.36f); public static readonly Color Header = new Color(0.72f, 0.88f, 0.6f); public static readonly Color Rule = new Color(0.55f, 0.66f, 0.45f, 0.5f); private static TMP_FontAsset _font; private static Material _mat; private static Sprite _softPanel; private static Texture2D _scan; private static Sprite _outline; public static bool Ready { get { EnsureRef(); if ((Object)(object)_font != (Object)null) { return (Object)(object)_mat != (Object)null; } return false; } } public static string Hex(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGB(c); } public static string Tag(string s, Color c) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return "" + s + ""; } public static string Signed(int v) { return ((v > 0) ? "+" : "") + v.ToString("N0"); } private static void EnsureRef() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00cd: 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_0177: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_font != (Object)null && (Object)(object)_mat != (Object)null) { return; } try { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null) { return; } TextMeshProUGUI val = null; if ((Object)(object)instance.weightCounter != (Object)null) { val = instance.weightCounter; } else if (instance.controlTipLines != null && instance.controlTipLines.Length > 0) { val = instance.controlTipLines[0]; } else if ((Object)(object)instance.clockNumber != (Object)null) { val = instance.clockNumber; } if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)((TMP_Text)val).font != (Object)null) { _font = ((TMP_Text)val).font; } if (!((Object)(object)((TMP_Text)val).fontSharedMaterial != (Object)null)) { return; } _mat = new Material(((TMP_Text)val).fontSharedMaterial); try { _mat.SetColor("_FaceColor", Color.white); _mat.EnableKeyword("GLOW_ON"); _mat.SetColor("_GlowColor", new Color(0.4f, 1f, 0.55f, 1f)); _mat.SetFloat("_GlowPower", 0.35f); _mat.SetFloat("_GlowOuter", 0.45f); _mat.SetFloat("_GlowInner", 0.05f); _mat.EnableKeyword("OUTLINE_ON"); _mat.SetColor("_OutlineColor", new Color(0f, 0.08f, 0.03f, 1f)); _mat.SetFloat("_OutlineWidth", 0.18f); } catch { } } catch { } } public static TMP_FontAsset Font() { EnsureRef(); if ((Object)(object)_font == (Object)null) { try { _font = TMP_Settings.defaultFontAsset; } catch { } } return _font; } public static Canvas OverlayCanvas(string name, int sortingOrder) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); Object.DontDestroyOnLoad((Object)(object)val); Canvas val2 = val.AddComponent(); val2.renderMode = (RenderMode)0; val2.sortingOrder = sortingOrder; CanvasScaler val3 = val.AddComponent(); val3.uiScaleMode = (ScaleMode)1; val3.referenceResolution = new Vector2(1920f, 1080f); val3.screenMatchMode = (ScreenMatchMode)0; val3.matchWidthOrHeight = 0.5f; return val2; } public static Image Panel(Transform parent, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Panel"); val.transform.SetParent(parent, false); Image val2 = val.AddComponent(); ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; return val2; } public static Image SoftPanel(Transform parent, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Panel"); val.transform.SetParent(parent, false); Image val2 = val.AddComponent(); val2.sprite = SoftSprite(); val2.type = (Type)1; ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; return val2; } public static Image Box(Transform parent, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Box"); val.transform.SetParent(parent, false); Image val2 = val.AddComponent(); val2.sprite = OutlineSprite(); val2.type = (Type)1; ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; return val2; } private static Sprite OutlineSprite() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_00b6: 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_00d9: 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) if ((Object)(object)_outline != (Object)null) { return _outline; } int num = 16; int num2 = 4; int num3 = 2; Texture2D val = new Texture2D(num, num, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { bool flag = j < num3 || j >= num - num3 || i < num3 || i >= num - num3; val.SetPixel(j, i, new Color(1f, 1f, 1f, flag ? 1f : 0f)); } } val.Apply(); ((Object)val).hideFlags = (HideFlags)61; _outline = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)num2, (float)num2, (float)num2, (float)num2)); return _outline; } public static RawImage Scanlines(Transform parent, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Scanlines"); val.transform.SetParent(parent, false); RawImage val2 = val.AddComponent(); val2.texture = (Texture)(object)ScanTex(); ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; return val2; } public static TextMeshProUGUI Text(Transform parent, string name, float size, TextAlignmentOptions align, bool nativeGlow) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004a: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).font = Font(); if (nativeGlow && (Object)(object)_mat != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = _mat; } ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = Ink; ((TMP_Text)val2).alignment = align; ((TMP_Text)val2).richText = true; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; return val2; } public static void Stretch(RectTransform rt, float padX, float padY) { //IL_0001: 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) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.offsetMin = new Vector2(padX, padY); rt.offsetMax = new Vector2(0f - padX, 0f - padY); } private static Sprite SoftSprite() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00c4: 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_00e7: 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) if ((Object)(object)_softPanel != (Object)null) { return _softPanel; } int num = 32; int num2 = 12; Texture2D val = new Texture2D(num, num, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { int num3 = Mathf.Min(Mathf.Min(j, num - 1 - j), Mathf.Min(i, num - 1 - i)); float num4 = Mathf.Clamp01((float)num3 / (float)num2); num4 = num4 * num4 * (3f - 2f * num4); val.SetPixel(j, i, new Color(1f, 1f, 1f, num4)); } } val.Apply(); ((Object)val).hideFlags = (HideFlags)61; _softPanel = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4((float)num2, (float)num2, (float)num2, (float)num2)); return _softPanel; } private static Texture2D ScanTex() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0052: 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_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scan != (Object)null) { return _scan; } _scan = new Texture2D(1, 3, (TextureFormat)4, false); ((Texture)_scan).wrapMode = (TextureWrapMode)0; ((Texture)_scan).filterMode = (FilterMode)0; _scan.SetPixel(0, 0, new Color(0f, 0f, 0f, 0f)); _scan.SetPixel(0, 1, new Color(0f, 0f, 0f, 0f)); _scan.SetPixel(0, 2, new Color(0f, 0f, 0f, 1f)); _scan.Apply(); ((Object)_scan).hideFlags = (HideFlags)61; return _scan; } } [Serializable] public class DeltaMsg { public long id; public int delta; public int game; public int inst; public string name = ""; } public static class NetworkSync { private const string MsgDelta = "LCCT_Delta"; private const string MsgRequest = "LCCT_Req"; private const string MsgState = "LCCT_State"; private static bool _registered; private static NetworkManager _registeredOn; private static bool _requested; public static void Tick() { try { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening) { _registered = false; _registeredOn = null; _requested = false; return; } if (!_registered || (Object)(object)_registeredOn != (Object)(object)singleton) { Register(singleton); } if (!singleton.IsServer && singleton.IsConnectedClient && !_requested) { Send("LCCT_Req", 0uL, "1"); _requested = true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("NetworkSync.Tick: " + ex.Message)); } } public static void RequestResync() { _requested = false; } private static void Register(NetworkManager nm) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown CustomMessagingManager customMessagingManager = nm.CustomMessagingManager; if (customMessagingManager != null) { customMessagingManager.RegisterNamedMessageHandler("LCCT_Delta", new HandleNamedMessageDelegate(OnDelta)); customMessagingManager.RegisterNamedMessageHandler("LCCT_Req", new HandleNamedMessageDelegate(OnRequest)); customMessagingManager.RegisterNamedMessageHandler("LCCT_State", new HandleNamedMessageDelegate(OnState)); _registered = true; _registeredOn = nm; Plugin.Log.LogInfo((object)("NetworkSync handlers registered (server=" + nm.IsServer + ").")); } } public static void BroadcastDelta(ulong id, string username, int delta, CasinoGameType game, int instId) { try { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsServer || singleton.CustomMessagingManager == null) { return; } DeltaMsg deltaMsg = new DeltaMsg(); deltaMsg.id = (long)id; deltaMsg.delta = delta; deltaMsg.game = (int)game; deltaMsg.inst = instId; deltaMsg.name = ((username == null) ? "" : username); string payload = JsonUtility.ToJson((object)deltaMsg); foreach (ulong connectedClientsId in singleton.ConnectedClientsIds) { if (connectedClientsId != 0) { Send("LCCT_Delta", connectedClientsId, payload); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("BroadcastDelta: " + ex.Message)); } } private static void Send(string msg, ulong clientId, string payload) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(Encoding.UTF8.GetByteCount(payload) + 64, (Allocator)2, 524288); try { ((FastBufferWriter)(ref val)).WriteValueSafe(payload, false); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(msg, clientId, val, (NetworkDelivery)2); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } private static void OnDelta(ulong sender, FastBufferReader reader) { try { if (!TrackerManager.IsServer()) { string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false); DeltaMsg deltaMsg = JsonUtility.FromJson(text); if (deltaMsg != null && (Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.RecordResolution((ulong)deltaMsg.id, deltaMsg.name, deltaMsg.delta, (CasinoGameType)deltaMsg.game, deltaMsg.inst); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("OnDelta: " + ex.Message)); } } private static void OnRequest(ulong sender, FastBufferReader reader) { try { if (TrackerManager.IsServer() && !((Object)(object)TrackerManager.Instance == (Object)null)) { SyncBlob syncBlob = TrackerManager.Instance.BuildSyncBlob(); Send("LCCT_State", sender, JsonUtility.ToJson((object)syncBlob)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("OnRequest: " + ex.Message)); } } private static void OnState(ulong sender, FastBufferReader reader) { try { if (!TrackerManager.IsServer()) { string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false); SyncBlob b = JsonUtility.FromJson(text); if ((Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.ApplySyncBlob(b); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("OnState: " + ex.Message)); } } } [Serializable] public class PlayerRunRecord { public long clientId; public string username = ""; public int totalWon; public int totalLost; public int biggestSingleWin; public int biggestSingleLoss; public string biggestWinGame = ""; public string biggestLossGame = ""; public int gamesPlayed; public int Net => totalWon - totalLost; } [Serializable] public class RunSaveBlob { public List records = new List(); } [Serializable] public class SessionEntry { public long clientId; public string username = ""; public int delta; } [Serializable] public class SyncBlob { public List records = new List(); public List session = new List(); } [BepInPlugin("jaredfreedman.LethalCasinoTracker", "LethalCasinoTracker", "1.1.0")] [BepInDependency("mrgrm7.LethalCasino", "1.1.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "jaredfreedman.LethalCasinoTracker"; public static ManualLogSource Log; public static bool VerboseLogging; private static bool _initialized; private static ConfigEntry _verbose; private static ConfigEntry _hudEnabled; private static ConfigEntry _hudMarginX; private static ConfigEntry _hudMarginY; private static ConfigEntry _hudWidth; private static ConfigEntry _hudFont; private static ConfigEntry _summaryEnabled; private static ConfigEntry _summaryDuration; private static ConfigEntry _sfxEnabled; private static ConfigEntry _sfxVolume; private static ConfigEntry _chalkEnabled; private static ConfigEntry _chalkX; private static ConfigEntry _chalkY; private static ConfigEntry _chalkZ; private static ConfigEntry _chalkScale; private static ConfigEntry _chalkYaw; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindConfig(); if (!_initialized) { _initialized = true; try { Harmony h = new Harmony("jaredfreedman.LethalCasinoTracker"); GameOverPatch.ApplyPatches(h); CasinoHooks.ApplyPatches(h); } catch (Exception ex) { Log.LogError((object)("Failed to apply Harmony patches: " + ex.Message)); } ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); Log.LogInfo((object)"LethalCasinoTracker 1.1.0 loaded."); } } private void BindConfig() { _verbose = ((BaseUnityPlugin)this).Config.Bind("General", "VerboseLogging", false, "Log every tracked bet result (debugging)."); _hudEnabled = ((BaseUnityPlugin)this).Config.Bind("HUD", "Enabled", true, "Show the top-right session scoreboard while on a moon."); _hudMarginX = ((BaseUnityPlugin)this).Config.Bind("HUD", "MarginX", 12, "Distance from the right edge of the screen, in pixels."); _hudMarginY = ((BaseUnityPlugin)this).Config.Bind("HUD", "MarginY", 70, "Distance from the top edge of the screen, in pixels."); _hudWidth = ((BaseUnityPlugin)this).Config.Bind("HUD", "Width", 270, "Panel width (reference px at 1080p)."); _hudFont = ((BaseUnityPlugin)this).Config.Bind("HUD", "FontSize", 19, "Font size for HUD rows."); _summaryEnabled = ((BaseUnityPlugin)this).Config.Bind("Summary", "Enabled", true, "Show the centered session recap on takeoff."); _summaryDuration = ((BaseUnityPlugin)this).Config.Bind("Summary", "HoldSeconds", 7f, "How long the recap stays fully visible (matches the vanilla performance report)."); _sfxEnabled = ((BaseUnityPlugin)this).Config.Bind("Summary", "Sound", true, "Play a win/loss jingle with the recap."); _sfxVolume = ((BaseUnityPlugin)this).Config.Bind("Summary", "Volume", 0.5f, "Recap jingle volume (0-1)."); _chalkEnabled = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "Enabled", true, "Spawn the physical casino records board near the casino."); _chalkX = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "OffsetRight", 0f, "Board placement offset along the casino's right axis (m)."); _chalkY = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "OffsetUp", 2.6f, "Board placement offset upward from the casino (m)."); _chalkZ = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "OffsetForward", 4.5f, "Board placement offset in front of the casino (m)."); _chalkScale = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "Scale", 0.0075f, "World scale of the board."); _chalkYaw = ((BaseUnityPlugin)this).Config.Bind("Chalkboard", "Yaw", 180f, "Rotate the board to face the right way (degrees: try 0/90/180/270)."); VerboseLogging = _verbose.Value; } public static bool HudEnabled() { if (_hudEnabled != null) { return _hudEnabled.Value; } return true; } public static int HudMarginX() { if (_hudMarginX != null) { return _hudMarginX.Value; } return 12; } public static int HudMarginY() { if (_hudMarginY != null) { return _hudMarginY.Value; } return 70; } public static int HudWidth() { if (_hudWidth != null) { return _hudWidth.Value; } return 270; } public static int HudFontSize() { if (_hudFont != null) { return _hudFont.Value; } return 19; } public static bool SummaryEnabled() { if (_summaryEnabled != null) { return _summaryEnabled.Value; } return true; } public static float SummaryDuration() { if (_summaryDuration != null) { return _summaryDuration.Value; } return 7f; } public static bool SfxEnabled() { if (_sfxEnabled != null) { return _sfxEnabled.Value; } return true; } public static float SfxVolume() { if (_sfxVolume != null) { return _sfxVolume.Value; } return 0.5f; } public static bool ChalkboardEnabled() { if (_chalkEnabled != null) { return _chalkEnabled.Value; } return true; } public static float ChalkOffsetX() { if (_chalkX != null) { return _chalkX.Value; } return 0f; } public static float ChalkOffsetY() { if (_chalkY != null) { return _chalkY.Value; } return 2.6f; } public static float ChalkOffsetZ() { if (_chalkZ != null) { return _chalkZ.Value; } return 4.5f; } public static float ChalkScale() { if (_chalkScale != null) { return _chalkScale.Value; } return 0.0075f; } public static float ChalkYaw() { if (_chalkYaw != null) { return _chalkYaw.Value; } return 180f; } } public class SummaryScreenController : MonoBehaviour { private class Row { public string name; public bool has; public int delta; } private const float W = 700f; private const float Pad = 26f; private const float RowH = 40f; private static readonly Color RInk = new Color(0.95f, 0.5f, 0.36f); private static readonly Color RHead = new Color(1f, 0.36f, 0.24f); private static readonly Color RDim = new Color(0.74f, 0.34f, 0.27f); private static readonly Color RBg = new Color(0.11f, 0.015f, 0.015f, 0.94f); private static readonly Color RBorder = new Color(0.92f, 0.26f, 0.17f, 0.95f); private static readonly Color Up = new Color(0.55f, 0.95f, 0.5f); private static readonly Color Down = new Color(1f, 0.42f, 0.35f); private GameObject _root; private CanvasGroup _group; private RectTransform _panel; private RectTransform _inner; private TextMeshProUGUI _title; private TextMeshProUGUI _notes; private TextMeshProUGUI _collected; private TextMeshProUGUI _grade; private readonly List _rowBoxes = new List(); private bool _built; private Coroutine _co; private AudioSource _audio; private AudioClip _winClip; private AudioClip _loseClip; private AudioClip _neutralClip; public static SummaryScreenController Instance { get; private set; } private void Awake() { Instance = this; _audio = ((Component)this).gameObject.AddComponent(); _audio.playOnAwake = false; _audio.spatialBlend = 0f; _audio.ignoreListenerPause = true; try { _winClip = MakeJingle("win", new float[4] { 523.25f, 659.25f, 783.99f, 1046.5f }, 0.13f, 0f); _loseClip = MakeJingle("lose", new float[4] { 440f, 392f, 349.23f, 293.66f }, 0.2f, -28f); _neutralClip = MakeJingle("neutral", new float[1] { 660f }, 0.09f, 0f); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not build recap audio: " + ex.Message)); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } private static string Tag(string s, Color c) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return "" + s + ""; } private static string Signed(int v) { return ((v > 0) ? "+" : "") + v.ToString("N0"); } private TextMeshProUGUI Label(string name, float x, float y, float w, float h, float size, TextAlignmentOptions align, Color col) { //IL_000e: 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_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_0061: 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_007b: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = LCStyle.Text(((Component)_inner).transform, name, size, align, nativeGlow: false); RectTransform rectTransform = ((TMP_Text)val).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(0f, 1f); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(x, 0f - y); rectTransform.sizeDelta = new Vector2(w, h); ((Graphic)val).color = col; return val; } private void BuildUI() { //IL_005c: 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_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_00ba: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_017a: 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) //IL_01d1: 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_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0261: 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) //IL_02d8: 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_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0325: 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_034b: 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_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: 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_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_044e: 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_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0493: 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_04f2: 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_051e: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: 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_05de: Unknown result type (might be due to invalid IL or missing references) Canvas val = LCStyle.OverlayCanvas("LCCT_Recap", 950); _root = ((Component)val).gameObject; _group = _root.AddComponent(); _group.alpha = 0f; Image val2 = LCStyle.Panel(_root.transform, new Color(0f, 0f, 0f, 0.6f)); LCStyle.Stretch(((Graphic)val2).rectTransform, 0f, 0f); Image val3 = LCStyle.Panel(_root.transform, RBorder); _panel = ((Graphic)val3).rectTransform; RectTransform panel = _panel; Vector2 anchorMin = (_panel.anchorMax = new Vector2(0.5f, 0.5f)); panel.anchorMin = anchorMin; _panel.pivot = new Vector2(0.5f, 0.5f); Image val5 = LCStyle.Panel(((Component)val3).transform, RBg); _inner = ((Graphic)val5).rectTransform; LCStyle.Stretch(_inner, 4f, 4f); RawImage val6 = LCStyle.Scanlines(((Component)_inner).transform, new Color(0.3f, 0f, 0f, 0.22f)); LCStyle.Stretch(((Graphic)val6).rectTransform, 0f, 0f); _title = Label("Title", 26f, 14f, 648f, 40f, 30f, (TextAlignmentOptions)258, RHead); ((TMP_Text)_title).fontStyle = (FontStyles)1; ((TMP_Text)_title).text = "CASINO PERFORMANCE REPORT"; Image val7 = LCStyle.Panel(((Component)_inner).transform, RBorder); RectTransform rectTransform = ((Graphic)val7).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(0f, 1f); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(26f, -58f); rectTransform.sizeDelta = new Vector2(648f, 3f); float num = 406f; ((TMP_Text)Label("EmpHead", 26f, 70f, num - 26f, 24f, 18f, (TextAlignmentOptions)257, RDim)).text = "EMPLOYEE"; ((TMP_Text)Label("NotesHead", num + 6f, 70f, 674f - num - 6f, 24f, 18f, (TextAlignmentOptions)257, RDim)).text = "NOTES"; float num2 = num + 6f; float num3 = 674f - num2; Image val8 = LCStyle.Box(((Component)_inner).transform, RBorder); RectTransform rectTransform2 = ((Graphic)val8).rectTransform; rectTransform2.anchorMin = new Vector2(0f, 1f); rectTransform2.anchorMax = new Vector2(0f, 1f); rectTransform2.pivot = new Vector2(0f, 1f); rectTransform2.anchoredPosition = new Vector2(num2, -98f); rectTransform2.sizeDelta = new Vector2(num3, 160f); _notes = LCStyle.Text(((Component)_inner).transform, "Notes", 17f, (TextAlignmentOptions)257, nativeGlow: false); RectTransform rectTransform3 = ((TMP_Text)_notes).rectTransform; rectTransform3.anchorMin = new Vector2(0f, 1f); rectTransform3.anchorMax = new Vector2(0f, 1f); rectTransform3.pivot = new Vector2(0f, 1f); rectTransform3.anchoredPosition = new Vector2(num2 + 12f, -110f); rectTransform3.sizeDelta = new Vector2(num3 - 24f, 160f); ((Graphic)_notes).color = RInk; Image val9 = LCStyle.Box(((Component)_inner).transform, RBorder); RectTransform rectTransform4 = ((Graphic)val9).rectTransform; rectTransform4.anchorMin = new Vector2(0f, 0f); rectTransform4.anchorMax = new Vector2(0f, 0f); rectTransform4.pivot = new Vector2(0f, 0f); rectTransform4.anchoredPosition = new Vector2(26f, 16f); rectTransform4.sizeDelta = new Vector2(num - 26f, 44f); _collected = LCStyle.Text(((Component)_inner).transform, "Collected", 20f, (TextAlignmentOptions)513, nativeGlow: false); RectTransform rectTransform5 = ((TMP_Text)_collected).rectTransform; rectTransform5.anchorMin = new Vector2(0f, 0f); rectTransform5.anchorMax = new Vector2(0f, 0f); rectTransform5.pivot = new Vector2(0f, 0f); rectTransform5.anchoredPosition = new Vector2(40f, 16f); rectTransform5.sizeDelta = new Vector2(num - 26f - 20f, 44f); _grade = LCStyle.Text(((Component)_inner).transform, "Grade", 30f, (TextAlignmentOptions)516, nativeGlow: false); RectTransform rectTransform6 = ((TMP_Text)_grade).rectTransform; rectTransform6.anchorMin = new Vector2(1f, 0f); rectTransform6.anchorMax = new Vector2(1f, 0f); rectTransform6.pivot = new Vector2(1f, 0f); rectTransform6.anchoredPosition = new Vector2(-26f, 16f); rectTransform6.sizeDelta = new Vector2(294f, 44f); ((TMP_Text)_grade).fontStyle = (FontStyles)1; _built = true; } public void Show(Dictionary sessionSnapshot, int crewNet) { //IL_00b3: 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_00ea: 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_0121: 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_017f: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_0238: 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_0218: 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_026e: 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_02bc: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SummaryEnabled()) { if ((Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.EndSessionWipe(); } return; } if (!_built) { BuildUI(); } List list = BuildRows(sessionSnapshot); for (int i = 0; i < _rowBoxes.Count; i++) { if ((Object)(object)_rowBoxes[i] != (Object)null) { Object.Destroy((Object)(object)_rowBoxes[i]); } } _rowBoxes.Clear(); float num = 406f; float num2 = num - 26f; int num3 = Mathf.Min(list.Count, 6); for (int j = 0; j < num3; j++) { Row row = list[j]; Image val = LCStyle.Box(((Component)_inner).transform, RBorder); RectTransform rectTransform = ((Graphic)val).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(0f, 1f); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(26f, 0f - (98f + (float)j * 40f)); rectTransform.sizeDelta = new Vector2(num2, 34f); TextMeshProUGUI val2 = LCStyle.Text(((Component)val).transform, "Row", 19f, (TextAlignmentOptions)513, nativeGlow: false); LCStyle.Stretch(((TMP_Text)val2).rectTransform, 12f, 0f); string text = (row.has ? Tag(Signed(row.delta), (row.delta > 0) ? Up : Down) : Tag("--", RDim)); ((TMP_Text)val2).text = Tag(Trunc(row.name, 12), RInk) + "" + text; _rowBoxes.Add(((Component)val).gameObject); } ((TMP_Text)_notes).text = BuildNotes(); Color c = ((crewNet > 0) ? Up : ((crewNet < 0) ? Down : RInk)); ((TMP_Text)_collected).text = Tag("COLLECTED: ", RDim) + Tag((crewNet == 0) ? "0" : Signed(crewNet), c); ((TMP_Text)_grade).text = Tag("GRADE ", RDim) + Tag(Grade(crewNet), RHead); float num4 = 98f + (float)Mathf.Max(num3, 3) * 40f + 76f; _panel.sizeDelta = new Vector2(700f, num4); PlayResultSound(crewNet); _root.SetActive(true); if (_co != null) { ((MonoBehaviour)this).StopCoroutine(_co); } _co = ((MonoBehaviour)this).StartCoroutine(Run()); } private static string BuildNotes() { //IL_00e2: 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_00c2: 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_0190: 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_0142: Unknown result type (might be due to invalid IL or missing references) TrackerManager instance = TrackerManager.Instance; if ((Object)(object)instance == (Object)null) { return ""; } List recordsSorted = instance.GetRecordsSorted(); PlayerRunRecord playerRunRecord = null; PlayerRunRecord playerRunRecord2 = null; for (int i = 0; i < recordsSorted.Count; i++) { if (playerRunRecord == null || recordsSorted[i].biggestSingleWin > playerRunRecord.biggestSingleWin) { playerRunRecord = recordsSorted[i]; } if (playerRunRecord2 == null || recordsSorted[i].biggestSingleLoss > playerRunRecord2.biggestSingleLoss) { playerRunRecord2 = recordsSorted[i]; } } StringBuilder stringBuilder = new StringBuilder(); if (playerRunRecord != null && playerRunRecord.biggestSingleWin > 0) { stringBuilder.Append(Tag("Top win: ", RDim)).Append(Tag(Trunc(playerRunRecord.username, 9) + " " + Signed(playerRunRecord.biggestSingleWin), Up)).Append('\n'); } else { stringBuilder.Append(Tag("Top win: --", RDim)).Append('\n'); } if (playerRunRecord2 != null && playerRunRecord2.biggestSingleLoss > 0) { stringBuilder.Append(Tag("Top loss: ", RDim)).Append(Tag(Trunc(playerRunRecord2.username, 9) + " -" + playerRunRecord2.biggestSingleLoss.ToString("N0"), Down)).Append('\n'); } else { stringBuilder.Append(Tag("Top loss: --", RDim)).Append('\n'); } stringBuilder.Append(Tag("Games: " + instance.TotalGames(), RDim)); return stringBuilder.ToString(); } private static string Grade(int crewNet) { if (crewNet >= 1500) { return "S"; } if (crewNet >= 400) { return "A"; } if (crewNet > 0) { return "B"; } if (crewNet == 0) { return "C"; } if (crewNet > -400) { return "D"; } return "F"; } private static List BuildRows(Dictionary snap) { List list = new List(); StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && instance.allPlayerScripts != null) { PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && (val.isPlayerControlled || val.isPlayerDead)) { Row row = new Row(); row.name = (string.IsNullOrEmpty(val.playerUsername) ? ("Player " + val.playerClientId) : val.playerUsername); row.has = snap != null && snap.TryGetValue(val.playerClientId, out var value) && value != 0; row.delta = (row.has ? snap[val.playerClientId] : 0); list.Add(row); } } } return list; } private IEnumerator Run() { float fadeIn = 0.45f; float hold = Plugin.SummaryDuration(); float fadeOut = 0.8f; float t = 0f; while (t < fadeIn) { t += Time.unscaledDeltaTime; _group.alpha = Mathf.Clamp01(t / fadeIn); yield return null; } _group.alpha = 1f; yield return (object)new WaitForSecondsRealtime(hold); t = 0f; while (t < fadeOut) { t += Time.unscaledDeltaTime; _group.alpha = 1f - Mathf.Clamp01(t / fadeOut); yield return null; } _group.alpha = 0f; _root.SetActive(false); _co = null; if ((Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.EndSessionWipe(); } } private void PlayResultSound(int crewNet) { if (Plugin.SfxEnabled() && !((Object)(object)_audio == (Object)null)) { AudioClip val = ((crewNet > 0) ? _winClip : ((crewNet < 0) ? _loseClip : _neutralClip)); if ((Object)(object)val != (Object)null) { _audio.PlayOneShot(val, Plugin.SfxVolume()); } } } private static string Trunc(string s, int max) { if (string.IsNullOrEmpty(s)) { return ""; } if (s.Length > max) { return s.Substring(0, max); } return s; } private static AudioClip MakeJingle(string name, float[] freqs, float noteDur, float noteGlideHz) { int num = 44100; int num2 = Mathf.Max(1, (int)(noteDur * (float)num)); int num3 = num2 * freqs.Length; float[] array = new float[num3]; for (int i = 0; i < freqs.Length; i++) { float num4 = freqs[i]; for (int j = 0; j < num2; j++) { float num5 = (float)j / (float)num; float num6 = (float)j / (float)num2; float num7 = num4 + noteGlideHz * num6; float num8 = Mathf.Exp(-4f * num6); float num9 = Mathf.Clamp01(num6 * 40f); array[i * num2 + j] = Mathf.Sin((float)Math.PI * 2f * num7 * num5) * num8 * num9 * 0.28f; } } AudioClip val = AudioClip.Create("LCCT_" + name, num3, 1, num, false); val.SetData(array, 0); return val; } } public class TrackerManager : MonoBehaviour { private class Pending { public ulong id; public string name; public int delta; public CasinoGameType game; public float lastTouch; } public const string Es3File = "LethalCasinoTracker.es3"; private const string Es3KeyPrefix = "CasinoTracker_RunRecords_"; private const float FlushDelay = 0.85f; private readonly Dictionary _sessionDeltas = new Dictionary(); private readonly Dictionary _runRecords = new Dictionary(); private readonly Dictionary _pending = new Dictionary(); private bool _recordsLoaded; private bool _wasLanded; private bool _wasListening; public static TrackerManager Instance { get; private set; } public bool SessionActive { get; private set; } public bool RecordsDirty { get; set; } private void Awake() { Instance = this; } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public void RecordResolution(ulong id, string username, int delta, CasinoGameType game, int gameInstanceId) { if (delta != 0) { string text = (string.IsNullOrEmpty(username) ? ("Player " + id) : username); _sessionDeltas.TryGetValue(id, out var value); _sessionDeltas[id] = value + delta; string key = gameInstanceId + ":" + id; if (!_pending.TryGetValue(key, out var value2)) { value2 = new Pending(); value2.id = id; value2.name = text; value2.game = game; _pending[key] = value2; } value2.delta += delta; value2.game = game; value2.name = text; value2.lastTouch = Time.realtimeSinceStartup; if (Plugin.VerboseLogging) { Plugin.Log.LogInfo((object)("Delta " + delta + " -> " + text + " (" + CasinoGameNames.Display(game) + "), session net now " + _sessionDeltas[id])); } } } private void Update() { bool flag = (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening; if (_wasListening && !flag) { SoftResetForMenu(); } _wasListening = flag; StartOfRound instance = StartOfRound.Instance; bool flag2 = (Object)(object)instance != (Object)null && instance.shipHasLanded && !instance.shipIsLeaving; if (flag2 && !_wasLanded) { OnShipLanded(); } else if (!flag2 && _wasLanded) { OnShipLeaving(); } _wasLanded = flag2; if (_pending.Count > 0) { float realtimeSinceStartup = Time.realtimeSinceStartup; List list = null; foreach (KeyValuePair item in _pending) { if (realtimeSinceStartup - item.Value.lastTouch >= 0.85f) { if (list == null) { list = new List(); } list.Add(item.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { Pending p = _pending[list[i]]; _pending.Remove(list[i]); FinalizeRound(p); } } } NetworkSync.Tick(); } private void FinalizeRound(Pending p) { PlayerRunRecord orCreateRecord = GetOrCreateRecord(p.id, p.name); orCreateRecord.gamesPlayed++; if (p.delta > 0) { orCreateRecord.totalWon += p.delta; if (p.delta > orCreateRecord.biggestSingleWin) { orCreateRecord.biggestSingleWin = p.delta; orCreateRecord.biggestWinGame = CasinoGameNames.Display(p.game); } } else if (p.delta < 0) { int num = -p.delta; orCreateRecord.totalLost += num; if (num > orCreateRecord.biggestSingleLoss) { orCreateRecord.biggestSingleLoss = num; orCreateRecord.biggestLossGame = CasinoGameNames.Display(p.game); } } RecordsDirty = true; } private void FlushAllPendingNow() { if (_pending.Count != 0) { List list = new List(_pending.Values); _pending.Clear(); for (int i = 0; i < list.Count; i++) { FinalizeRound(list[i]); } } } private PlayerRunRecord GetOrCreateRecord(ulong id, string name) { if (!_runRecords.TryGetValue(id, out var value)) { value = new PlayerRunRecord(); value.clientId = (long)id; value.username = name; _runRecords[id] = value; } else if (!string.IsNullOrEmpty(name)) { value.username = name; } return value; } public void OnShipLanded() { SessionActive = true; if (IsServer()) { if (!_recordsLoaded) { LoadRecords(); } _recordsLoaded = true; } else { NetworkSync.RequestResync(); } RecordsDirty = true; } public void OnShipLeaving() { FlushAllPendingNow(); if (IsServer()) { SaveRecords(); } bool flag = IsGordion(); Dictionary sessionSnapshot = new Dictionary(_sessionDeltas); SessionActive = false; SummaryScreenController instance = SummaryScreenController.Instance; if (flag && (Object)(object)instance != (Object)null) { instance.Show(sessionSnapshot, CrewNet()); } else { EndSessionWipe(); } } public static bool IsGordion() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.currentLevel == (Object)null || string.IsNullOrEmpty(instance.currentLevel.PlanetName)) { return false; } return instance.currentLevel.PlanetName.IndexOf("Gordion", StringComparison.OrdinalIgnoreCase) >= 0; } public void EndSessionWipe() { _sessionDeltas.Clear(); CasinoHooks.ResetValueTracking(); RecordsDirty = true; } private void SoftResetForMenu() { _sessionDeltas.Clear(); _runRecords.Clear(); _pending.Clear(); SessionActive = false; _wasLanded = false; _recordsLoaded = false; RecordsDirty = true; } public void EliminateRun() { _sessionDeltas.Clear(); _runRecords.Clear(); _pending.Clear(); CasinoHooks.ResetValueTracking(); SessionActive = false; RecordsDirty = true; if (IsServer()) { DeleteRecordsForSlot(SlotId()); } Plugin.Log.LogInfo((object)"Casino records wiped (crew eliminated)."); } public void OnSaveFileDeleted(string filePath) { string text = "default"; try { if (!string.IsNullOrEmpty(filePath)) { text = Path.GetFileNameWithoutExtension(filePath); } } catch { } DeleteRecordsForSlot(text); if (text == SlotId()) { _sessionDeltas.Clear(); _runRecords.Clear(); _pending.Clear(); CasinoHooks.ResetValueTracking(); _recordsLoaded = false; RecordsDirty = true; } Plugin.Log.LogInfo((object)("Casino records wiped for deleted save '" + text + "'.")); } private static string SlotId() { try { if ((Object)(object)GameNetworkManager.Instance != (Object)null && !string.IsNullOrEmpty(GameNetworkManager.Instance.currentSaveFileName)) { return Path.GetFileNameWithoutExtension(GameNetworkManager.Instance.currentSaveFileName); } } catch { } return "default"; } private static string KeyFor(string slot) { return "CasinoTracker_RunRecords_" + slot; } private void DeleteRecordsForSlot(string slot) { try { string text = KeyFor(slot); if (ES3.KeyExists(text, "LethalCasinoTracker.es3")) { ES3.DeleteKey(text, "LethalCasinoTracker.es3"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ES3 delete failed: " + ex.Message)); } } public void SaveRecords() { try { RunSaveBlob runSaveBlob = new RunSaveBlob(); foreach (PlayerRunRecord value in _runRecords.Values) { runSaveBlob.records.Add(value); } string text = JsonUtility.ToJson((object)runSaveBlob); ES3.Save(KeyFor(SlotId()), text, "LethalCasinoTracker.es3"); if (Plugin.VerboseLogging) { Plugin.Log.LogInfo((object)("Saved " + runSaveBlob.records.Count + " run records for slot '" + SlotId() + "'.")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to save run records: " + ex.Message)); } } public void LoadRecords() { try { _runRecords.Clear(); string text = KeyFor(SlotId()); if (!ES3.KeyExists(text, "LethalCasinoTracker.es3")) { Plugin.Log.LogInfo((object)("No casino records for slot '" + SlotId() + "'.")); RecordsDirty = true; return; } string text2 = ES3.Load(text, "LethalCasinoTracker.es3", ""); if (string.IsNullOrEmpty(text2)) { RecordsDirty = true; return; } RunSaveBlob runSaveBlob = JsonUtility.FromJson(text2); if (runSaveBlob != null && runSaveBlob.records != null) { for (int i = 0; i < runSaveBlob.records.Count; i++) { PlayerRunRecord playerRunRecord = runSaveBlob.records[i]; if (playerRunRecord != null) { _runRecords[(ulong)playerRunRecord.clientId] = playerRunRecord; } } } Plugin.Log.LogInfo((object)("Loaded " + _runRecords.Count + " run records for slot '" + SlotId() + "'.")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to load run records: " + ex.Message)); } RecordsDirty = true; } public SyncBlob BuildSyncBlob() { SyncBlob syncBlob = new SyncBlob(); foreach (PlayerRunRecord value2 in _runRecords.Values) { syncBlob.records.Add(value2); } foreach (KeyValuePair sessionDelta in _sessionDeltas) { SessionEntry sessionEntry = new SessionEntry(); sessionEntry.clientId = (long)sessionDelta.Key; sessionEntry.delta = sessionDelta.Value; sessionEntry.username = (_runRecords.TryGetValue(sessionDelta.Key, out var value) ? value.username : ""); syncBlob.session.Add(sessionEntry); } return syncBlob; } public void ApplySyncBlob(SyncBlob b) { if (b == null) { return; } _runRecords.Clear(); if (b.records != null) { for (int i = 0; i < b.records.Count; i++) { PlayerRunRecord playerRunRecord = b.records[i]; if (playerRunRecord != null) { _runRecords[(ulong)playerRunRecord.clientId] = playerRunRecord; } } } _sessionDeltas.Clear(); if (b.session != null) { for (int j = 0; j < b.session.Count; j++) { SessionEntry sessionEntry = b.session[j]; if (sessionEntry != null) { _sessionDeltas[(ulong)sessionEntry.clientId] = sessionEntry.delta; } } } _recordsLoaded = true; RecordsDirty = true; Plugin.Log.LogInfo((object)("Applied tracker state from host (" + _runRecords.Count + " records).")); } public bool TryGetSessionDelta(ulong id, out int delta) { return _sessionDeltas.TryGetValue(id, out delta); } public int CrewNet() { int num = 0; foreach (int value in _sessionDeltas.Values) { num += value; } return num; } public List GetRecordsSorted() { List list = new List(_runRecords.Values); list.Sort((PlayerRunRecord a, PlayerRunRecord b) => b.Net.CompareTo(a.Net)); return list; } public int TotalGames() { int num = 0; foreach (PlayerRunRecord value in _runRecords.Values) { num += value.gamesPlayed; } return num; } public static bool IsServer() { if ((Object)(object)NetworkManager.Singleton != (Object)null) { return NetworkManager.Singleton.IsServer; } return false; } } } namespace LethalCasinoTracker.Patches { public static class GameOverPatch { public static void OnPlayersFired() { if ((Object)(object)TrackerManager.Instance != (Object)null) { Plugin.Log.LogInfo((object)"Crew eliminated by the company — wiping casino records."); TrackerManager.Instance.EliminateRun(); } } public static void OnSaveFileDeleted(string filePath) { if ((Object)(object)TrackerManager.Instance != (Object)null) { TrackerManager.Instance.OnSaveFileDeleted(filePath); } } public static void ApplyPatches(Harmony h) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown Patch(h, AccessTools.Method(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc", (Type[])null, (Type[])null), AccessTools.Method(typeof(GameOverPatch), "OnPlayersFired", (Type[])null, (Type[])null), "StartOfRound.FirePlayersAfterDeadlineClientRpc"); MethodInfo methodInfo = AccessTools.Method(typeof(GameOverPatch), "OnSaveFileDeleted", (Type[])null, (Type[])null); try { MethodInfo[] methods = typeof(ES3).GetMethods(BindingFlags.Static | BindingFlags.Public); int num = 0; for (int i = 0; i < methods.Length; i++) { if (methods[i].Name != "DeleteFile") { continue; } ParameterInfo[] parameters = methods[i].GetParameters(); if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(string)) { try { h.Patch((MethodBase)methods[i], (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("ES3.DeleteFile patch failed: " + ex.Message)); } } } Plugin.Log.LogInfo((object)("Patched ES3.DeleteFile (" + num + " overloads).")); } catch (Exception ex2) { Plugin.Log.LogError((object)("Could not patch ES3.DeleteFile: " + ex2.Message)); } } private static void Patch(Harmony h, MethodInfo orig, MethodInfo postfix, string label) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown try { if (orig == null) { Plugin.Log.LogWarning((object)("Patch target not found: " + label)); return; } h.Patch((MethodBase)orig, (HarmonyMethod)null, new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("Patched " + label)); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to patch " + label + ": " + ex.Message)); } } } }