Decompiled source of Rain Better Skateboards MONO v1.0.0

RainsBetterSkateboard.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RainsBetterSkateboard;
using RainsBetterSkateboard.Logging;
using ScheduleOne.Skating;
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(BetterSkateboardTweaks), "RainsBetterSkateboard", "1.0.0", "RainingDeath", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("FishNet.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RainsBetterSkateboard")]
[assembly: AssemblyConfiguration("DebugMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RainsBetterSkateboard")]
[assembly: AssemblyTitle("RainsBetterSkateboard")]
[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;
		}
	}
}
public class SkateConfigRoot
{
	public List<SkateboardBoard> Boards { get; set; } = new List<SkateboardBoard>();

}
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)
	{
		return new SkateboardBoard
		{
			Name = name,
			TopSpeed_Kmh = s.TopSpeed_Kmh,
			ReverseTopSpeed_Kmh = s.ReverseTopSpeed_Kmh,
			TurnForce = s.TurnForce,
			TurnChangeRate = s.TurnChangeRate,
			TurnReturnToRestRate = s.TurnReturnToRestRate,
			TurnSpeedBoost = s.TurnSpeedBoost,
			Gravity = s.Gravity,
			BrakeForce = s.BrakeForce,
			RotationClampForce = s.RotationClampForce,
			HoverForce = s.HoverForce,
			HoverHeight = s.HoverHeight,
			HoverRayLength = s.HoverRayLength,
			Hover_P = s.Hover_P,
			Hover_I = s.Hover_I,
			Hover_D = s.Hover_D,
			SlowOnTerrain = s.SlowOnTerrain,
			FrictionEnabled = s.FrictionEnabled,
			LongitudinalFrictionMultiplier = s.LongitudinalFrictionMultiplier,
			LateralFrictionForceMultiplier = s.LateralFrictionForceMultiplier,
			JumpForce = s.JumpForce,
			JumpDuration_Min = s.JumpDuration_Min,
			JumpDuration_Max = s.JumpDuration_Max,
			JumpForwardBoost = s.JumpForwardBoost,
			PushForceMultiplier = s.PushForceMultiplier,
			PushForceDuration = s.PushForceDuration,
			PushDelay = s.PushDelay,
			AirMovementEnabled = s.AirMovementEnabled,
			AirMovementForce = s.AirMovementForce,
			AirMovementJumpReductionDuration = s.AirMovementJumpReductionDuration
		};
	}
}
namespace RainsBetterSkateboard
{
	public class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			Log.LogInfo("Initializing RainsBetterSkateboard...");
		}
	}
	public sealed class BetterSkateboardTweaks : MelonMod
	{
		private const string ConfigPath = "Mods/BetterSkateboardConfig.json";

		private static SkateConfigRoot _config = new SkateConfigRoot();

		private static bool _hadConfigAtStart;

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

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!sceneName.Equals("Main", StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
			Dictionary<string, Skateboard> dictionary = (from s in Resources.FindObjectsOfTypeAll<Skateboard>()
				where Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)((Component)s).gameObject)
				group s by ((Object)((Component)s).gameObject).name).ToDictionary((IGrouping<string, Skateboard> g) => g.Key, (IGrouping<string, Skateboard> g) => g.First());
			if (dictionary.Count == 0)
			{
				MelonLogger.Warning("[BetterSkateboard] No Skateboard prefabs were found via Resources.");
				return;
			}
			string[] value = dictionary.Keys.OrderBy((string n) => n).ToArray();
			MelonLogger.Msg("[BetterSkateboard] Prefabs discovered: " + string.Join(", ", value));
			if (!_hadConfigAtStart)
			{
				_config.Boards = dictionary.Select((KeyValuePair<string, Skateboard> kv) => SkateboardBoard.FromPrefab(kv.Key, kv.Value)).ToList();
				SafeWrite("Mods/BetterSkateboardConfig.json", JsonConvert.SerializeObject((object)_config, (Formatting)1));
				_hadConfigAtStart = true;
				MelonLogger.Msg("[BetterSkateboard] Wrote defaults → Mods/BetterSkateboardConfig.json");
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (SkateboardBoard board in _config.Boards)
			{
				if (board == null || string.IsNullOrEmpty(board.Name))
				{
					num2++;
					continue;
				}
				if (!dictionary.TryGetValue(board.Name, out var value2))
				{
					num2++;
					MelonLogger.Warning("[BetterSkateboard] Prefab not found for '" + board.Name + "' (exact match).");
					continue;
				}
				value2.TopSpeed_Kmh = board.TopSpeed_Kmh;
				value2.ReverseTopSpeed_Kmh = board.ReverseTopSpeed_Kmh;
				value2.TurnForce = board.TurnForce;
				value2.TurnChangeRate = board.TurnChangeRate;
				value2.TurnReturnToRestRate = board.TurnReturnToRestRate;
				value2.TurnSpeedBoost = board.TurnSpeedBoost;
				value2.Gravity = board.Gravity;
				value2.BrakeForce = board.BrakeForce;
				value2.RotationClampForce = board.RotationClampForce;
				value2.HoverForce = board.HoverForce;
				value2.HoverHeight = board.HoverHeight;
				value2.HoverRayLength = board.HoverRayLength;
				value2.Hover_P = board.Hover_P;
				value2.Hover_I = board.Hover_I;
				value2.Hover_D = board.Hover_D;
				value2.SlowOnTerrain = board.SlowOnTerrain;
				value2.FrictionEnabled = board.FrictionEnabled;
				value2.LongitudinalFrictionMultiplier = board.LongitudinalFrictionMultiplier;
				value2.LateralFrictionForceMultiplier = board.LateralFrictionForceMultiplier;
				value2.JumpForce = board.JumpForce;
				value2.JumpDuration_Min = board.JumpDuration_Min;
				value2.JumpDuration_Max = board.JumpDuration_Max;
				value2.JumpForwardBoost = board.JumpForwardBoost;
				value2.PushForceMultiplier = board.PushForceMultiplier;
				value2.PushForceDuration = board.PushForceDuration;
				value2.PushDelay = board.PushDelay;
				value2.AirMovementEnabled = board.AirMovementEnabled;
				value2.AirMovementForce = board.AirMovementForce;
				value2.AirMovementJumpReductionDuration = board.AirMovementJumpReductionDuration;
				num++;
				MelonLogger.Msg($"[BetterSkateboard] Patched prefab '{board.Name}' (HoverHeight={value2.HoverHeight}, HoverForce={value2.HoverForce}, TopSpeed_Kmh={value2.TopSpeed_Kmh})");
			}
			MelonLogger.Msg($"[BetterSkateboard] Applied {num} prefab(s) from config. Missing: {num2}.");
		}

		private static SkateConfigRoot LoadConfig(out bool had)
		{
			had = false;
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName("Mods/BetterSkateboardConfig.json"));
				if (!File.Exists("Mods/BetterSkateboardConfig.json"))
				{
					return null;
				}
				string text = File.ReadAllText("Mods/BetterSkateboardConfig.json");
				SkateConfigRoot skateConfigRoot = TryParse(text);
				if (skateConfigRoot?.Boards != null && skateConfigRoot.Boards.Count > 0)
				{
					had = true;
					return skateConfigRoot;
				}
			}
			catch
			{
			}
			return null;
		}

		private static SkateConfigRoot TryParse(string text)
		{
			try
			{
				SkateConfigRoot skateConfigRoot = JsonConvert.DeserializeObject<SkateConfigRoot>(text);
				if (skateConfigRoot != null && skateConfigRoot.Boards?.Count > 0)
				{
					return skateConfigRoot;
				}
			}
			catch
			{
			}
			try
			{
				List<SkateboardBoard> list = JsonConvert.DeserializeObject<List<SkateboardBoard>>(text);
				if (list != null && list.Count > 0)
				{
					return new SkateConfigRoot
					{
						Boards = list
					};
				}
			}
			catch
			{
			}
			try
			{
				SkateboardBoard skateboardBoard = JsonConvert.DeserializeObject<SkateboardBoard>(text);
				if (skateboardBoard != null && !string.IsNullOrEmpty(skateboardBoard.Name))
				{
					return new SkateConfigRoot
					{
						Boards = new List<SkateboardBoard> { skateboardBoard }
					};
				}
			}
			catch
			{
			}
			return null;
		}

		private static void SafeWrite(string path, string json)
		{
			try
			{
				if (File.Exists(path))
				{
					File.Copy(path, path + ".bak", overwrite: true);
				}
			}
			catch
			{
			}
			File.WriteAllText(path, json);
		}
	}
}
namespace RainsBetterSkateboard.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 System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}