Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ScrapRanking FIXED V2 v1.0.1
ScrapRanking.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ScrapRanking")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ScrapRanking")] [assembly: AssemblyTitle("ScrapRanking")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace ScrapRanking { [BepInPlugin("mai.scrapranking", "Scrap Ranking", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("mai.scrapranking"); private void Awake() { harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ScrapRanking cargado!"); } } public static class RankingData { public static Dictionary<int, int> totalScrap = new Dictionary<int, int>(); public static void AccumulateAndReset(EndOfGameStats gameStats) { if (gameStats?.allPlayerStats == null) { return; } for (int i = 0; i < gameStats.allPlayerStats.Length; i++) { if (!totalScrap.ContainsKey(i)) { totalScrap[i] = 0; } totalScrap[i] += gameStats.allPlayerStats[i].profitable; gameStats.allPlayerStats[i].profitable = 0; } } public static void ResetTotal(EndOfGameStats gameStats) { totalScrap.Clear(); if (gameStats?.allPlayerStats != null) { for (int i = 0; i < gameStats.allPlayerStats.Length; i++) { gameStats.allPlayerStats[i].profitable = 0; } } } } [HarmonyPatch(typeof(StartOfRound), "StartGame")] public class ResetDailyOnStartGame { private static void Postfix(StartOfRound __instance) { if (__instance.gameStats?.allPlayerStats == null) { return; } for (int i = 0; i < __instance.gameStats.allPlayerStats.Length; i++) { int profitable = __instance.gameStats.allPlayerStats[i].profitable; if (!RankingData.totalScrap.ContainsKey(i)) { RankingData.totalScrap[i] = 0; } RankingData.totalScrap[i] += profitable; __instance.gameStats.allPlayerStats[i].profitable = 0; Debug.Log((object)$"[ScrapRanking] StartGame - jugador {i}: profitable={profitable}, totalAcumulado={RankingData.totalScrap[i]}"); } } } [HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")] public class ResetTotalOnFired { private static void Postfix(StartOfRound __instance) { RankingData.ResetTotal(__instance.gameStats); } } [HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")] public class ResetTotalOnNewGame { private static void Postfix() { RankingData.ResetTotal(StartOfRound.Instance?.gameStats); } } [HarmonyPatch(typeof(Terminal), "OnSubmit")] public class TerminalRankingCommand { private static bool Prefix(Terminal __instance) { if (__instance.textAdded == 0) { return true; } string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Trim().ToLower(); if (text != "ranking") { return true; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; EndOfGameStats gameStats = StartOfRound.Instance.gameStats; List<(string, int)> list = new List<(string, int)>(); for (int i = 0; i < allPlayerScripts.Length; i++) { PlayerControllerB val = allPlayerScripts[i]; if (val.isPlayerControlled || val.isPlayerDead || val.disconnectedMidGame) { int profitable = gameStats.allPlayerStats[i].profitable; int num = (RankingData.totalScrap.ContainsKey(i) ? RankingData.totalScrap[i] : 0); list.Add((val.playerUsername, profitable + num)); } } list = list.OrderByDescending<(string, int), int>(((string name, int scrap) p) => p.scrap).ToList(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("\n----- SCRAP RANKING -----\n"); for (int j = 0; j < list.Count; j++) { string text2 = j switch { 2 => "#3", 1 => "#2", 0 => "#1", _ => "#" + (j + 1), }; stringBuilder.AppendLine(text2 + " " + list[j].Item1 + " - $" + list[j].Item2); } stringBuilder.AppendLine("\n-------------------------"); TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>(); val2.displayText = stringBuilder.ToString(); val2.clearPreviousText = true; val2.terminalEvent = ""; __instance.LoadNewNode(val2); __instance.textAdded = 0; __instance.screenText.ActivateInputField(); ((Selectable)__instance.screenText).Select(); return false; } } [HarmonyPatch(typeof(HUDManager), "FillEndGameStats")] [HarmonyPriority(0)] public class FillEndGameStatsPatch { private static bool Prefix(HUDManager __instance, EndOfGameStats stats, int scrapCollected = 0) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 PlayerControllerB[] allPlayerScripts = __instance.playersManager.allPlayerScripts; List<(string, int, bool, bool)> list = new List<(string, int, bool, bool)>(); int num = 0; int num2 = 0; for (int i = 0; i < allPlayerScripts.Length; i++) { PlayerControllerB val = allPlayerScripts[i]; if (val.isPlayerControlled || val.isPlayerDead || val.disconnectedMidGame) { if (val.isPlayerDead) { num++; } else if (val.isPlayerControlled) { num2++; } bool item = val.isPlayerDead && (int)val.causeOfDeath == 10; int profitable = stats.allPlayerStats[i].profitable; list.Add((val.playerUsername, profitable, val.isPlayerDead, item)); } } list = list.OrderByDescending<(string, int, bool, bool), int>(((string name, int scrap, bool isDead, bool isMissing) p) => p.scrap).ToList(); EndOfGameStatUIElements statsUIElements = __instance.statsUIElements; for (int j = 0; j < statsUIElements.playerNamesText.Length; j++) { ((TMP_Text)statsUIElements.playerNamesText[j]).text = ""; ((TMP_Text)statsUIElements.playerNotesText[j]).text = ""; ((Behaviour)statsUIElements.playerStates[j]).enabled = false; } for (int k = 0; k < list.Count && k < statsUIElements.playerNamesText.Length; k++) { (string, int, bool, bool) tuple = list[k]; string text = k switch { 2 => "#3", 1 => "#2", 0 => "#1", _ => "#" + (k + 1), }; ((TMP_Text)statsUIElements.playerNamesText[k]).text = text + " " + tuple.Item1; ((TMP_Text)statsUIElements.playerNotesText[k]).text = "Scrap: $" + tuple.Item2; ((TMP_Text)statsUIElements.playerNotesText[k]).fontSize = 16f; ((Behaviour)statsUIElements.playerStates[k]).enabled = true; statsUIElements.playerStates[k].sprite = (tuple.Item3 ? (tuple.Item4 ? statsUIElements.missingIcon : statsUIElements.deceasedIcon) : statsUIElements.aliveIcon); } ((TMP_Text)statsUIElements.quotaNumerator).text = scrapCollected.ToString(); ((TMP_Text)statsUIElements.quotaDenominator).text = RoundManager.Instance.totalScrapValueInLevel.ToString(); if (StartOfRound.Instance.allPlayersDead) { ((Behaviour)statsUIElements.allPlayersDeadOverlay).enabled = true; ((TMP_Text)statsUIElements.gradeLetter).text = "F"; return false; } ((Behaviour)statsUIElements.allPlayersDeadOverlay).enabled = false; int num3 = 0; float num4 = (float)RoundManager.Instance.scrapCollectedInLevel / RoundManager.Instance.totalScrapValueInLevel; if (num2 == StartOfRound.Instance.connectedPlayersAmount + 1) { num3++; } else if (num > 1) { num3--; } if (num4 >= 0.99f) { num3 += 2; } else if (num4 >= 0.6f) { num3++; } else if (num4 <= 0.25f) { num3--; } switch (num3) { case -1: ((TMP_Text)statsUIElements.gradeLetter).text = "D"; break; case 0: ((TMP_Text)statsUIElements.gradeLetter).text = "C"; break; case 1: ((TMP_Text)statsUIElements.gradeLetter).text = "B"; break; case 2: ((TMP_Text)statsUIElements.gradeLetter).text = "A"; break; case 3: ((TMP_Text)statsUIElements.gradeLetter).text = "S"; break; } return false; } } }