Decompiled source of SteamTimelineIntegration v1.0.1

Mods/SteamTimelineIntegration.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppRUMBLE.Environment.MatchFlow;
using Il2CppRUMBLE.Networking.MatchFlow;
using Il2CppRUMBLE.Players;
using Il2CppRUMBLE.Utilities;
using Il2CppSteamworks;
using MelonLoader;
using Microsoft.CodeAnalysis;
using RumbleModUI;
using RumbleModdingAPI.RMAPI;
using SteamTimelineIntegration;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "SteamTimelineIntegration", "1.0.1", "Dazbii", null)]
[assembly: VerifyLoaderVersion(0, 7, 2)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 253, 188, 180)]
[assembly: MelonAuthorColor(255, 253, 188, 180)]
[assembly: AssemblyTitle("SteamTimelineIntegration")]
[assembly: AssemblyDescription("Rumble mod to enable integrations with the steam timeline ")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SteamTimelineIntegration")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("621d30a5-8fa1-4d87-9826-92c0149b033e")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(PedestalManager), "TeleportPedestalsToOwners")]
public static class Pedestal_Patch
{
	public static void Prefix()
	{
		Il2CppStructArray<int> roundsWonList = Singleton<MatchHandler>.Instance.RoundsWonList;
		int currentRound = Singleton<MatchHandler>.Instance.CurrentRound;
		Melon<Core>.Instance.RoundEnded(Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)roundsWonList), currentRound);
	}
}
namespace SteamTimelineIntegration
{
	public static class BuildInfo
	{
		public const string ModName = "SteamTimelineIntegration";

		public const string ModVersion = "1.0.1";

		public const string Description = "Rumble mod to enable integrations with the steam timeline ";

		public const string Author = "Dazbii";

		public const string Company = "";
	}
	internal enum Gamemode
	{
		Playing = 1,
		Park,
		Gym,
		BetweenMatches
	}
	public class Core : MelonMod
	{
		private Mod Mod = new Mod();

		private ModSetting<bool> incomingDamage;

		private ModSetting<bool> outgoingDamage;

		private string opponentName;

		private PlayerData player;

		private PlayerData opponent;

		private int clientRoundWins;

		private string previousOpponentName;

		private int cumulativeWins;

		private int cumulativeClientWins;

		private int cumulativeLosses;

		private int cumulativeHostLosses;

		private TimelineEventHandle_t roundEvent;

		public override void OnLateInitializeMelon()
		{
			((MelonBase)this).OnLateInitializeMelon();
			UI.instance.UI_Initialized += OnUIInit;
			Actions.onRoundStarted += RoundStarted;
			Actions.onMatchStarted += MatchStarted;
			Actions.onMatchEnded += MatchEnded;
			Actions.onPlayerHealthChanged += PlayerHealthChange;
		}

