Decompiled source of Rain Better Skateboards IL2CPP v1.0.0

RainsBetterSkateboardsIL2CPP.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.Skating;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RainsBetterSkateboard;
using RainsBetterSkateboardsIL2CPP.Logging;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(BetterSkateboardTweaks_IL2CPP), "RainsBetterSkateboardsIL2CPP", "1.0.0", "RainingDeath", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("RainsBetterSkateboardsIL2CPP")]
[assembly: AssemblyConfiguration("DebugMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RainsBetterSkateboardsIL2CPP")]
[assembly: AssemblyTitle("RainsBetterSkateboardsIL2CPP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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;
		}
	}
}
[Serializable]
public class SkateConfigRoot
{
	public SkateboardBoard[] Boards = Array.Empty<SkateboardBoard>();
}
[Serializable]
public class SkateboardBoard
{
	public string Name;

	public float TopSpeed_Kmh;

	public float ReverseTopSpeed_Kmh;

	public float TurnForce;

	public float TurnChangeRate;

	public float TurnReturnToRestRate;

	public float TurnSpeedBoost;

	public float Gravity;

	public float BrakeForce;

	public float RotationClampForce;

	public float HoverForce;

	public float HoverHeight;

	public float HoverRayLength;

	public float Hover_P;

	public float Hover_I;

	public float Hover_D;

	public bool SlowOnTerrain;

	public bool FrictionEnabled;

	public float LongitudinalFrictionMultiplier;

	public float LateralFrictionForceMultiplier;

	public float JumpForce;

	public float JumpDuration_Min;

	public float JumpDuration_Max;

	public float JumpForwardBoost;

	public float PushForceMultiplier;

	public float PushForceDuration;

	public float PushDelay;

	public bool AirMovementEnabled;

	public float AirMovementForce;

	public float AirMovementJumpReductionDuration;

	public static SkateboardBoard FromPrefab(string name, Skateboard s)
	{
		SkateboardBoard skateboardBoard = new SkateboardBoard();
		skateboardBoard.Name = name;
		skateboardBoard.TopSpeed_Kmh = s.TopSpeed_Kmh;
		skateboardBoard.ReverseTopSpeed_Kmh = s.ReverseTopSpeed_Kmh;
		skateboardBoard.TurnForce = s.TurnForce;
		skateboardBoard.TurnChangeRate = s.TurnChangeRate;
		skateboardBoard.TurnReturnToRestRate = s.TurnReturnToRestRate;
		skateboardBoard.TurnSpeedBoost = s.TurnSpeedBoost;
		skateboardBoard.Gravity = s.Gravity;
		skateboardBoard.BrakeForce = s.BrakeForce;
		skateboardBoard.RotationClampForce = s.RotationClampForce;
		skateboardBoard.HoverForce = s.HoverForce;
		skateboardBoard.HoverHeight = s.HoverHeight;
		skateboardBoard.HoverRayLength = s.HoverRayLength;
		skateboardBoard.Hover_P = s.Hover_P;
		skateboardBoard.Hover_I = s.Hover_I;
		skateboardBoard.Hover_D = s.Hover_D;
		skateboardBoard.SlowOnTerrain = s.SlowOnTerrain;
		skateboardBoard.FrictionEnabled = s.FrictionEnabled;
		skateboardBoard.LongitudinalFrictionMultiplier = s.LongitudinalFrictionMultiplier;
		skateboardBoard.LateralFrictionForceMultiplier = s.LateralFrictionForceMultiplier;
		skateboardBoard.JumpForce = s.JumpForce;
		skateboardBoard.JumpDuration_Min = s.JumpDuration_Min;
		skateboardBoard.JumpDuration_Max = s.JumpDuration_Max;
		skateboardBoard.JumpForwardBoost = s.JumpForwardBoost;
		skateboardBoard.PushForceMultiplier = s.PushForceMultiplier;
		skateboardBoard.PushForceDuration = s.PushForceDuration;
		skateboardBoard.PushDelay = s.PushDelay;
		skateboardBoard.AirMovementEnabled = s.AirMovementEnabled;
		skateboardBoard.AirMovementForce = s.AirMovementForce;
		skateboardBoard.AirMovementJumpReductionDuration = s.AirMovementJumpReductionDuration;
		return skateboardBoard;
	}
}
namespace RainsBetterSkateboardsIL2CPP
{
	public class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Log.LogInfo("Initializing RainsBetterSkateboardsIL2CPP...");
		}
	}
}
namespace RainsBetterSkateboardsIL2CPP.Logging
{
	public static class Log
	{
		public static void LogInfo(string message)
		{
			Melon<Core>.Logger.Msg(message);
		}

		public static void LogWarning(string message)
		{
			Melon<Core>.Logger.Warning(message);
		}

		public static void LogError(string message)
		{
			Melon<Core>.Logger.Error(message);
		}

