RUMBLE does not support other mod managers. If you want to use a manager, you must use the RUMBLE Mod Manager, a manager specifically designed for this game.
Decompiled source of MatchHistory v2.1.2
Mods/MatchHistory.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using Il2CppRUMBLE.Interactions.InteractionBase; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Networking.MatchFlow; using Il2CppRUMBLE.Players; using Il2CppRUMBLE.Utilities; using Il2CppSystem.Collections.Generic; using MatchHistory; using MelonLoader; using RumbleModUI; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::MatchHistory.MatchHistory), "MatchHistory", "2.1.2", "Baumritter", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: VerifyLoaderVersion(0, 6, 4, true)] [assembly: MelonColor(200, 0, 200, 0)] [assembly: MelonAuthorColor(200, 0, 200, 0)] [assembly: AssemblyTitle("MatchHistory")] [assembly: AssemblyDescription("Tracks matches and makes stats available")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MatchHistory")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8f661a7c-3b10-46a8-b2b1-ff3b3eed3a32")] [assembly: AssemblyFileVersion("2.1.2")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.1.2.0")] namespace MatchHistory; internal class General { internal class Delay { private readonly bool debug = false; private DateTime debugTime; private object CRObj; public string name = "Delay"; private bool Running = false; public bool Done = false; private DateTime StartTime; private double Wait; public void Delay_Start(double WaitTime, bool AllowRetrigger = false) { if (!Running || AllowRetrigger) { if (Running) { MelonCoroutines.Stop(CRObj); } Done = false; Wait = WaitTime; StartTime = DateTime.Now; debugTime = DateTime.Now; CRObj = MelonCoroutines.Start(WaitLoop()); if (debug) { MelonLogger.Msg(name + " - Started"); } } } public void Delay_Stop(bool Done = false) { if (Done) { this.Done = true; } if (Running) { MelonCoroutines.Stop(CRObj); } Running = false; if (debug && Done) { MelonLogger.Msg(name + " - Done"); } if (debug && !Done) { MelonLogger.Msg(name + " - Stopped"); } TimeSpan timeSpan = DateTime.Now - debugTime; if (debug && Done) { MelonLogger.Msg(name + " - " + timeSpan.TotalMilliseconds); } } private IEnumerator WaitLoop() { WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate(); Running = true; while (true) { if (DateTime.Now >= StartTime.AddSeconds(Wait)) { Delay_Stop(Done: true); yield return null; } yield return waitForFixedUpdate; } } } internal class Folders { private readonly bool debug = false; private string UserData = "UserData"; private string ModFolder; private List<string> SubFolders = new List<string>(); public void SetModFolderCustom(string ModName) { ModFolder = ModName; if (debug) { MelonLogger.Msg("Set ModFolder to " + ModFolder); } } public void SetModFolderNamespace() { ModFolder = GetType().Namespace; if (debug) { MelonLogger.Msg("Set ModFolder to " + ModFolder); } } public void AddSubFolder(string FolderName) { SubFolders.Add(FolderName); if (debug) { MelonLogger.Msg("Added Subfolder " + FolderName); } } public void RemoveSubFolder(string FolderName) { SubFolders.Remove(FolderName); if (debug) { MelonLogger.Msg("Removed Subfolder " + FolderName); } } public void CheckAllFoldersExist() { CreateFolderIfNotExisting(GetFolderString()); if (SubFolders.Count <= 0) { return; } foreach (string subFolder in SubFolders) { CreateFolderIfNotExisting(GetFolderString(subFolder)); } } public void RemoveOtherFolders() { if (debug) { MelonLogger.Msg("Folder Removal: Start"); } string[] directories = Directory.GetDirectories(GetFolderString("", IgnoreList: true)); string[] array = directories; foreach (string text in array) { if (debug) { MelonLogger.Msg(text); } string text2 = text.Split(new char[1] { '\\' })[^1]; if (CheckIfFolderInList(text2)) { Directory.Delete(GetFolderString(text2, IgnoreList: true), recursive: true); if (debug) { MelonLogger.Msg("Deleted: " + GetFolderString(text2, IgnoreList: true)); } } } if (debug) { MelonLogger.Msg("Folder Removal: End"); } } public string GetFolderString(string SubFolder = "", bool IgnoreList = false) { string text = UserData + "\\" + ModFolder; if (SubFolder != "" && (SubFolders.Contains(SubFolder) || IgnoreList)) { text = ((!IgnoreList) ? (text + "\\" + SubFolders.FirstOrDefault((string x) => x.Contains(SubFolder))) : (text + "\\" + SubFolder)); if (debug) { MelonLogger.Msg("Generated Path: " + text); } } else if (debug) { MelonLogger.Msg("Generated Path with no SubFolder: " + text); } return text; } private void CreateFolderIfNotExisting(string Path) { if (debug && !Directory.Exists(Path)) { MelonLogger.Msg("Path doesn't exist: " + Path); } else if (debug && Directory.Exists(Path)) { MelonLogger.Msg("Path does exist: " + Path); } if (!Directory.Exists(Path)) { Directory.CreateDirectory(Path); } } private bool CheckIfFolderInList(string FolderName) { bool flag = false; string folderString = GetFolderString(FolderName, IgnoreList: true); if (!SubFolders.Contains(FolderName) && Directory.Exists(folderString)) { flag = true; } if (debug && flag) { MelonLogger.Msg("Folder not in List " + folderString); } else if (debug && !flag) { MelonLogger.Msg("Folder in List " + folderString); } return flag; } } internal class Button { private GameObject ButtonTemplate; public List<GameObject> Buttons = new List<GameObject>(); public void GetTemplateButton() { if ((Object)(object)ButtonTemplate == (Object)null) { GameObject val = GameObject.Find("------------TUTORIAL------------/Static tutorials/RUMBLE Starter Guide/Next Page Button/InteractionButton"); ButtonTemplate = Object.Instantiate<GameObject>(val); ((UnityEventBase)((Component)ButtonTemplate.transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed).m_PersistentCalls.Clear(); ((Object)ButtonTemplate).name = "ButtonTemplate"; ButtonTemplate.SetActive(false); Object.DontDestroyOnLoad((Object)(object)ButtonTemplate); } } public void AddButton(string name) { GameObject val = Object.Instantiate<GameObject>(ButtonTemplate); ((Object)val).name = name; Buttons.Add(val); } public void RemoveButton(string name) { Enumerator<GameObject> enumerator = Buttons.GetEnumerator(); while (enumerator.MoveNext()) { GameObject current = enumerator.Current; if (((Object)current).name == name) { GameObject val = current; Buttons.Remove(val); break; } } } public UnityEvent OnPressed(string name = "", int index = -1) { if (name != "") { int num = SearchButtonList(name); if (num != -1) { return ((Component)Buttons[num].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed; } return ((Component)Buttons[0].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed; } if (index != -1) { return ((Component)Buttons[index].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed; } return ((Component)Buttons[0].transform.GetChild(0)).GetComponent<InteractionButton>().OnPressed; } private int SearchButtonList(string name) { for (int i = 0; i < Buttons.Count; i++) { if (((Object)Buttons[i]).name == name) { return i; } } return -1; } } internal class StringExtension { public enum Colors { Red, Yellow, Green, Blue } public static string ApplyColor(string Input, Colors color) { return color switch { Colors.Red => "<color=red>" + Input + "</color>", Colors.Yellow => "<color=yellow>" + Input + "</color>", Colors.Green => "<color=green>" + Input + "</color>", Colors.Blue => "<color=blue>" + Input + "</color>", _ => "<color=black>" + Input + "</color>", }; } } } internal class Data { public class PlayerData { public string UserID { get; set; } public string Name { get; set; } public int BP { get; set; } public PlayerData() { Init(); } public PlayerData(Player player) { SetDataFromPlayer(player); } public void SetDataFromPlayer(Player player) { GeneralData generalData = player.Data.GeneralData; UserID = generalData.InternalUsername; Name = SanitizeName(generalData.PublicUsername); BP = generalData.BattlePoints; } public override string ToString() { return UserID + " " + Name + " : " + BP; } private string SanitizeName(string Input) { bool flag = false; char[] array = Input.ToCharArray(); string text = ""; if (Input.Contains("<u>")) { Input.Replace("<u>", ""); } if (Input.Contains(",")) { Input.Replace(",", ""); } for (int i = 0; i < Input.Length; i++) { if (array[i] == '<' && i != Input.Length && (array[i + 1] == '#' || array[i + 1] == 'c')) { flag = true; } if (!flag) { text += array[i]; } if (array[i] == '>') { flag = false; } } return text; } private void Init() { UserID = "0"; Name = "Player"; BP = 0; } } public class RoundData { public enum RoundResult { P1Win, P2Win, Undefined } public int Index { get; set; } public int P1_HP { get; set; } public int P2_HP { get; set; } public TimeSpan RoundTime { get; set; } public RoundResult Result { get; set; } public RoundData() { Init(); } public RoundData(int Index, int P1_HP, int P2_HP, RoundResult result) { SetData(Index, P1_HP, P2_HP, result); } public void SetData(int Index, int P1_HP, int P2_HP, RoundResult result) { this.Index = Index; this.P1_HP = P1_HP; this.P2_HP = P2_HP; Result = result; } public void SetRoundTime(DateTime From, DateTime To) { RoundTime = From - To; } public override string ToString() { return Index + " " + P1_HP + " " + P2_HP + " " + Result; } private void Init() { Index = -1; P1_HP = -1; P2_HP = -1; Result = RoundResult.Undefined; RoundTime = TimeSpan.Zero; } } public class MatchData { public enum MatchResult { P1Win, P2Win, Tie, P1Dc, P2Dc, Undefined } private int CurrentRound { get; set; } public PlayerData P1 { get; set; } public PlayerData P2 { get; set; } public RoundData[] Rounds { get; set; } public MatchResult Result { get; set; } public MatchData() { Rounds = new RoundData[3]; for (int i = 0; i < Rounds.Length; i++) { Rounds[i] = new RoundData(); } Result = MatchResult.Undefined; P1 = new PlayerData(); P2 = new PlayerData(); CurrentRound = 1; } public string GetHash() { return P1.Name + P1.BP + P2.Name + P2.BP; } public void InitPlayers(Player P1Data, Player P2Data) { P1.SetDataFromPlayer(P1Data); P2.SetDataFromPlayer(P2Data); } public void SetRoundTime(DateTime From, DateTime To) { Rounds[CurrentRound - 1].SetRoundTime(From, To); } public void SetRound(int P1_HP, int P2_HP, RoundData.RoundResult result) { Rounds[CurrentRound - 1].SetData(CurrentRound, P1_HP, P2_HP, result); CurrentRound++; } public int GetRoundNr() { return CurrentRound; } public void CalculateMatchResult() { int num = 0; int num2 = 0; RoundData[] rounds = Rounds; foreach (RoundData roundData in rounds) { if (roundData.Result == RoundData.RoundResult.P1Win) { num++; } else if (roundData.Result == RoundData.RoundResult.P2Win) { num2++; } } if (num > num2) { Result = MatchResult.P1Win; } else if (num < num2) { Result = MatchResult.P2Win; } else if (num == num2) { Result = MatchResult.Tie; } } public string GetStatusString(bool FileOutput) { string text = ((!FileOutput) ? "" : (P1.Name + " vs " + P2.Name + Environment.NewLine + Environment.NewLine)); RoundData[] rounds = Rounds; foreach (RoundData roundData in rounds) { if (roundData.Index != -1) { text = text + "Round " + roundData.Index + " : " + roundData.RoundTime.ToString("mm\\:ss") + " : "; text = (FileOutput ? ((roundData.Result == RoundData.RoundResult.P1Win) ? (text + "You won" + Environment.NewLine) : ((roundData.Result != RoundData.RoundResult.P2Win) ? (text + "No Result" + Environment.NewLine) : (text + "Opponent won" + Environment.NewLine))) : ((roundData.Result == RoundData.RoundResult.P1Win) ? (text + General.StringExtension.ApplyColor("You won", General.StringExtension.Colors.Green) + Environment.NewLine) : ((roundData.Result != RoundData.RoundResult.P2Win) ? (text + General.StringExtension.ApplyColor("No Result", General.StringExtension.Colors.Yellow) + Environment.NewLine) : (text + General.StringExtension.ApplyColor("Opponent won", General.StringExtension.Colors.Red) + Environment.NewLine)))); text = text + "Your HP: " + roundData.P1_HP + " --- Enemy HP: " + roundData.P2_HP + Environment.NewLine + Environment.NewLine; } } text = text + "Match Result:" + Environment.NewLine; if (FileOutput) { switch (Result) { case MatchResult.P1Win: text += "You won"; break; case MatchResult.P2Win: text += "Opponent won"; break; case MatchResult.P1Dc: text += "You left"; break; case MatchResult.P2Dc: text += "Opponent left"; break; case MatchResult.Undefined: text += "No Result"; break; } } else { switch (Result) { case MatchResult.P1Win: text += General.StringExtension.ApplyColor("You won", General.StringExtension.Colors.Green); break; case MatchResult.P2Win: text += General.StringExtension.ApplyColor("Opponent won", General.StringExtension.Colors.Red); break; case MatchResult.P1Dc: text += General.StringExtension.ApplyColor("You left", General.StringExtension.Colors.Red); break; case MatchResult.P2Dc: text += General.StringExtension.ApplyColor("Opponent left", General.StringExtension.Colors.Red); break; case MatchResult.Undefined: text += General.StringExtension.ApplyColor("No Result", General.StringExtension.Colors.Yellow); break; } } return text; } } } public static class BuildInfo { public const string ModName = "MatchHistory"; public const string ModVersion = "2.1.2"; public const string Description = "Tracks matches and makes stats available"; public const string Author = "Baumritter"; public const string Company = ""; } public class MatchHistory : MelonMod { private string currentscene; private string LastMatch; private bool debug = false; private bool MatchRunning = false; private int MHL = 20; private DateTime Start; private DateTime End; private Data.MatchData CurrentMatch; private Data.MatchData PreviousMatch; private Player P1; private Player P2; private GameObject EndofMatchObject; private UI UI = UI.instance; private Mod Mod = new Mod(); private ModSetting<int> MatchHistoryLength = new ModSetting<int>(); private General.Folders Folders = new General.Folders(); private object C_Match; private object C_RoundEnd; private object C_RoundStart; public override void OnLateInitializeMelon() { ((MelonBase)this).OnLateInitializeMelon(); UI.UI_Initialized += OnUIInit; Folders.SetModFolderNamespace(); Folders.AddSubFolder("Logs"); Folders.CheckAllFoldersExist(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName); currentscene = sceneName; if ((currentscene == "Map0" || currentscene == "Map1") && C_Match == null) { C_Match = MelonCoroutines.Start(WaitForMatchStart()); } } public override void OnApplicationQuit() { ((MelonBase)this).OnApplicationQuit(); if (MatchRunning) { OnMatchEnd(Data.MatchData.MatchResult.P1Dc); KillMatchFlow("Game closed."); if (debug) { MelonLogger.Msg(LastMatch); } } } private void OnUIInit() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown Mod.ModName = "MatchHistory"; Mod.ModVersion = "2.1.2"; Mod.SetFolder("MatchHistory"); Mod.AddDescription("Description", "", "Settings for the Match History", new Tags { IsSummary = true }); Mod.AddToList("Match History Length", 20, "Defines how many Matches should be kept in the record." + Environment.NewLine + "Default: 20", new Tags()); Mod.GetFromFile(); AddLogFileToSettings(); UI.AddMod(Mod); MelonLoggerExtension.Log("Added Mod."); } private IEnumerator WaitForMatchStart() { WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate(); bool GymDelayTrigger = false; DateTime GymDelay = DateTime.Now; if (debug) { MelonLogger.Msg("Matchflow - Waiting for Match Start"); } while (true) { if (currentscene != "Gym") { GymDelayTrigger = false; } if (!GymDelayTrigger && currentscene == "Gym") { GymDelay = DateTime.Now; GymDelayTrigger = true; } if (GymDelayTrigger && GymDelay.AddSeconds(2.0) < DateTime.Now) { KillMatchFlow("Gym loaded for more than 2 seconds."); } if ((int)Singleton<MatchHandler>.instance.CurrentMatchPhase == 2) { OnMatchStart(); yield return null; } yield return waitForFixedUpdate; } } private void OnMatchStart() { if (C_Match != null) { MelonCoroutines.Stop(C_Match); } if (debug) { MelonLogger.Msg("Matchflow - Match started"); } CurrentMatch = new Data.MatchData(); P1 = Singleton<PlayerManager>.instance.LocalPlayer; if (Singleton<PlayerManager>.instance.AllPlayers.Count == 1) { CurrentMatch.P1.SetDataFromPlayer(P1); OnMatchEnd(Data.MatchData.MatchResult.P2Dc); return; } P2 = Singleton<PlayerManager>.instance.AllPlayers[1]; if (debug) { MelonLogger.Msg("Matchflow - Data got"); } CurrentMatch.InitPlayers(P1, P2); MatchRunning = true; Start = DateTime.Now; EndofMatchObject = ((Component)GameObject.Find("Logic/MatchSlabOne").transform.GetChild(2).GetChild(0).GetChild(0)).gameObject; C_RoundEnd = MelonCoroutines.Start(WaitForRoundEnd()); } private IEnumerator WaitForRoundEnd() { WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate(); if (debug) { MelonLogger.Msg("Matchflow - Waiting for Round End"); } while (true) { if (Singleton<PlayerManager>.instance.AllPlayers.Count == 1) { OnMatchEnd(Data.MatchData.MatchResult.P2Dc); yield return null; } else if ((int)Singleton<MatchHandler>.instance.CurrentMatchPhase == 4) { OnRoundEnd(); yield return null; } yield return waitForFixedUpdate; } } private void OnRoundEnd() { if (C_RoundEnd != null) { MelonCoroutines.Stop(C_RoundEnd); } End = DateTime.Now; int healthPoints = P1.Data.HealthPoints; int healthPoints2 = P2.Data.HealthPoints; Data.RoundData.RoundResult result = ((healthPoints <= healthPoints2) ? Data.RoundData.RoundResult.P2Win : Data.RoundData.RoundResult.P1Win); CurrentMatch.SetRoundTime(Start, End); CurrentMatch.SetRound(healthPoints, healthPoints2, result); if (debug) { MelonLogger.Msg("Matchflow - Round ended"); } C_RoundStart = MelonCoroutines.Start(WaitForRoundStart()); } private IEnumerator WaitForRoundStart() { WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate(); if (debug) { MelonLogger.Msg("Matchflow - Waiting for Round Start"); } while (true) { if (EndofMatchObject.active) { if (debug) { MelonLogger.Msg("Matchflow - End of Match Object found"); } OnMatchEnd(); yield return null; } else if ((int)Singleton<MatchHandler>.instance.CurrentMatchPhase == 2) { OnRoundStart(); yield return null; } yield return waitForFixedUpdate; } } private void OnRoundStart() { if (C_RoundStart != null) { MelonCoroutines.Stop(C_RoundStart); } Start = DateTime.Now; if (debug) { MelonLogger.Msg("Matchflow - Round started"); } C_RoundEnd = MelonCoroutines.Start(WaitForRoundEnd()); } private void OnMatchEnd(Data.MatchData.MatchResult ForceResult = Data.MatchData.MatchResult.Undefined) { if (C_RoundEnd != null) { MelonCoroutines.Stop(C_RoundEnd); } if (C_RoundStart != null) { MelonCoroutines.Stop(C_RoundStart); } MatchRunning = false; if (PreviousMatch != null && PreviousMatch.GetHash() == CurrentMatch.GetHash()) { if (debug) { MelonLogger.Msg("Tried to log same match again"); } return; } if (ForceResult != Data.MatchData.MatchResult.Undefined) { CurrentMatch.Result = ForceResult; } else { CurrentMatch.CalculateMatchResult(); } if (debug) { MelonLogger.Msg("Matchflow - Match stopped"); } LastMatch = CurrentMatch.GetStatusString(FileOutput: true); AddCurrentLogToSettings(); LogMatchHistory(LastMatch); PreviousMatch = CurrentMatch; MelonLogger.Msg("Match logged"); if (debug) { MelonLogger.Msg(LastMatch); } C_Match = MelonCoroutines.Start(WaitForMatchStart()); } private void KillMatchFlow(string Reason) { if (C_Match != null) { MelonCoroutines.Stop(C_Match); } if (C_RoundEnd != null) { MelonCoroutines.Stop(C_RoundEnd); } if (C_RoundStart != null) { MelonCoroutines.Stop(C_RoundStart); } if (debug) { MelonLogger.Msg("Matchflow - Terminated: " + Reason); } } private void LogMatchHistory(string Output) { string path = Folders.GetFolderString("Logs") + "\\Match_" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".txt"; MHL = (int)((ModSetting)MatchHistoryLength).SavedValue; if (Directory.GetFiles(Folders.GetFolderString("Logs")).Length > 20) { foreach (FileInfo item in (from x in new DirectoryInfo(Folders.GetFolderString("Logs")).GetFiles() orderby x.LastWriteTime descending select x).Skip(MHL)) { item.Delete(); } } File.WriteAllText(path, Output); if (debug) { MelonLogger.Msg("Log Written"); } } private void AddCurrentLogToSettings() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown string text = CurrentMatch.P2.Name + " - " + DateTime.Now.ToString("HH:mm"); Mod.AddDescription(text, "", CurrentMatch.GetStatusString(FileOutput: false), new Tags { IsEmpty = true }); UI.ForceRefresh(); } private void AddLogFileToSettings() { //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown string folderString = Folders.GetFolderString("Logs"); string[] files = Directory.GetFiles(folderString); foreach (string text in files) { string[] array = File.ReadAllLines(text); string text2 = ""; string text3 = array[0].Substring(array[0].IndexOf(" vs ") + 4).Replace(Environment.NewLine, ""); string text4 = text.Split(new char[1] { '_' })[2].Replace(".txt", ""); string text5 = text4.Substring(0, 2); string text6 = text4.Substring(2); text4 = text5 + ":" + text6; string text7 = text3 + " - " + text4; for (int j = 2; j < array.Length; j++) { text2 = ((!array[j].Contains("You won")) ? ((!array[j].Contains("Opponent won")) ? ((!array[j].Contains("No Result")) ? ((!array[j].Contains("You left")) ? ((!array[j].Contains("Opponent left")) ? (text2 + array[j] + Environment.NewLine) : (text2 + array[j].Replace("Opponent left", General.StringExtension.ApplyColor("Opponent left", General.StringExtension.Colors.Red)) + Environment.NewLine)) : (text2 + array[j].Replace("You left", General.StringExtension.ApplyColor("You left", General.StringExtension.Colors.Red)) + Environment.NewLine)) : (text2 + array[j].Replace("No Result", General.StringExtension.ApplyColor("No Result", General.StringExtension.Colors.Yellow)) + Environment.NewLine)) : (text2 + array[j].Replace("Opponent won", General.StringExtension.ApplyColor("Opponent won", General.StringExtension.Colors.Red)) + Environment.NewLine)) : (text2 + array[j].Replace("You won", General.StringExtension.ApplyColor("You won", General.StringExtension.Colors.Green)) + Environment.NewLine)); } Mod.AddDescription(text7, "", text2, new Tags { IsEmpty = true }); } } }