using System;
using System.Diagnostics;
using System.IO;
using System.Media;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using ParkMatches;
using Photon.Pun;
using RUMBLE.Environment;
using RUMBLE.Environment.Park;
using RUMBLE.Interactions.InteractionBase;
using RUMBLE.Managers;
using RUMBLE.Players;
using RUMBLE.Players.Subsystems;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(ParkMatchesClass), "Park Matches", "1.0.2", "UlvakSkillz", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: AssemblyTitle("ParkMatches")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ParkMatches")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2d9b3ff8-39c5-41fe-8004-afe2d753d3cd")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
public static class Patch
{
private static Harmony harmony = new Harmony("_ParkMatchesClass");
public static void Start()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
harmony.Patch((MethodBase)AccessTools.Method(typeof(ParkInstance), "RPC_CleanScene", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patch), "RPCCleanScenePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
private static void RPCCleanScenePostfix(ParkInstance __instance)
{
if (!ParkMatchesClass.instance.isActive || !(ParkMatchesClass.instance.matchBufferTimer <= DateTime.Now))
{
return;
}
List<Player> allPlayers = ParkMatchesClass.instance.playerManager.AllPlayers;
if (allPlayers.Count < 2 || ParkMatchesClass.instance.fightStarted)
{
return;
}
int num = 256;
Enumerator<Player> enumerator = allPlayers.GetEnumerator();
while (enumerator.MoveNext())
{
Player current = enumerator.Current;
if (ParkMatchesClass.instance.localPlayer == current)
{
ParkMatchesClass.instance.clientActorNumber = current.Data.GeneralData.ActorNo;
}
if (current.Data.GeneralData.ActorNo == 1)
{
ParkMatchesClass.instance.hostPlayer = current;
}
else if (num == 256)
{
num = current.Data.GeneralData.ActorNo;
}
else if (current.Data.GeneralData.ActorNo < num)
{
num = current.Data.GeneralData.ActorNo;
}
}
MelonLogger.Msg($"Found Lowest Actor: {num} | Player's: {ParkMatchesClass.instance.localPlayer.Data.GeneralData.ActorNo}");
if (ParkMatchesClass.instance.isHost || ParkMatchesClass.instance.localPlayer.Data.GeneralData.ActorNo == num)
{
MelonLogger.Msg("Player Included");
ParkMatchesClass.instance.StartFight();
}
else
{
MelonLogger.Msg("Player Excluded");
}
}
}
namespace ParkMatches;
public class ParkMatchesClass : MelonMod
{
private string settingsFile = "UserData/ParkMatches/Settings.txt";
public bool isActive;
public static ParkMatchesClass instance;
private InteractionButton parkResetSceneButton;
public PlayerManager playerManager;
private PlayerResetSystem localResetSystem;
private ParkMatchCounter parkMatchCounter;
public DateTime matchBufferTimer;
private Vector3 hostRespawn = new Vector3(-8.65f, -5.5f, -5.75f);
private Quaternion hostRotation = Quaternion.Euler(0f, 40f, 0f);
private Vector3 clientRespawn = new Vector3(2f, -5.5f, 8f);
private Quaternion clientRotation = Quaternion.Euler(0f, 220f, 0f);
private bool sceneChanged;
private string currentScene = "";
public bool fightStarted = false;
private bool atRoundStart = false;
public bool isHost = true;
private int hostPoints;
private int clientPoints;
private PlayerHealth localPlayerHealth;
private PlayerHealth otherPlayerHealth;
public Player hostPlayer;
public Player clientPlayer;
public short clientActorNumber;
public Player localPlayer;
private DateTime localDeathTimer;
private DateTime otherDeathTimer;
private DateTime redeathPreventionTimer;
private bool localDeathTimerActive = false;
private bool otherDeathTimerActive = false;
private bool waitedAnUpdate = false;
private string[] FilePaths = new string[6];
private static Thread[] threads = new Thread[3];
private static bool[] threadActive = new bool[threads.Length];
public override void OnInitializeMelon()
{
instance = this;
matchBufferTimer = DateTime.Now;
Patch.Start();
FilePaths[0] = "UserData\\ParkMatches\\DingDing.wav";
FilePaths[1] = "UserData\\ParkMatches\\YouWin.wav";
FilePaths[2] = "UserData\\ParkMatches\\YouLose.wav";
FilePaths[3] = "UserData\\ParkMatches\\ExitArena.wav";
FilePaths[4] = "UserData\\ParkMatches\\EnterArena.wav";
FilePaths[5] = "UserData\\ParkMatches\\NewRoundStart.wav";
bool flag = true;
for (int i = 0; i < FilePaths.Length; i++)
{
if (!File.Exists(FilePaths[i]))
{
flag = false;
MelonLogger.Msg(FilePaths[i] + " Doesn't Exist!");
}
}
if (flag)
{
MelonLogger.Msg("Initialized");
}
else
{
MelonLogger.Msg("Initialized with Sound Files Missing");
}
}
public override void OnFixedUpdate()
{
CheckForSceneChange();
if (fightStarted)
{
if (!atRoundStart && redeathPreventionTimer <= DateTime.Now)
{
CheckHealths();
CheckPositions();
}
if (atRoundStart && redeathPreventionTimer <= DateTime.Now)
{
parkResetSceneButton.RPC_OnPressed();
ResetPlayers();
PlaySoundIfFileExists(FilePaths[5], 0);
atRoundStart = false;
}
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
sceneChanged = true;
currentScene = sceneName;
}
public void CheckPositions()
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: 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_02c8: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(-3.15f, 0.25f);
Vector2 val2 = default(Vector2);
val2.x = ((Component)((Component)playerManager.localPlayer.Controller).gameObject.transform.GetChild(2).GetChild(13).GetChild(0)).gameObject.transform.position.x;
val2.y = ((Component)((Component)playerManager.localPlayer.Controller).gameObject.transform.GetChild(2).GetChild(13).GetChild(0)).gameObject.transform.position.z;
float num = Vector2.Distance(val2, val);
if (localDeathTimerActive && num < 12f)
{
PlaySoundIfFileExists(FilePaths[4], 2);
localDeathTimerActive = false;
}
if (localDeathTimerActive)
{
if (localDeathTimer <= DateTime.Now)
{
if (waitedAnUpdate)
{
localPlayerHealth.SetHealth((short)0, playerManager.AllPlayers[0].Data.HealthPoints, true);
MelonLogger.Msg($"Host player died from outside arena | Distance: {num}");
localDeathTimerActive = false;
waitedAnUpdate = false;
}
else
{
waitedAnUpdate = true;
}
}
}
else if (num >= 12f && !atRoundStart)
{
PlaySoundIfFileExists(FilePaths[3], 1);
localDeathTimer = DateTime.Now.AddSeconds(2.0);
localDeathTimerActive = true;
}
if (isHost)
{
val2.x = ((Component)((Component)clientPlayer.Controller).gameObject.transform.GetChild(3).GetChild(13).GetChild(0)).transform.position.x;
val2.y = ((Component)((Component)clientPlayer.Controller).gameObject.transform.GetChild(3).GetChild(13).GetChild(0)).transform.position.z;
}
else
{
val2.x = ((Component)((Component)hostPlayer.Controller).gameObject.transform.GetChild(3).GetChild(13).GetChild(0)).transform.position.x;
val2.y = ((Component)((Component)hostPlayer.Controller).gameObject.transform.GetChild(3).GetChild(13).GetChild(0)).transform.position.z;
}
num = Vector2.Distance(val2, val);
if (otherDeathTimerActive && num < 12f)
{
otherDeathTimerActive = false;
}
if (otherDeathTimerActive)
{
if (otherDeathTimer <= DateTime.Now)
{
otherPlayerHealth.SetHealth((short)0, playerManager.AllPlayers[1].Data.HealthPoints, true);
MelonLogger.Msg($"Client player died from outside arena | Distance: {num}");
otherDeathTimerActive = false;
}
}
else if (num >= 13f)
{
otherDeathTimer = DateTime.Now.AddSeconds(2.0);
otherDeathTimerActive = true;
}
}
public void CheckHealths()
{
if (hostPlayer.Data.HealthPoints != 0 && clientPlayer.Data.HealthPoints != 0)
{
return;
}
if (clientPlayer.Data.HealthPoints == 0)
{
MelonLogger.Msg("0 hp On Client");
hostPoints++;
}
if (hostPlayer.Data.HealthPoints == 0)
{
MelonLogger.Msg("0 hp On Host");
clientPoints++;
}
if (hostPlayer.Data.HealthPoints == 0)
{
if (isHost)
{
otherPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[1].Data.HealthPoints, false);
}
else
{
localPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[0].Data.HealthPoints, false);
}
}
if (clientPlayer.Data.HealthPoints == 0)
{
if (isHost)
{
localPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[0].Data.HealthPoints, false);
}
else
{
otherPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[1].Data.HealthPoints, false);
}
}
if (hostPoints == 2 || clientPoints == 2)
{
if (clientPoints == 2)
{
MelonLogger.Msg("Client won");
if (isHost)
{
PlaySoundIfFileExists(FilePaths[2], 0);
}
else
{
PlaySoundIfFileExists(FilePaths[1], 0);
}
}
else
{
MelonLogger.Msg("Host won");
if (isHost)
{
PlaySoundIfFileExists(FilePaths[1], 0);
}
else
{
PlaySoundIfFileExists(FilePaths[2], 0);
}
}
matchBufferTimer = DateTime.Now.AddSeconds(1.0);
fightStarted = false;
parkMatchCounter.ringSize = 13f;
MelonLogger.Msg("Match Over");
}
else
{
MelonLogger.Msg("New Round");
redeathPreventionTimer = DateTime.Now.AddSeconds(3.0);
atRoundStart = true;
parkResetSceneButton.RPC_OnPressed();
ResetPlayers();
}
}
private void ResetPlayers()
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
MelonLogger.Msg("Resetting Players");
localPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[0].Data.HealthPoints, false);
otherPlayerHealth.SetHealth((short)20, playerManager.AllPlayers[1].Data.HealthPoints, false);
if (isHost)
{
localResetSystem.RPC_RelocatePlayerController(hostRespawn, hostRotation);
}
else
{
localResetSystem.RPC_RelocatePlayerController(clientRespawn, clientRotation);
}
}
public void CheckForSceneChange()
{
if (!sceneChanged)
{
return;
}
try
{
if (currentScene == "Park")
{
playerManager = GameObject.Find("Game Instance/Initializable/PlayerManager").GetComponent<PlayerManager>();
parkResetSceneButton = GameObject.Find("________________LOGIC__________________ /Heinhouwser products/Parkboard (Park)/Primary Display/Park/Minigame Start button/InteractionButton/Button").GetComponent<InteractionButton>();
parkMatchCounter = GameObject.Find("________________LOGIC__________________ /Park Toys/MatchCounter").GetComponent<ParkMatchCounter>();
localPlayerHealth = ((Component)GameObject.Find("Health/Local").transform.parent).GetComponent<PlayerHealth>();
localPlayer = playerManager.localPlayer;
localResetSystem = ((Component)playerManager.localPlayer.Controller).gameObject.GetComponent<PlayerResetSystem>();
isHost = PhotonNetwork.IsMasterClient;
MelonLogger.Msg("Reset Park Button Found");
}
else
{
if (currentScene == "Gym")
{
readSettingsFile();
}
fightStarted = false;
}
sceneChanged = false;
}
catch
{
}
}
public void StartFight()
{
MelonLogger.Msg("Starting Fight");
try
{
otherPlayerHealth = GameObject.Find("Player Controller(Clone)/Health").GetComponent<PlayerHealth>();
hostPoints = 0;
clientPoints = 0;
if (isHost)
{
hostPlayer = playerManager.AllPlayers[0];
clientPlayer = playerManager.AllPlayers[1];
}
else
{
hostPlayer = playerManager.AllPlayers[1];
clientPlayer = playerManager.AllPlayers[0];
}
PlaySoundIfFileExists(FilePaths[0], 0);
redeathPreventionTimer = DateTime.Now.AddSeconds(3.0);
atRoundStart = true;
localDeathTimerActive = false;
otherDeathTimerActive = false;
fightStarted = true;
ResetPlayers();
parkMatchCounter.ringSize = 50f;
MelonLogger.Msg("Match Started");
}
catch (Exception ex)
{
MelonLogger.Error("Error Starting Fight: " + ex.Message);
}
}
private void readSettingsFile()
{
if (File.Exists(settingsFile))
{
try
{
string[] array = File.ReadAllLines(settingsFile);
if (array[1].ToLower() == "true")
{
MelonLogger.Msg("Setting to Active");
isActive = true;
}
else
{
MelonLogger.Msg("Setting to Inactive");
isActive = false;
}
return;
}
catch
{
MelonLogger.Error("Error reading " + settingsFile + " ! Setting Inactive");
isActive = false;
return;
}
}
MelonLogger.Error(settingsFile + " does not Exist! Setting Inactive");
isActive = false;
}
private void PlaySoundIfFileExists(string soundFilePath, int threadToPlayOn)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
if (File.Exists(soundFilePath))
{
if (threadActive[threadToPlayOn])
{
return;
}
try
{
SoundPlayer player = new SoundPlayer(soundFilePath);
try
{
threadActive[threadToPlayOn] = true;
if (threads[threadToPlayOn] == null || !threads[threadToPlayOn].IsAlive)
{
threads[threadToPlayOn] = new Thread((ThreadStart)delegate
{
player.PlaySync();
threadActive[threadToPlayOn] = false;
});
threads[threadToPlayOn].Start();
}
return;
}
finally
{
if (player != null)
{
((IDisposable)player).Dispose();
}
}
}
catch (Exception ex)
{
MelonLogger.Msg("Error playing sound: " + ex.Message);
return;
}
}
MelonLogger.Msg("Sound File Doesn't Exist: " + soundFilePath);
}
}