		public static void LogFatal(string message)
		{
			Melon<Core>.Logger.BigError(message);
		}
	}
}
namespace RainsBetterSkateboard
{
	public sealed class BetterSkateboardTweaks_IL2CPP : MelonMod
	{
		private static readonly string ConfigPath = Path.Combine(MelonEnvironment.ModsDirectory, "BetterSkateboardConfig.json");

		private static SkateConfigRoot _config = new SkateConfigRoot();

		private static bool _hadConfigAtStart;

		public override void OnInitializeMelon()
		{
			_config = LoadConfig(out _hadConfigAtStart) ?? new SkateConfigRoot();
			if (_hadConfigAtStart)
			{
				MelonLogger.Msg($"[BetterSkateboard] Loaded config for {_config.Boards.Length} boards at startup.");
			}
			else
			{
				MelonLogger.Msg("[BetterSkateboard] No valid config at startup; will write defaults after prefabs are found in Main.");
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!sceneName.Equals("Main", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			Dictionary<string, Skateboard> dictionary = FindSkateboardPrefabsByName();
			if (dictionary.Count == 0)
			{
				MelonLogger.Warning("[BetterSkateboard] Could not isolate any skateboard prefabs.");
				return;
			}
			List<string> list = new List<string>(dictionary.Keys);
			list.Sort(StringComparer.Ordinal);
			MelonLogger.Msg("[BetterSkateboard] Prefabs discovered: " + string.Join(", ", list.ToArray()));
			if (!_hadConfigAtStart)
			{
				List<SkateboardBoard> list2 = new List<SkateboardBoard>(dictionary.Count);
				foreach (KeyValuePair<string, Skateboard> item in dictionary)
				{
					list2.Add(SkateboardBoard.FromPrefab(item.Key, item.Value));
				}
				_config.Boards = list2.ToArray();
				string json = JsonConvert.SerializeObject((object)_config, (Formatting)1);
				SafeWrite(ConfigPath, json);
				_hadConfigAtStart = true;
				MelonLogger.Msg("[BetterSkateboard] Wrote defaults → " + ConfigPath);
				return;
			}
			int num = 0;
			int num2 = 0;
			SkateboardBoard[] boards = _config.Boards;
			if (boards != null)
			{
				foreach (SkateboardBoard skateboardBoard in boards)
				{
					if (skateboardBoard == null || string.IsNullOrEmpty(skateboardBoard.Name))
					{
						num2++;
						continue;
					}
					if (!dictionary.TryGetValue(skateboardBoard.Name, out var value) || (Object)(object)value == (Object)null)
					{
						num2++;
						MelonLogger.Warning("[BetterSkateboard] Prefab not found for '" + skateboardBoard.Name + "' (exact match).");
						continue;
					}
					value.TopSpeed_Kmh = skateboardBoard.TopSpeed_Kmh;
					value.ReverseTopSpeed_Kmh = skateboardBoard.ReverseTopSpeed_Kmh;
					value.TurnForce = skateboardBoard.TurnForce;
					value.TurnChangeRate = skateboardBoard.TurnChangeRate;
					value.TurnReturnToRestRate = skateboardBoard.TurnReturnToRestRate;
					value.TurnSpeedBoost = skateboardBoard.TurnSpeedBoost;
					value.Gravity = skateboardBoard.Gravity;
					value.BrakeForce = skateboardBoard.BrakeForce;
					value.RotationClampForce = skateboardBoard.RotationClampForce;
					value.HoverForce = skateboardBoard.HoverForce;
					value.HoverHeight = skateboardBoard.HoverHeight;
					value.HoverRayLength = skateboardBoard.HoverRayLength;
					value.Hover_P = skateboardBoard.Hover_P;
					value.Hover_I = skateboardBoard.Hover_I;
					value.Hover_D = skateboardBoard.Hover_D;
					value.SlowOnTerrain = skateboardBoard.SlowOnTerrain;
					value.FrictionEnabled = skateboardBoard.FrictionEnabled;
					value.LongitudinalFrictionMultiplier = skateboardBoard.LongitudinalFrictionMultiplier;
					value.LateralFrictionForceMultiplier = skateboardBoard.LateralFrictionForceMultiplier;
					value.JumpForce = skateboardBoard.JumpForce;
					value.JumpDuration_Min = skateboardBoard.JumpDuration_Min;
					value.JumpDuration_Max = skateboardBoard.JumpDuration_Max;
					value.JumpForwardBoost = skateboardBoard.JumpForwardBoost;
					value.PushForceMultiplier = skateboardBoard.PushForceMultiplier;
					value.PushForceDuration = skateboardBoard.PushForceDuration;
					value.PushDelay = skateboardBoard.PushDelay;
					value.AirMovementEnabled = skateboardBoard.AirMovementEnabled;
					value.AirMovementForce = skateboardBoard.AirMovementForce;
					value.AirMovementJumpReductionDuration = skateboardBoard.AirMovementJumpReductionDuration;
					num++;
					MelonLogger.Msg($"[BetterSkateboard] Patched '{skateboardBoard.Name}' (HoverHeight={value.HoverHeight}, HoverForce={value.HoverForce}, TopSpeed_Kmh={value.TopSpeed_Kmh})");
				}
			}
			MelonLogger.Msg($"[BetterSkateboard] Applied {num} prefab(s) from config. Missing: {num2}.");
		}

		private static Dictionary<string, Skateboard> FindSkateboardPrefabsByName()
		{
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Skateboard> dictionary = new Dictionary<string, Skateboard>(8);
			Il2CppReferenceArray<Object> val = Resources.FindObjectsOfTypeAll(Il2CppType.Of<Skateboard>());
			if (val == null || ((Il2CppArrayBase<Object>)(object)val).Length == 0)
			{
				return dictionary;
			}
			for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++)
			{
				Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i];
				Skateboard val3 = ((Il2CppObjectBase)val2).TryCast<Skateboard>();
				if (!((Object)(object)val3 == (Object)null))
				{
					object obj = ((Object)val3).name;
					if (obj == null)
					{
						GameObject gameObject = ((Component)val3).gameObject;
						obj = ((gameObject != null) ? ((Object)gameObject).name : null) ?? string.Empty;
					}
					string text = (string)obj;
					if (text.EndsWith("(Clone)", StringComparison.Ordinal))
					{
						text = text.Substring(0, text.Length - "(Clone)".Length).TrimEnd();
					}
					if (!string.IsNullOrEmpty(text) && !dictionary.ContainsKey(text))
					{
						dictionary.Add(text, val3);
					}
				}
			}
			if (dictionary.Count == 0)
			{
				List<string> list = new List<string>();
				for (int j = 0; j < ((Il2CppArrayBase<Object>)(object)val).Length; j++)
				{
					Object obj2 = ((Il2CppArrayBase<Object>)(object)val)[j];
					Skateboard val4 = (Skateboard)(object)((obj2 is Skateboard) ? obj2 : null);
					if (!((Object)(object)val4 == (Object)null))
					{
						DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(19, 3);
						defaultInterpolatedStringHandler.AppendFormatted(((Object)val4).name);
						defaultInterpolatedStringHandler.AppendLiteral(" (GO:");
						GameObject gameObject2 = ((Component)val4).gameObject;
						defaultInterpolatedStringHandler.AppendFormatted((gameObject2 != null) ? ((Object)gameObject2).name : null);
						defaultInterpolatedStringHandler.AppendLiteral(", sceneValid:");
						GameObject gameObject3 = ((Component)val4).gameObject;
						bool? value;
						if (gameObject3 == null)
						{
							value = null;
						}
						else
						{
							Scene scene = gameObject3.scene;
							value = ((Scene)(ref scene)).IsValid();
						}
						defaultInterpolatedStringHandler.AppendFormatted(value);
						defaultInterpolatedStringHandler.AppendLiteral(")");
						list.Add(defaultInterpolatedStringHandler.ToStringAndClear());
					}
				}
				MelonLogger.Warning("[BetterSkateboard] Saw Skateboards: " + string.Join(", ", list));
			}
			return dictionary;
		}

