Decompiled source of FashionableStructures v0.1.0

Mods/FashionableStructures.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.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using AssetBundleLoader;
using FashionableStructures;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppRUMBLE.MoveSystem;
using Il2CppSystem.Collections;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UniverseLib.Runtime.Il2Cpp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(main), "FashionableStructures", "0.1.0", "Tamrell", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCopyright("Copyright © AlienWare 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15220484-bea8-4b8e-ac8c-41ff723ec2f0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("FashionableStructures")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FashionableStructures")]
[assembly: AssemblyTitle("FashionableStructures")]
[assembly: AssemblyVersion("1.0.0.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 FashionableStructures
{
	public class main : MelonMod
	{
		[HarmonyPatch(typeof(Structure), "OnFetchFromPool")]
		public static class StructureRespawn
		{
			private static void Postfix(ref Structure __instance)
			{
				if (Instance.configs == null)
				{
					MelonLogger.Error("No configuration loaded, cannot load asset bundles.");
					return;
				}
				GameObject gameObject = ((Component)__instance.processableComponent).gameObject;
				switch (((Object)gameObject).name)
				{
				case "LargeRock":
					Instance.AttachAccessoriesToStructure(Instance.configs.LargeRock, gameObject, "LargeRock");
					break;
				case "Pillar":
					Instance.AttachAccessoriesToStructure(Instance.configs.Pillar, ((Component)gameObject.transform.FindChild("Pillar")).gameObject, "Pillar");
					break;
				case "Disc":
					Instance.AttachAccessoriesToStructure(Instance.configs.Disk, ((Component)gameObject.transform.FindChild("Structure_Disc")).gameObject, "Disc");
					break;
				case "Wall":
					Instance.AttachAccessoriesToStructure(Instance.configs.Wall, ((Component)gameObject.transform.FindChild("Wall")).gameObject, "Wall");
					break;
				case "RockCube":
					Instance.AttachAccessoriesToStructure(Instance.configs.Cube, ((Component)gameObject.transform.FindChild("RockCube")).gameObject, "Cube");
					break;
				case "Ball":
					Instance.AttachAccessoriesToStructure(Instance.configs.Ball, ((Component)gameObject.transform.FindChild("Ball")).gameObject, "Ball");
					break;
				}
			}
		}

		public class Structure
		{
			[JsonPropertyName("assetBundle")]
			public string AssetBundle { get; set; }

			[JsonPropertyName("assetName")]
			public string AssetName { get; set; }

			[JsonPropertyName("placementOptions")]
			public List<PlacementOption> PlacementOptions { get; set; }

			[JsonPropertyName("probability")]
			public float Probability { get; set; }
		}

		public class PlacementOption
		{
			[JsonPropertyName("position")]
			public List<float> Position { get; set; }

			[JsonPropertyName("rotation")]
			public List<float> Rotation { get; set; }

			[JsonPropertyName("scale")]
			public List<float> Scale { get; set; }
		}

		public class Config
		{
			[JsonPropertyName("Disk")]
			public List<List<Structure>> Disk { get; set; }

			[JsonPropertyName("Pillar")]
			public List<List<Structure>> Pillar { get; set; }

			[JsonPropertyName("Ball")]
			public List<List<Structure>> Ball { get; set; }

			[JsonPropertyName("Cube")]
			public List<List<Structure>> Cube { get; set; }

			[JsonPropertyName("Wall")]
			public List<List<Structure>> Wall { get; set; }

			[JsonPropertyName("LargeRock")]
			public List<List<Structure>> LargeRock { get; set; }
		}

		private Config? configs;

		private Dictionary<string, AssetBundle> assetBundles = new Dictionary<string, AssetBundle>();

		public static main Instance { get; private set; }

		public override void OnApplicationStart()
		{
			((MelonBase)this).OnApplicationStart();
			Instance = this;
			loadConfigs();
			LoadAllAssetBundles();
		}

		private void AttachAccessoriesToStructure(List<List<Structure>> accessoryBundles, GameObject struc, string structureName)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			IEnumerator enumerator = struc.transform.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Transform val = (Transform)enumerator.Current;
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			finally
			{
				if (enumerator is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}
			List<Structure> list = accessoryBundles[Random.Range(0, accessoryBundles.Count)];
			foreach (Structure item in list)
			{
				if (assetBundles.TryGetValue(item.AssetBundle, out AssetBundle value))
				{
					if (!(item.Probability < Random.value))
					{
						GameObject val2 = Object.Instantiate<GameObject>(value.LoadAsset<GameObject>(item.AssetName), struc.transform);
						((Object)val2).name = item.AssetName;
						if ((Object)(object)val2 == (Object)null)
						{
							MelonLogger.Error("Failed to load asset '" + item.AssetName + "'.");
							continue;
						}
						PlacementOption placementOption = item.PlacementOptions[Random.Range(0, item.PlacementOptions.Count)];
						val2.transform.localPosition = new Vector3(placementOption.Position[0], placementOption.Position[1], placementOption.Position[2]);
						val2.transform.localRotation = new Quaternion(placementOption.Rotation[0], placementOption.Rotation[1], placementOption.Rotation[2], placementOption.Rotation[3]);
						val2.transform.localScale = new Vector3(placementOption.Scale[0], placementOption.Scale[1], placementOption.Scale[2]);
						MelonLogger.Msg($"Asset '{item.AssetName}' attached to {structureName}.");
					}
				}
				else
				{
					MelonLogger.Error("Asset bundle '" + item.AssetBundle + "' not loaded.");
				}
			}
		}

		private void loadConfigs()
		{
			try
			{
				string json = File.ReadAllText("UserData\\FashionableStructures\\config.json");
				configs = JsonSerializer.Deserialize<Config>(json);
				if (configs == null)
				{
					MelonLogger.Msg("Config file is corrupted or empty");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Msg("An error occurred: " + ex.Message);
			}
		}

		private void LoadAllAssetBundles()
		{
			if (configs == null)
			{
				MelonLogger.Error("No configuration loaded, cannot load asset bundles.");
				return;
			}
			List<List<Structure>>[] array = new List<List<Structure>>[6] { configs.Disk, configs.Pillar, configs.Ball, configs.Cube, configs.Wall, configs.LargeRock };
			foreach (List<List<Structure>> list in array)
			{
				foreach (List<Structure> item in list)
				{
					foreach (Structure item2 in item)
					{
						if (!assetBundles.ContainsKey(item2.AssetBundle))
						{
							string text = Path.Combine("UserData", "FashionableStructures", "FashionableAssets", item2.AssetBundle);
							AssetBundle assetBundle = AssetBundle.LoadFromFile(text);
							if ((Object)(object)assetBundle == (Object)null)
							{
								MelonLogger.Msg("Could not load asset bundle from: " + text);
								continue;
							}
							assetBundles[item2.AssetBundle] = assetBundle;
							MelonLogger.Msg("Asset bundle loaded successfully from: " + text);
						}
					}
				}
			}
		}
	}
}
namespace UniverseLib.Runtime.Il2Cpp
{
	public static class ICallManager
	{
		private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();

		private static readonly Dictionary<string, Delegate> unreliableCache = new Dictionary<string, Delegate>();

		public static T GetICall<T>(string signature) where T : Delegate
		{
			if (iCallCache.ContainsKey(signature))
			{
				return (T)iCallCache[signature];
			}
			IntPtr intPtr = IL2CPP.il2cpp_resolve_icall(signature);
			if (intPtr == IntPtr.Zero)
			{
				throw new MissingMethodException("Could not find any iCall with the signature '" + signature + "'!");
			}
			Delegate delegateForFunctionPointer = Marshal.GetDelegateForFunctionPointer(intPtr, typeof(T));
			iCallCache.Add(signature, delegateForFunctionPointer);
			return (T)delegateForFunctionPointer;
		}

		public static T GetICallUnreliable<T>(params string[] possibleSignatures) where T : Delegate
		{
			string text = possibleSignatures.First();
			if (unreliableCache.ContainsKey(text))
			{
				return (T)unreliableCache[text];
			}
			foreach (string text2 in possibleSignatures)
			{
				IntPtr intPtr = IL2CPP.il2cpp_resolve_icall(text2);
				if (intPtr != IntPtr.Zero)
				{
					T val = (T)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(T));
					unreliableCache.Add(text, val);
					return val;
				}
			}
			throw new MissingMethodException("Could not find any iCall from list of provided signatures starting with '" + text + "'!");
		}
	}
}
namespace AssetBundleLoader
{
	public class AssetBundle : Object
	{
		internal delegate IntPtr d_LoadFromFile(IntPtr path, uint crc, ulong offset);

		private delegate IntPtr d_LoadFromMemory(IntPtr binary, uint crc);

		public delegate IntPtr d_GetAllLoadedAssetBundles_Native();

		internal delegate IntPtr d_LoadAssetWithSubAssets_Internal(IntPtr _this, IntPtr name, IntPtr type);

		internal delegate IntPtr d_LoadAsset_Internal(IntPtr _this, IntPtr name, IntPtr type);

		internal delegate void d_Unload(IntPtr _this, bool unloadAllLoadedObjects);

		public readonly IntPtr m_bundlePtr = IntPtr.Zero;

		static AssetBundle()
		{
			ClassInjector.RegisterTypeInIl2Cpp<AssetBundle>();
		}

		[HideFromIl2Cpp]
		public static AssetBundle LoadFromFile(string path)
		{
			MelonLogger.Msg(Directory.GetCurrentDirectory());
			IntPtr intPtr = ICallManager.GetICallUnreliable<d_LoadFromFile>(new string[2] { "UnityEngine.AssetBundle::LoadFromFile_Internal", "UnityEngine.AssetBundle::LoadFromFile" })(IL2CPP.ManagedStringToIl2Cpp(path), 0u, 0uL);
			MelonLogger.Msg((object)(nint)intPtr);
			return (intPtr != IntPtr.Zero) ? new AssetBundle(intPtr) : null;
		}

		[HideFromIl2Cpp]
		public static AssetBundle LoadFromMemory(byte[] binary, uint crc = 0u)
		{
			IntPtr intPtr = ICallManager.GetICallUnreliable<d_LoadFromMemory>(new string[2] { "UnityEngine.AssetBundle::LoadFromMemory_Internal", "UnityEngine.AssetBundle::LoadFromMemory" })(((Il2CppObjectBase)Il2CppStructArray<byte>.op_Implicit(binary)).Pointer, crc);
			return (intPtr != IntPtr.Zero) ? new AssetBundle(intPtr) : null;
		}

		[HideFromIl2Cpp]
		public static AssetBundle[] GetAllLoadedAssetBundles()
		{
			IntPtr intPtr = ICallManager.GetICall<d_GetAllLoadedAssetBundles_Native>("UnityEngine.AssetBundle::GetAllLoadedAssetBundles_Native")();
			return (intPtr != IntPtr.Zero) ? Il2CppArrayBase<AssetBundle>.op_Implicit((Il2CppArrayBase<AssetBundle>)(object)new Il2CppReferenceArray<AssetBundle>(intPtr)) : null;
		}

		public AssetBundle(IntPtr ptr)
			: base(ptr)
		{
			m_bundlePtr = ptr;
		}

		[HideFromIl2Cpp]
		public Object[] LoadAllAssets()
		{
			IntPtr intPtr = ICallManager.GetICall<d_LoadAssetWithSubAssets_Internal>("UnityEngine.AssetBundle::LoadAssetWithSubAssets_Internal")(m_bundlePtr, IL2CPP.ManagedStringToIl2Cpp(""), ((Il2CppObjectBase)Il2CppType.Of<Object>()).Pointer);
			return (Object[])((intPtr != IntPtr.Zero) ? ((Array)Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)new Il2CppReferenceArray<Object>(intPtr))) : ((Array)new Object[0]));
		}

		[HideFromIl2Cpp]
		public T LoadAsset<T>(string name) where T : Object
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			IntPtr intPtr = ICallManager.GetICall<d_LoadAsset_Internal>("UnityEngine.AssetBundle::LoadAsset_Internal")(m_bundlePtr, IL2CPP.ManagedStringToIl2Cpp(name), ((Il2CppObjectBase)Il2CppType.Of<T>()).Pointer);
			return (intPtr != IntPtr.Zero) ? ((Il2CppObjectBase)new Object(intPtr)).TryCast<T>() : default(T);
		}

		[HideFromIl2Cpp]
		public void Unload(bool unloadAllLoadedObjects)
		{
			ICallManager.GetICall<d_Unload>("UnityEngine.AssetBundle::Unload")(m_bundlePtr, unloadAllLoadedObjects);
		}
	}
}