using 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;
}
}
}