		private static SkateConfigRoot LoadConfig(out bool had)
		{
			had = false;
			try
			{
				string directoryName = Path.GetDirectoryName(ConfigPath);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				if (!File.Exists(ConfigPath))
				{
					return null;
				}
				string text = File.ReadAllText(ConfigPath);
				SkateConfigRoot skateConfigRoot = JsonConvert.DeserializeObject<SkateConfigRoot>(text);
				if (skateConfigRoot?.Boards != null && skateConfigRoot.Boards.Length != 0)
				{
					had = true;
					return skateConfigRoot;
				}
				if (text.TrimStart().StartsWith("["))
				{
					string text2 = "{\"Boards\":" + text + "}";
					skateConfigRoot = JsonConvert.DeserializeObject<SkateConfigRoot>(text2);
					if (skateConfigRoot?.Boards != null && skateConfigRoot.Boards.Length != 0)
					{
						had = true;
						return skateConfigRoot;
					}
				}
				SkateboardBoard skateboardBoard = JsonConvert.DeserializeObject<SkateboardBoard>(text);
				if (skateboardBoard != null && !string.IsNullOrEmpty(skateboardBoard.Name))
				{
					had = true;
					SkateConfigRoot skateConfigRoot2 = new SkateConfigRoot();
					skateConfigRoot2.Boards = new SkateboardBoard[1] { skateboardBoard };
					return skateConfigRoot2;
				}
				had = true;
				return new SkateConfigRoot
				{
					Boards = Array.Empty<SkateboardBoard>()
				};
			}
			catch
			{
				return null;
			}
		}

		private static void SafeWrite(string path, string json)
		{
			try
			{
				string directoryName = Path.GetDirectoryName(path);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				if (File.Exists(path))
				{
					File.Copy(path, path + ".bak", overwrite: true);
				}
				string text = path + ".tmp";
				File.WriteAllText(text, json);
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				File.Move(text, path);
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BetterSkateboard] SafeWrite failed: " + ex.Message);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}