The BepInEx console will not appear when launching like it does for other games on Thunderstore. This is normal (and helps prevent crashes during startup). You can turn it back on in your BepInEx.cfg file.
Decompiled source of TerrainRandomiser v0.1.1
TerrainRandomiser.dll
Decompiled a day agousing System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [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: AssemblyCompany("TerrainRandomiser")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.1")] [assembly: AssemblyInformationalVersion("0.1.1+4549ad42ed23cb611c92de9a0ff2ada69eeadccb")] [assembly: AssemblyProduct("TerrainRandomiser")] [assembly: AssemblyTitle("TerrainRandomiser")] [assembly: AssemblyVersion("0.1.1.0")] 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; } } } namespace TerrainRandomiser { [BepInPlugin("com.snosz.terrainrandomiser", "TerrainRandomiser", "0.1.1")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(GUIManager), "Awake")] private static class GUIManagerAwakePatch { private static void Postfix(GUIManager __instance) { SeedPickerUI seedPickerUI = ((Component)__instance.boardingPass).gameObject.AddComponent<SeedPickerUI>(); Instance.seedPickerUI = seedPickerUI; } } [HarmonyPatch(typeof(AirportCheckInKiosk), "BeginIslandLoadRPC")] public class BeginIslandLoadPatch { private static void Postfix() { if (shouldRandomise && PhotonNetwork.IsMasterClient) { Instance.SetMasterSeed(masterSeed); } } } [HarmonyPatch(typeof(MapHandler), "Start")] private static class MapHandlerStartPatch { private static void Prefix(MapHandler __instance) { if (!shouldRandomise) { return; } Debug.LogError((object)$"[TerrainRandomiser] Starting generation with seed: {masterSeed}"); if (PhotonNetwork.IsMasterClient) { viewIDsToSend = new List<int>(); } else { viewsRequiringIDs = new List<PhotonView>(); } Random.InitState(masterSeed); for (int i = 0; i < __instance.segments.Length; i++) { GameObject segmentParent = __instance.segments[i].segmentParent; PropGrouper val = ((segmentParent != null) ? segmentParent.GetComponent<PropGrouper>() : null); if (val != null) { val.RunAll(true); } } if (PhotonNetwork.IsMasterClient) { Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; customProperties[(object)"propViews"] = viewIDsToSend.ToArray(); PhotonNetwork.CurrentRoom.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null); Debug.Log((object)$"[MapGenRandomizer] Host sent {viewIDsToSend.Count} ViewIDs to clients."); } } private static void Postfix(MapHandler __instance) { if (shouldRandomise && !PhotonNetwork.IsMasterClient) { Debug.Log((object)string.Format("[MapGenRandomizer] Required viewIDs: {0} | Received viewIDs: {1}", viewsRequiringIDs?.Count ?? (-1), (receivedViewIDs == null) ? "null" : receivedViewIDs.Count.ToString())); } } } [HarmonyPatch(typeof(PropGrouper), "RunAll")] public class PropGrouperPatch { private static void Postfix(PropGrouper __instance) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 if (!shouldRandomise) { return; } List<PropSpawner> list = new List<PropSpawner>(); List<PropSpawner_Line> list2 = new List<PropSpawner_Line>(); PropSpawner[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<PropSpawner>(); PropSpawner_Line[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<PropSpawner_Line>(); for (int i = 0; i < componentsInChildren.Length; i++) { PropGrouper componentInParent = ((Component)componentsInChildren[i]).GetComponentInParent<PropGrouper>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.timing == 1) { list.Add(componentsInChildren[i]); } } for (int j = 0; j < componentsInChildren2.Length; j++) { PropGrouper componentInParent2 = ((Component)componentsInChildren2[j]).GetComponentInParent<PropGrouper>(); if ((Object)(object)componentInParent2 != (Object)null && (int)componentInParent2.timing == 1) { list2.Add(componentsInChildren2[j]); } } foreach (PropSpawner item in list) { item.Go(); } foreach (PropSpawner_Line item2 in list2) { item2.Go(); } } } [HarmonyPatch(typeof(PropSpawner), "Spawn")] public static class PropSpawnerPatch { internal static Quaternion GetRandomRotationWithUp(Vector3 normal) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) Vector3 onUnitSphere = Random.onUnitSphere; onUnitSphere.y = 0f; onUnitSphere = Vector3.Cross(normal, Vector3.Cross(normal, onUnitSphere)); return Quaternion.LookRotation(onUnitSphere, normal); } private static bool Prefix(PropSpawner __instance, SpawnData spawnData, ref GameObject __result) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0072: Unknown result type (might be due to invalid IL or missing references) if (shouldRandomise) { GameObject val = __instance.props[Random.Range(0, __instance.props.Length)]; PhotonView val2 = default(PhotonView); if ((Object)(object)val != (Object)null && val.TryGetComponent<PhotonView>(ref val2)) { BreakableBridge val3 = default(BreakableBridge); if (val.TryGetComponent<BreakableBridge>(ref val3)) { __result = ((Component)__instance).gameObject; return false; } Quaternion randomRotationWithUp = GetRandomRotationWithUp(Vector3.up); GameObject val4 = Object.Instantiate<GameObject>(val, spawnData.pos, randomRotationWithUp, ((Component)__instance).transform); Luggage val5 = default(Luggage); if (val4.TryGetComponent<Luggage>(ref val5)) { SpineCheck component = val4.GetComponent<SpineCheck>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } for (int i = 0; i < __instance.modifiers.Count; i++) { __instance.modifiers[i].ModifyObject(val4, spawnData); } for (int j = 0; j < __instance.postConstraints.Count; j++) { if (!__instance.postConstraints[j].CheckConstraint(val4, spawnData)) { Object.DestroyImmediate((Object)(object)val4); __result = null; return false; } } if (PhotonNetwork.IsMasterClient) { int num = PhotonNetwork.AllocateViewID(true); viewIDsToSend.Add(num); PhotonView component2 = val4.GetComponent<PhotonView>(); component2.ViewID = num; } else { PhotonView component3 = val4.GetComponent<PhotonView>(); viewsRequiringIDs.Add(component3); } __result = val4; return false; } return true; } return true; } } [HarmonyPatch(typeof(PropSpawner_Line), "Spawn")] public static class PropSpawner_LinePatch { internal static Quaternion GetRandomRotationWithUp(Vector3 normal) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) Vector3 onUnitSphere = Random.onUnitSphere; onUnitSphere.y = 0f; onUnitSphere = Vector3.Cross(normal, Vector3.Cross(normal, onUnitSphere)); return Quaternion.LookRotation(onUnitSphere, normal); } private static bool Prefix(PropSpawner_Line __instance, SpawnData spawnData, ref GameObject __result) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0072: Unknown result type (might be due to invalid IL or missing references) if (shouldRandomise) { GameObject val = __instance.props[Random.Range(0, __instance.props.Length)]; PhotonView val2 = default(PhotonView); if ((Object)(object)val != (Object)null && val.TryGetComponent<PhotonView>(ref val2)) { BreakableBridge val3 = default(BreakableBridge); if (val.TryGetComponent<BreakableBridge>(ref val3)) { __result = ((Component)__instance).gameObject; return false; } Quaternion randomRotationWithUp = GetRandomRotationWithUp(Vector3.up); GameObject val4 = Object.Instantiate<GameObject>(val, spawnData.pos, randomRotationWithUp, ((Component)__instance).transform); Luggage val5 = default(Luggage); if (val4.TryGetComponent<Luggage>(ref val5)) { SpineCheck component = val4.GetComponent<SpineCheck>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } for (int i = 0; i < __instance.modifiers.Count; i++) { __instance.modifiers[i].ModifyObject(val4, spawnData); } for (int j = 0; j < __instance.postConstraints.Count; j++) { if (!__instance.postConstraints[j].CheckConstraint(val4, spawnData)) { Object.DestroyImmediate((Object)(object)val4); __result = null; return false; } } if (PhotonNetwork.IsMasterClient) { int num = PhotonNetwork.AllocateViewID(true); viewIDsToSend.Add(num); PhotonView component2 = val4.GetComponent<PhotonView>(); component2.ViewID = num; } else { PhotonView component3 = val4.GetComponent<PhotonView>(); viewsRequiringIDs.Add(component3); } __result = val4; return false; } return true; } return true; } } [HarmonyPatch(typeof(Spawner), "TrySpawnItems")] public static class SpawnerTrySpawnItemsPatch { private static void Postfix(Spawner __instance, ref List<PhotonView> __result) { PhotonView item = default(PhotonView); if (shouldRandomise && PhotonNetwork.IsMasterClient && __result.Count == 0 && ((Component)__instance).TryGetComponent<PhotonView>(ref item)) { __result.Add(item); } } } public static Plugin Instance; private static Harmony _harmony; public static int masterSeed = 1000; public static List<int> viewIDsToSend; public static List<PhotonView> viewsRequiringIDs; public static List<int> receivedViewIDs; public ConfigEntry<int> configSeed; public AssetBundle seedPickerUIBundle; public SeedPickerUI seedPickerUI; public static bool shouldRandomise = true; private void Awake() { Instance = this; byte[] seedpicker = Resource1.seedpicker; seedPickerUIBundle = AssetBundle.LoadFromMemory(seedpicker); configSeed = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Seed", 1000, "Seed to apply."); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; masterSeed = configSeed.Value; CreateCustomMapHandlerSingleton(); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.snosz.terrainrandomiser"); } private void CreateCustomMapHandlerSingleton() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)TerrainRandomiserHandler.Instance == (Object)null) { GameObject val = new GameObject("CustomMapHandler"); val.AddComponent<TerrainRandomiserHandler>(); Object.DontDestroyOnLoad((Object)(object)val); } } public void SetMasterSeed(int newSeed) { masterSeed = newSeed; configSeed.Value = masterSeed; Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; customProperties[(object)"seed"] = masterSeed; PhotonNetwork.CurrentRoom.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null); Debug.Log((object)$"[TerrainRandomiser] Seed has been set to: {masterSeed}"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } seedPickerUIBundle.Unload(false); } public void UpdateRequiredViewIDs() { if (!shouldRandomise || PhotonNetwork.IsMasterClient || viewsRequiringIDs == null || receivedViewIDs == null) { return; } if (viewsRequiringIDs.Count == receivedViewIDs.Count) { for (int i = 0; i < receivedViewIDs.Count; i++) { viewsRequiringIDs[i].ViewID = receivedViewIDs[i]; } } else { Debug.LogError((object)"[MapGenRandomizer] ID Count mismatch! Map will be out of sync!"); } } } [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resource1 { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("TerrainRandomiser.Resource1", typeof(Resource1).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] seedpicker { get { object @object = ResourceManager.GetObject("seedpicker", resourceCulture); return (byte[])@object; } } internal Resource1() { } } public class SeedPickerUI : MonoBehaviour { private GameObject seedPickerInstance; private GameObject seedPickerUIPrefab; private Button setButton; private Button randomSeedButton; private TMP_InputField seedInputField; private Toggle enableRandomiserToggle; private int inputSeed; private readonly KeyCode[] validKeys; private void Awake() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Expected O, but got Unknown if ((Object)(object)seedPickerUIPrefab == (Object)null) { seedPickerUIPrefab = Plugin.Instance.seedPickerUIBundle.LoadAsset<GameObject>("SeedPicker"); } seedPickerInstance = Object.Instantiate<GameObject>(seedPickerUIPrefab, ((Component)this).transform); seedPickerInstance.transform.localPosition = new Vector3(0f, 185f, 0f); Transform obj = seedPickerInstance.transform.Find("RandomSeedButton"); randomSeedButton = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null); Transform obj2 = seedPickerInstance.transform.Find("SeedInputField"); seedInputField = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_InputField>() : null); if ((Object)(object)seedInputField != (Object)null) { inputSeed = Plugin.Instance.configSeed.Value; seedInputField.text = Plugin.Instance.configSeed.Value.ToString(); } Transform obj3 = seedPickerInstance.transform.Find("SetSeedButton"); setButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null); Transform obj4 = seedPickerInstance.transform.Find("EnableRandomiserToggle"); enableRandomiserToggle = ((obj4 != null) ? ((Component)obj4).GetComponent<Toggle>() : null); if ((Object)(object)enableRandomiserToggle != (Object)null) { enableRandomiserToggle.isOn = Plugin.shouldRandomise; } if ((Object)(object)randomSeedButton != (Object)null) { ((UnityEvent)randomSeedButton.onClick).AddListener(new UnityAction(OnRandomSeedClicked)); } if ((Object)(object)setButton != (Object)null) { ((UnityEvent)setButton.onClick).AddListener(new UnityAction(OnSetSeedClicked)); } if ((Object)(object)enableRandomiserToggle != (Object)null) { ((UnityEvent<bool>)(object)enableRandomiserToggle.onValueChanged).AddListener((UnityAction<bool>)OnToggleChanged); } } private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 if ((Object)(object)seedInputField == (Object)null || !seedInputField.isFocused) { return; } KeyCode[] array = validKeys; for (int i = 0; i < array.Length; i++) { KeyCode val = array[i]; if (!UnityInput.Current.GetKeyDown(val)) { continue; } if ((int)val == 8) { if (seedInputField.text.Length > 0) { seedInputField.text = seedInputField.text.Substring(0, seedInputField.text.Length - 1); } if (int.TryParse(seedInputField.text, out var result)) { inputSeed = result; } } else { char c = ((object)(KeyCode)(ref val)).ToString().Last(); TMP_InputField obj = seedInputField; obj.text += c; if (int.TryParse(seedInputField.text, out var result2)) { inputSeed = result2; } } } } private void OnRandomSeedClicked() { Plugin.Instance.SetMasterSeed(Random.Range(1, 10001)); seedInputField.text = Plugin.masterSeed.ToString(); inputSeed = Plugin.masterSeed; } private void OnSetSeedClicked() { if (int.TryParse(seedInputField.text, out var _)) { if (PhotonNetwork.IsMasterClient) { Plugin.Instance.SetMasterSeed(inputSeed); } } else { Debug.LogWarning((object)"[TerrainRandomiser] Invalid seed input"); } } private void OnToggleChanged(bool value) { Debug.Log((object)$"[TerrainRandomiser] Randomiser enabled: {value}"); Plugin.shouldRandomise = value; } public SeedPickerUI() { KeyCode[] array = new KeyCode[11]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); validKeys = (KeyCode[])(object)array; ((MonoBehaviour)this)..ctor(); } } public class TerrainRandomiserHandler : MonoBehaviourPunCallbacks { public static TerrainRandomiserHandler Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Debug.Log((object)"[TerrainRandomiserHandler] Singleton initialized"); } public override void OnJoinedRoom() { Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"seed") && customProperties[(object)"seed"] is int num) { Plugin.masterSeed = num; Debug.Log((object)$"[TerrainRandomiserHandler] Initialized with seed: {num}"); } if (!PhotonNetwork.IsMasterClient && ((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"propViews") && customProperties[(object)"propViews"] is int[] source) { if (Plugin.receivedViewIDs == null) { Plugin.receivedViewIDs = new List<int>(); } Plugin.receivedViewIDs = source.ToList(); Plugin.Instance.UpdateRequiredViewIDs(); Debug.Log((object)$"[TerrainRandomiserHandler] Initialized receivedViewIDs with {Plugin.receivedViewIDs.Count} IDs"); } } public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { Debug.Log((object)"[TerrainRandomiserHandler] Room properties updated!"); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"seed") && propertiesThatChanged[(object)"seed"] is int num) { Plugin.masterSeed = num; Debug.Log((object)$"[TerrainRandomiserHandler] Updated seed to: {num}"); } if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"shouldRandomise") && propertiesThatChanged[(object)"shouldRandomise"] is bool flag) { Plugin.shouldRandomise = flag; Debug.Log((object)$"[TerrainRandomiserHandler] ShouldRandomise: {flag}"); } if (!PhotonNetwork.IsMasterClient && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"propViews") && propertiesThatChanged[(object)"propViews"] is int[] source) { if (Plugin.receivedViewIDs == null) { Plugin.receivedViewIDs = new List<int>(); } Plugin.receivedViewIDs = source.ToList(); Plugin.Instance.UpdateRequiredViewIDs(); Debug.Log((object)$"[TerrainRandomiserHandler] Updated receivedViewIDs with {Plugin.receivedViewIDs.Count} IDs"); } } } }