Decompiled source of MushroomSeedFixed v1.2.0

MushroomSeedFix.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AIGraph;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using Enemies;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using SNetwork;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MushroomSeedFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MushroomSeedFix")]
[assembly: AssemblyTitle("MushroomSeedFix")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 MushroomSeedFix
{
	internal static class ConfigBindings
	{
		private static ConfigEntry<int>? sessionSeed;

		private static ConfigEntry<int>? enemySeed;

		private static ConfigEntry<int>? enemyRotationSeed;

		private static ConfigEntry<int>? scoutPathSeed;

		private static ConfigEntry<int>? placementSeed;

		public static int SessionSeed => sessionSeed?.Value ?? 0;

		public static int EnemySeed => enemySeed?.Value ?? 0;

		public static int EnemyRotationSeed => enemyRotationSeed?.Value ?? 0;

		public static int ScoutPathSeed => scoutPathSeed?.Value ?? 0;

		public static int PlacementSeed => placementSeed?.Value ?? 0;

		public static void Init(ConfigFile file)
		{
			sessionSeed = file.Bind<int>("Setup", "SessionSeed", 0, "Session seed. Not used if <= 0");
			enemySeed = file.Bind<int>("Setup", "EnemySeed", 0, "Custom fixed seed to use for generating the random seeds for individual enemies which is used for SizeMultiplier. Not used if <= 0");
			enemyRotationSeed = file.Bind<int>("Setup", "EnemyRotationSeed", 0, "Custom fixed seed to use for rotating placed enemies. Not used if <= 0");
			scoutPathSeed = file.Bind<int>("Setup", "ScoutPathSeed", 0, "Custom fixed seed to use for generating random scout pathing. Not used if <= 0");
			placementSeed = file.Bind<int>("Setup", "PlacementSeed", 0, "Custom fixed seed to use for generating the random placements. Not used if <= 0");
		}
	}
	[BepInPlugin("Mushroom.Seed", "MushroomSeed", "1.2.0")]
	internal sealed class EntryPoint : BasePlugin
	{
		private Harmony? harmony;

		public override void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			harmony = new Harmony("Mushroom.Seed");
			harmony.PatchAll();
			ConfigBindings.Init(((BasePlugin)this).Config);
		}

		public override bool Unload()
		{
			return ((BasePlugin)this).Unload();
		}
	}
	public static class FixedSeedManager
	{
		private static Random? enemyRandom;

		private static Random? enemyRotationRandom;

		private static Random? scoutPathRandom;

		private static Random? placementRandom;

		internal static void Initialize()
		{
			int enemySeed = ConfigBindings.EnemySeed;
			if (enemySeed > 0)
			{
				enemyRandom = new Random(enemySeed);
			}
			else
			{
				enemyRandom = null;
			}
			int enemyRotationSeed = ConfigBindings.EnemyRotationSeed;
			if (enemyRotationSeed > 0)
			{
				enemyRotationRandom = new Random(enemyRotationSeed);
			}
			else
			{
				enemyRotationRandom = null;
			}
			int scoutPathSeed = ConfigBindings.ScoutPathSeed;
			if (scoutPathSeed > 0)
			{
				scoutPathRandom = new Random(scoutPathSeed);
			}
			else
			{
				scoutPathRandom = null;
			}
			int placementSeed = ConfigBindings.PlacementSeed;
			if (placementSeed > 0)
			{
				placementRandom = new Random(placementSeed);
			}
			else
			{
				placementRandom = null;
			}
		}

		public static Vector3 GetRandomScoutPathPosition(AIG_NodeCluster nodeCluster)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (scoutPathRandom == null)
			{
				Debug.Log(Object.op_Implicit("No RandomScoutPathRandom"));
				return nodeCluster.m_nodes[Random.Range(0, nodeCluster.m_nodes.Count)].Position;
			}
			return nodeCluster.m_nodes[scoutPathRandom.Next(0, nodeCluster.m_nodes.Count)].Position;
		}

		public static Vector2 GetRandomEnemyRotation()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (enemyRotationRandom == null)
			{
				Debug.Log(Object.op_Implicit("No EnemyRotationRandom"));
				return Random.insideUnitCircle;
			}
			(double Sin, double Cos) tuple = Math.SinCos((double)enemyRotationRandom.NextInt64(0L, long.MaxValue) / 9.223372036854776E+18 * Math.PI * 2.0);
			var (num, _) = tuple;
			return new Vector2((float)tuple.Cos, (float)num);
		}

		public static ushort GetRandomEnemySeed()
		{
			if (enemyRandom == null)
			{
				Debug.Log(Object.op_Implicit("No EnemyRandom"));
				return (ushort)Random.Range(0, 65535);
			}
			return (ushort)enemyRandom.Next(0, 65535);
		}

		public static float GetRandomPlacementHeat()
		{
			if (placementRandom == null)
			{
				Debug.Log(Object.op_Implicit("No PlacementRandom"));
				return Random.value;
			}
			return (float)placementRandom.Next(0, int.MaxValue) / 2.1474836E+09f;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Mushroom.Seed";

		public const string PLUGIN_NAME = "MushroomSeed";

		public const string PLUGIN_VERSION = "1.2.0";

		public const string AUTHOR = "time1pm & flaff";

		public const string BRANCH = "beta";

		public const string INTERNAL_VERSION = "000011";
	}
}
namespace MushroomSeedFix.Patches
{
	[HarmonyPatch]
	internal static class EnemyGroup_RandomRotationPatch
	{
		[HarmonyPatch(typeof(EnemyGroup), "GetRandomRotation")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool Patch(ref Quaternion __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			EnemyGroup.s_randomRot2D = FixedSeedManager.GetRandomEnemyRotation();
			__result = Quaternion.LookRotation(new Vector3(EnemyGroup.s_randomRot2D.x, 0f, EnemyGroup.s_randomRot2D.y), Vector3.up);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class InLobbyPatch
	{
		[HarmonyPatch(typeof(GS_Lobby), "Enter")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static void EnterLobby()
		{
			FixedSeedManager.Initialize();
		}
	}
	[HarmonyPatch]
	internal static class Scorer_ValidNodePatch
	{
		[HarmonyPatch(typeof(AIG_NodeCluster), "Scorer_ValidNode")]
		[HarmonyPrefix]
		public static bool Patch(AIG_NodeCluster __instance, AIG_INode node, ref float __result)
		{
			if (node.HasSpecialTraversal || node.BelongsToGate)
			{
				__instance.m_nodesToSpreadFrom.Enqueue(node);
				__result = -10f;
				return false;
			}
			if (!node.IsVoxelNode)
			{
				__result = -10f;
				return false;
			}
			int count = node.Links.Count;
			float num = 1f - Mathf.Clamp01((float)count / 3f);
			float randomPlacementHeat = FixedSeedManager.GetRandomPlacementHeat();
			node.PlacementHeat = num + randomPlacementHeat;
			__result = node.PlacementHeat;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class ScoutPatrolPathPatch
	{
		private static bool patch;

		[HarmonyPatch(typeof(EnemyGroup), "GetScoutPath")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static void PrefixScoutPath()
		{
			patch = true;
		}

		[HarmonyPatch(typeof(EnemyGroup), "GetScoutPath")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		public static void PostfixScoutPath()
		{
			patch = false;
		}

		[HarmonyPatch(typeof(AIG_NodeCluster), "GetRandomPosition")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool GetRandomPosition(AIG_NodeCluster __instance, ref Vector3 __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (patch)
			{
				__result = FixedSeedManager.GetRandomScoutPathPosition(__instance);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class SerialGeneratorPatch
	{
		[HarmonyPatch(typeof(SerialGenerator), "Generate")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool Generate()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			SeedRandom val = new SeedRandom("SerialGeneratorSeed")
			{
				Seed = RundownManager.ActiveExpedition.SessionSeed
			};
			Debug.Log(Object.op_Implicit(Deb.LG("SerialGenerator GENERATE! SessionRandom.seed: " + val.Seed, 0f)));
			SerialGenerator.m_serialStep = 0;
			SerialGenerator.m_codeWordStep = 0;
			SerialGenerator.m_ipStep = 0;
			for (int i = 0; i < SerialGenerator.m_maxCount; i++)
			{
				((Il2CppArrayBase<int>)(object)SerialGenerator.m_serials)[i] = 100 + i;
			}
			int length = ((Il2CppArrayBase<string>)(object)SerialGenerator.m_codeWords).Length;
			SerialGenerator.m_codeWordIndex = Il2CppStructArray<int>.op_Implicit(new int[length]);
			for (int j = 0; j < length; j++)
			{
				((Il2CppArrayBase<int>)(object)SerialGenerator.m_codeWordIndex)[j] = j;
			}
			int length2 = ((Il2CppArrayBase<string>)(object)SerialGenerator.m_codeWordPrefixes).Length;
			SerialGenerator.m_codeWordPrefixIndex = Il2CppStructArray<int>.op_Implicit(new int[length2]);
			for (int k = 0; k < length2; k++)
			{
				((Il2CppArrayBase<int>)(object)SerialGenerator.m_codeWordPrefixIndex)[k] = k;
			}
			SerialGenerator.m_ips = Il2CppStringArray.op_Implicit(new string[99]);
			for (int l = 0; l < ((Il2CppArrayBase<string>)(object)SerialGenerator.m_ips).Length; l++)
			{
				int num = val.Range(100, 255, "NO_TAG");
				int num2 = val.Range(50, 255, "NO_TAG");
				int num3 = val.Range(0, 255, "NO_TAG");
				int num4 = val.Range(0, 255, "NO_TAG");
				((Il2CppArrayBase<string>)(object)SerialGenerator.m_ips)[l] = num + "." + num2 + "." + num3 + "." + num4;
			}
			val.ShuffleArray<int>((Il2CppArrayBase<int>)(object)SerialGenerator.m_serials);
			val.ShuffleArray<int>((Il2CppArrayBase<int>)(object)SerialGenerator.m_codeWordIndex);
			val.ShuffleArray<int>((Il2CppArrayBase<int>)(object)SerialGenerator.m_codeWordPrefixIndex);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class SessionSeedPatch
	{
		[HarmonyPatch(typeof(Builder), "SetSessionIDSeed")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static void SetSessionSeed(ref int forcedSeed)
		{
			forcedSeed = ConfigBindings.SessionSeed;
		}
	}
	[HarmonyPatch]
	internal static class SpawnEnemyPatch
	{
		[HarmonyPatch(typeof(EnemyAllocator), "SpawnEnemy")]
		[HarmonyPrefix]
		[HarmonyWrapSafe]
		public static bool SpawnEnemy(EnemyAllocator __instance, uint persistantID, AIG_CourseNode courseNode, AgentMode mode, Vector3 position, Quaternion rotation, EnemyGroup? group, int placementIndex, ref EnemyAgent? __result)
		{
			//IL_0002: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			pEnemySpawnData val = default(pEnemySpawnData);
			val.HealthRel = 1f;
			val.AttachedGlueRel = 0f;
			val.placementIndex = placementIndex;
			GameObject val2;
			if (!__instance.m_enemyTypeLookup.ContainsKey(persistantID) || (Object)(object)(val2 = __instance.m_enemyTypeLookup[persistantID]) == (Object)null)
			{
				Debug.LogError(Object.op_Implicit("No prefabs with ID " + persistantID));
				__result = null;
				return false;
			}
			((pEnemySpawnData)(ref val)).Position = position;
			((pEnemySpawnData)(ref val)).Rotation = rotation;
			((pCourseNode)(ref val.courseNode)).Set(courseNode);
			val.mode = mode;
			val.seed = FixedSeedManager.GetRandomEnemySeed();
			if ((Object)(object)group != (Object)null)
			{
				val.groupReplicatorKey = group.Replicator.Key;
			}
			else
			{
				val.groupReplicatorKey = 0;
			}
			((SNet_ReplicationManager<pEnemySpawnData, EnemyReplicator>)(object)__instance.m_enemyReplicationManager).Spawn(val2, val);
			__result = __instance.m_spawnedEnemyAgent;
			return false;
		}
	}
}