		public void OnUIInit()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			Mod.ModName = "SteamTimelineIntegration";
			Mod.ModVersion = "1.0.1";
			Mod.SetFolder("SteamTimelineIntegration");
			Mod.AddDescription("Description", "", "Rumble mod to enable integrations with the steam timeline ", new Tags
			{
				IsSummary = true
			});
			incomingDamage = Mod.AddToList("Incoming", false, 0, "!!WARNING: This will clutter your timeline!!\nIf true, this will set add a marker each time you take damage", new Tags());
			outgoingDamage = Mod.AddToList("Outgoing", false, 0, "!!WARNING: This will clutter your timeline!!\nIf true, this will set add a marker each time your opponent takes damage", new Tags());
			Mod.GetFromFile();
			UI.instance.AddMod(Mod);
			((MelonBase)this).LoggerInstance.Msg("Added Mod");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName);
			switch (sceneName)
			{
			case "Gym":
				SteamTimeline.SetTimelineGameMode((ETimelineGameMode)3);
				break;
			case "Park":
				SteamTimeline.SetTimelineGameMode((ETimelineGameMode)2);
				break;
			case "Map0":
			case "Map1":
				SteamTimeline.SetTimelineGameMode((ETimelineGameMode)4);
				break;
			}
		}

		private void PlayerHealthChange(Player damagedPlayer, int damage)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = damagedPlayer == player.Player;
			if ((flag && (bool)((ModSetting)incomingDamage).Value) || (!flag && (bool)((ModSetting)outgoingDamage).Value))
			{
				SteamTimeline.AddInstantaneousTimelineEvent($"{damage}", "", flag ? "steam_defend" : "steam_attack", 0u, 0f, (ETimelineEventClipPriority)1);
			}
		}

		private void RoundStarted()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			int value = Singleton<MatchHandler>.Instance.CurrentRound + 1;
			roundEvent = SteamTimeline.StartRangeTimelineEvent($"Round {value}", "Versus " + opponentName, "steam_pair", 1000u, 0f, (ETimelineEventClipPriority)2);
		}

		public void RoundEnded(int[] roundsWonList, int currentRound)
		{
			//IL_0066: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			WinsLosses winsLosses = Util.CalcWinsLosses(roundsWonList, currentRound);
			if ((!Players.IsHost() && player.HealthPoints > 0) || (Players.IsHost() && player.HealthPoints <= 0))
			{
				clientRoundWins++;
				if (!Players.IsHost())
				{
					cumulativeClientWins++;
				}
				else
				{
					cumulativeHostLosses++;
				}
			}
			SteamTimeline.UpdateRangeTimelineEvent(roundEvent, $"Round {currentRound}", "Versus " + opponentName, (player.HealthPoints > 0) ? "steam_crown" : "steam_death", 1000u, (ETimelineEventClipPriority)2);
			SteamTimeline.EndRangeTimelineEvent(roundEvent, 0f);
			SteamTimeline.AddInstantaneousTimelineEvent($"Round {currentRound} {((player.HealthPoints > 0) ? "Win" : "Loss")}", "Versus " + opponentName, (player.HealthPoints > 0) ? "steam_crown" : "steam_death", 900u, 0f, (ETimelineEventClipPriority)1);
			SteamTimeline.SetGamePhaseAttribute("Round Score", $"{winsLosses.wins}/{winsLosses.losses}", 2u);
		}

		private void MatchStarted()
		{
			opponent = Players.GetEnemyPlayers().First().Data;
			player = Players.GetLocalPlayer().Data;
			opponentName = Util.GetPlayerName(opponent);
			if (opponentName != previousOpponentName)
			{
				cumulativeClientWins = 0;
				cumulativeHostLosses = 0;
				cumulativeLosses = 0;
				cumulativeWins = 0;
			}
			previousOpponentName = opponentName;
			clientRoundWins = 0;
			SteamTimeline.SetTimelineGameMode((ETimelineGameMode)1);
			SteamTimeline.StartGamePhase();
			SteamTimeline.SetGamePhaseID("Match against " + opponentName);
			SteamTimeline.SetGamePhaseAttribute("Round Score", "0/0", 10u);
			SteamTimeline.SetGamePhaseAttribute("Opponent", opponentName, 9u);
			if (Players.IsHost())
			{
				SteamTimeline.SetGamePhaseAttribute("Host/Client", "Host", 10u);
			}
			else
			{
				SteamTimeline.SetGamePhaseAttribute("Host/Client", "Client", 10u);
			}
		}

		private void MatchEnded()
		{
			SteamTimeline.SetTimelineGameMode((ETimelineGameMode)4);
			if (player.MatchData.MatchPoints >= 2)
			{
				SteamTimeline.AddGamePhaseTag("Win", "steam_crown", "Result", 10u);
				cumulativeWins++;
				if (clientRoundWins == 2)
				{
					cumulativeClientWins -= 2;
				}
			}
			else
			{
				SteamTimeline.AddGamePhaseTag("Loss", "steam_death", "Result", 10u);
				cumulativeLosses++;
				if (clientRoundWins == 2)
				{
					cumulativeHostLosses -= 2;
				}
			}
			SteamTimeline.SetGamePhaseAttribute("Set Score", $"Set: {cumulativeWins}({cumulativeClientWins}) - {cumulativeLosses}({cumulativeHostLosses})", 10u);
			SteamTimeline.SetGamePhaseAttribute("Client Round Wins", $"Client round wins: {clientRoundWins}", 5u);
			SteamTimeline.EndGamePhase();
		}
	}
	internal class WinsLosses
	{
		public int wins;

		public int losses;
	}
	internal static class Util
	{
		public static WinsLosses CalcWinsLosses(int[] roundsWonList, int currentRound)
		{
			WinsLosses winsLosses = new WinsLosses();
			for (int i = 0; i <= currentRound; i++)
			{
				if (roundsWonList[i] == 1)
				{
					winsLosses.wins++;
				}
				else
				{
					winsLosses.losses++;
				}
			}
			return winsLosses;
		}

		public static string GetPlayerName(PlayerData player)
		{
			return Regex.Replace(player.GeneralData.PublicUsername, "<.*?>|\\(.*?\\)|[^a-zA-Z0-9_ ]", "");
		}
	}
}