Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ArenaRaceMultiplayerSpawnFix v4.0.0
ArenaRaceMultiplayerSpawnFix.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [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; } } } namespace REPOJP.ArenaRaceMultiplayerSpawnFix { [BepInPlugin("REPOJP.ArenaRaceMultiplayerSpawnFix", "ArenaRaceMultiplayerSpawnFix", "1.5.0")] public class ArenaRaceMultiplayerSpawnFixPlugin : BaseUnityPlugin { private sealed class LayoutPlan { public readonly List<Vector3> Positions = new List<Vector3>(); } [HarmonyPatch(typeof(LevelGenerator), "PlayerSpawn")] private static class LevelGeneratorPlayerSpawnPatch { private static void Postfix() { try { if (!ShouldApplyLayout()) { return; } lastStartBoostArenaRaceInstanceId = 0; List<PlayerAvatar> randomizedPlayers = GetRandomizedPlayers(); if (randomizedPlayers.Count != 0) { LayoutPlan layoutPlan = BuildLayoutPlan(randomizedPlayers); if (layoutPlan != null && layoutPlan.Positions.Count != 0) { ApplyLayout(randomizedPlayers, layoutPlan); } } } catch (Exception ex) { LogError("Failure: PlayerSpawn Postfix\n" + ex); } } } [HarmonyPatch(typeof(ArenaRace), "StateSetRPC")] private static class ArenaRaceStateSetRPCPatch { private static void Postfix(ArenaRace __instance, States _state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 try { if ((int)_state == 2) { ApplyStartBoostOnce(__instance); } } catch (Exception ex) { LogError("Failure: ArenaRace.StateSetRPC Postfix\n" + ex); } } } public const string PluginGuid = "REPOJP.ArenaRaceMultiplayerSpawnFix"; public const string PluginName = "ArenaRaceMultiplayerSpawnFix"; public const string PluginVersion = "1.5.0"; private const float FixedHorizontalSpacing = 0.8f; private const float FixedVerticalSpacing = 3f; private const float FixedHeightOffset = 5f; private const float FixedBackwardOffset = 10f; private static ManualLogSource logSource; private static Harmony harmony; private static ConfigEntry<bool> enabledConfig; private static ConfigEntry<int> horizontalPlayersConfig; private static ConfigEntry<int> verticalPlayersConfig; private static ConfigEntry<bool> startBoostEnabledConfig; private static ConfigEntry<float> startBoostMultiplierConfig; private static FieldInfo arenaRacePlayerVehicleMapField; private static FieldInfo arenaRaceVehiclesField; private static MethodInfo itemVehicleOverrideYawMethod; private static MethodInfo itemVehicleOverridePitchMethod; private static int lastStartBoostArenaRaceInstanceId; private void Awake() { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown try { ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); logSource = ((BaseUnityPlugin)this).Logger; BindConfig(); arenaRacePlayerVehicleMapField = AccessTools.Field(typeof(ArenaRace), "playerVehicleMap"); arenaRaceVehiclesField = AccessTools.Field(typeof(ArenaRace), "vehicles"); itemVehicleOverrideYawMethod = AccessTools.Method(typeof(ItemVehicle), "OverrideYaw", new Type[3] { typeof(Vector3), typeof(float), typeof(int) }, (Type[])null); itemVehicleOverridePitchMethod = AccessTools.Method(typeof(ItemVehicle), "OverridePitch", new Type[2] { typeof(float), typeof(float) }, (Type[])null); harmony = new Harmony("REPOJP.ArenaRaceMultiplayerSpawnFix"); harmony.PatchAll(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex)); } } private void OnDestroy() { try { if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex) { LogError("Failure: OnDestroy\n" + ex); } } private void BindConfig() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown enabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod.このMODを有効にします"); horizontalPlayersConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Layout", "HorizontalPlayers", 10, new ConfigDescription("Number of players per horizontal row.横1行に並べる人数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); verticalPlayersConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Layout", "VerticalPlayers", 2, new ConfigDescription("Number of vertical rows.縦方向の行数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); startBoostEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Start Boost", "StartBoostEnabled", true, "Apply a temporary level 3 boost after the countdown.321後に一時的なレベル3ブーストを付与します"); startBoostMultiplierConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Start Boost", "StartBoostMultiplier", 10f, new ConfigDescription("Level 3 boost power multiplier.レベル3ブーストの強さ倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); } private static bool ShouldApplyLayout() { if (enabledConfig == null || !enabledConfig.Value) { return false; } if (!SafeIsMasterClientOrSingleplayer()) { return false; } if ((Object)(object)LevelGenerator.Instance == (Object)null || SafeLevelGenerated()) { return false; } if ((Object)(object)ArenaRace.instance == (Object)null) { return false; } if (!SafeRunIsArena()) { return false; } return true; } private static List<PlayerAvatar> GetRandomizedPlayers() { List<PlayerAvatar> list = new List<PlayerAvatar>(); if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { return list; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if ((Object)(object)player != (Object)null && (Object)(object)((Component)player).gameObject != (Object)null) { list.Add(player); } } return ShufflePlayers(list); } private static LayoutPlan BuildLayoutPlan(List<PlayerAvatar> players) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) LayoutPlan layoutPlan = new LayoutPlan(); if (players == null || players.Count == 0) { return layoutPlan; } Vector3 val = GetVanillaCenter(players) + Vector3.up * 5f; Vector3 courseForward = GetCourseForward(); Vector3 val2 = Vector3.Cross(Vector3.up, courseForward); Vector3 val3 = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.right; } int num = Mathf.Clamp((horizontalPlayersConfig != null) ? horizontalPlayersConfig.Value : 10, 1, 20); int num2 = Mathf.Clamp((verticalPlayersConfig != null) ? verticalPlayersConfig.Value : 2, 1, 20); int num3 = Mathf.CeilToInt((float)players.Count / (float)Mathf.Max(1, num)); num2 = Mathf.Max(num2, num3); List<Vector3> list = new List<Vector3>(); for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { float num4 = ((float)j - ((float)num - 1f) * 0.5f) * 0.8f; float num5 = 0f - ((float)i * 3f + 10f); Vector3 item = val + val3 * num4 + courseForward * num5; list.Add(item); } } list = ShufflePositions(list); for (int k = 0; k < players.Count && k < list.Count; k++) { layoutPlan.Positions.Add(list[k]); } return layoutPlan; } private static List<Vector3> ShufflePositions(List<Vector3> positions) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(positions); Random random = new Random(Guid.NewGuid().GetHashCode() ^ Environment.TickCount ^ list.Count); for (int num = list.Count - 1; num > 0; num--) { int index = random.Next(num + 1); Vector3 value = list[num]; list[num] = list[index]; list[index] = value; } return list; } private static void ApplyLayout(List<PlayerAvatar> players, LayoutPlan plan) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(players.Count, plan.Positions.Count); for (int i = 0; i < num; i++) { PlayerAvatar val = players[i]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = plan.Positions[i]; Quaternion rotation = ((Component)val).transform.rotation; val.Spawn(val2, rotation); } } } private static Vector3 GetVanillaCenter(List<PlayerAvatar> players) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; foreach (PlayerAvatar player in players) { if (!((Object)(object)player == (Object)null)) { val += ((Component)player).transform.position; num++; } } if (num == 0) { return Vector3.zero; } return val / (float)num; } private static Vector3 GetCourseForward() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = Vector3.forward; try { if ((Object)(object)ArenaRace.instance != (Object)null && (Object)(object)ArenaRace.instance.trackSpawnOrigin != (Object)null) { forward = ArenaRace.instance.trackSpawnOrigin.forward; } } catch { } forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } return ((Vector3)(ref forward)).normalized; } private static List<PlayerAvatar> ShufflePlayers(List<PlayerAvatar> players) { List<PlayerAvatar> list = new List<PlayerAvatar>(players); Random random = new Random(Guid.NewGuid().GetHashCode() ^ Environment.TickCount); for (int num = list.Count - 1; num > 0; num--) { int index = random.Next(num + 1); PlayerAvatar value = list[num]; list[num] = list[index]; list[index] = value; } return list; } private static void ApplyStartBoostOnce(ArenaRace arenaRace) { if ((Object)(object)arenaRace == (Object)null || enabledConfig == null || !enabledConfig.Value || startBoostEnabledConfig == null || !startBoostEnabledConfig.Value || !SafeIsMasterClientOrSingleplayer() || !SafeRunIsArena()) { return; } int instanceID = ((Object)arenaRace).GetInstanceID(); if (lastStartBoostArenaRaceInstanceId == instanceID) { return; } lastStartBoostArenaRaceInstanceId = instanceID; List<ItemVehicle> arenaRaceVehicles = GetArenaRaceVehicles(arenaRace); foreach (ItemVehicle item in arenaRaceVehicles) { ApplyStartBoostToVehicle(arenaRace, item); } } private static List<ItemVehicle> GetArenaRaceVehicles(ArenaRace arenaRace) { List<ItemVehicle> list = new List<ItemVehicle>(); if ((Object)(object)arenaRace == (Object)null) { return list; } try { if (arenaRacePlayerVehicleMapField != null) { object value = arenaRacePlayerVehicleMapField.GetValue(arenaRace); if (value is Dictionary<PlayerAvatar, ItemVehicle> dictionary) { foreach (KeyValuePair<PlayerAvatar, ItemVehicle> item in dictionary) { if ((Object)(object)item.Value != (Object)null && !list.Contains(item.Value)) { list.Add(item.Value); } } } } } catch { } try { if (list.Count == 0 && arenaRaceVehiclesField != null) { object value2 = arenaRaceVehiclesField.GetValue(arenaRace); if (value2 is List<ItemVehicle> list2) { foreach (ItemVehicle item2 in list2) { if ((Object)(object)item2 != (Object)null && !list.Contains(item2)) { list.Add(item2); } } } } } catch { } return list; } private static bool ApplyStartBoostToVehicle(ArenaRace arenaRace, ItemVehicle vehicle) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)arenaRace == (Object)null || (Object)(object)vehicle == (Object)null) { return false; } if (itemVehicleOverrideYawMethod == null) { return false; } float driftBoostLevel3ForwardBoost = vehicle.driftBoostLevel3ForwardBoost; float driftBoostLevel3SpeedBoostMultiplier = vehicle.driftBoostLevel3SpeedBoostMultiplier; try { float num = ((startBoostMultiplierConfig != null) ? startBoostMultiplierConfig.Value : 10f); float num2 = Mathf.Clamp(num, 0f, 100f); vehicle.driftBoostLevel3ForwardBoost = driftBoostLevel3ForwardBoost * num2; vehicle.driftBoostLevel3SpeedBoostMultiplier = driftBoostLevel3SpeedBoostMultiplier * num2; Vector3 startBoostForward = GetStartBoostForward(arenaRace, vehicle); float num3 = Mathf.Asin(Mathf.Clamp(startBoostForward.y, -1f, 1f)) * 57.29578f; Vector3 val = startBoostForward; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = ((Component)vehicle).transform.forward; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); itemVehicleOverrideYawMethod.Invoke(vehicle, new object[3] { val, 0.25f, 3 }); if (itemVehicleOverridePitchMethod != null) { itemVehicleOverridePitchMethod.Invoke(vehicle, new object[2] { num3, 1f }); } return true; } catch (Exception ex) { LogError("Failure: ApplyStartBoostToVehicle\n" + ex); return false; } finally { vehicle.driftBoostLevel3ForwardBoost = driftBoostLevel3ForwardBoost; vehicle.driftBoostLevel3SpeedBoostMultiplier = driftBoostLevel3SpeedBoostMultiplier; } } private static Vector3 GetStartBoostForward(ArenaRace arenaRace, ItemVehicle vehicle) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)arenaRace != (Object)null && (Object)(object)arenaRace.trackSpawnOrigin != (Object)null) { return arenaRace.trackSpawnOrigin.forward; } if ((Object)(object)vehicle != (Object)null) { return ((Component)vehicle).transform.forward; } } catch { } return Vector3.forward; } private static bool SafeIsMasterClientOrSingleplayer() { try { return SemiFunc.IsMasterClientOrSingleplayer(); } catch { return false; } } private static bool SafeRunIsArena() { try { return SemiFunc.RunIsArena(); } catch { return false; } } private static bool SafeLevelGenerated() { try { return (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated; } catch { return false; } } private static void LogError(string message) { if (logSource != null) { logSource.LogError((object)message); } } } }