Bonelab mods are targeting MelonLoader version 0.5.7. Newer versions will not work!, so double-check your MelonLoader version if you're having issues.
Decompiled source of Cubinator v1.0.2
Mods/BW_Cubinator.dll
Decompiled 5 months agousing System; using System.Collections; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BW_Cubinator; using MelonLoader; using MelonLoader.Preferences; using UnhollowerBaseLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Cubinator), "Boneworks Cubinator", "1.0.0", "Crypto_Neo", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: AssemblyTitle("BW_Cubinator")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BW_Cubinator")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3bc9308c-2706-4abe-8668-08d72992f879")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace BW_Cubinator; public class Cubinator : MelonMod { private bool Capturing; private MelonPreferences_Category cubemapSettings; private MelonPreferences_Entry<int> cfgResolution; private MelonPreferences_Entry<string> cfgOutputDir; public override void OnInitializeMelon() { if (!Directory.Exists(MelonUtils.UserDataDirectory + "\\Cubinator")) { Directory.CreateDirectory(MelonUtils.UserDataDirectory + "\\Cubinator"); } if (!File.Exists(MelonUtils.UserDataDirectory + "\\Cubinator\\Cubinator.cfg")) { File.Create(MelonUtils.UserDataDirectory + "\\Cubinator\\Cubinator.cfg"); } cubemapSettings = MelonPreferences.CreateCategory("Cubinator"); cubemapSettings.SetFilePath(MelonUtils.UserDataDirectory + "\\Cubinator\\Cubinator.cfg"); cfgResolution = MelonPreferences.CreateEntry<int>("Cubinator", "Resolution", 2048, (string)null, (string)null, false, false, (ValueValidator)null); cfgOutputDir = MelonPreferences.CreateEntry<string>("Cubinator", "OutputDirectory", MelonUtils.BaseDirectory + "\\Output", (string)null, (string)null, false, false, (ValueValidator)null); ((MelonBase)this).LoggerInstance.Msg(((MelonBase)this).Info.Name + " " + ((MelonBase)this).Info.Version + " built for Bonelab"); ((MelonBase)this).OnInitializeMelon(); } public override void OnDeinitializeMelon() { cubemapSettings.SaveToFile(true); ((MelonBase)this).OnDeinitializeMelon(); } public override void OnUpdate() { if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)112)) { MelonCoroutines.Start(CaptureCubemap()); } ((MelonBase)this).OnUpdate(); } private IEnumerator CaptureCubemap() { if (Capturing) { yield return null; } ((MelonBase)this).LoggerInstance.Msg("Capturing local environment, please wait..."); Capturing = true; if (!Directory.Exists(cfgOutputDir.Value)) { Directory.CreateDirectory(cfgOutputDir.Value); } GameObject art = GameObject.Find("[RigManager (Blank)]"); GameObject val = new GameObject(); Camera cam = val.AddComponent<Camera>(); ((Component)cam).transform.position = ((Component)Camera.main).transform.position; Quaternion rotation = ((Component)cam).transform.rotation; Quaternion rotation2 = ((Component)Camera.main).transform.rotation; ((Quaternion)(ref rotation)).SetEulerAngles(new Vector3(0f, ((Quaternion)(ref rotation2)).eulerAngles.y)); cam.farClipPlane = cam.farClipPlane; cam.nearClipPlane = cam.nearClipPlane; val.SetActive(false); art.SetActive(false); Cubemap cm = new Cubemap(cfgResolution.Value, (TextureFormat)3, false); new RenderTexture(cfgResolution.Value * 2, cfgResolution.Value, 0); yield return (object)new WaitForEndOfFrame(); cam.RenderToCubemap(cm, 63); for (int i = 0; i < 6; i++) { SaveFace(i, cm); } art.SetActive(true); Capturing = false; ((MelonBase)this).LoggerInstance.Msg("Environmental capturing complete, PNG output saved to " + cfgOutputDir.Value); } public void SaveFace(int face, Cubemap cum) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001f: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_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_00ad: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(cfgResolution.Value, cfgResolution.Value, (TextureFormat)3, false); CubemapFace val2 = (CubemapFace)3; val2 = (CubemapFace)(face switch { 0 => 4, 1 => 5, 2 => 0, 3 => 1, 4 => 2, _ => 3, }); string text = "/Bottom.png"; text = face switch { 0 => "/Front.png", 1 => "/Back.png", 2 => "/Right.png", 3 => "/Left.png", 4 => "/Top.png", _ => "/Bottom.png", }; val.SetPixels(FlipFlip(cum.GetPixels(val2, 0))); File.WriteAllBytes(cfgOutputDir.Value + text, Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val))); } public Il2CppStructArray<Color> FlipFlip(Il2CppStructArray<Color> pixels) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (pixels != null) { Il2CppStructArray<Color> val = Il2CppStructArray<Color>.op_Implicit((Color[])(object)new Color[((Il2CppArrayBase<Color>)(object)pixels).Length]); ((Il2CppArrayBase<Color>)(object)pixels).CopyTo(Il2CppArrayBase<Color>.op_Implicit((Il2CppArrayBase<Color>)(object)val), 0); for (int i = 0; i < cfgResolution.Value; i++) { for (int j = 0; j < cfgResolution.Value; j++) { int num = i * cfgResolution.Value + j; int num2 = ((Il2CppArrayBase<Color>)(object)pixels).Length - cfgResolution.Value - i * cfgResolution.Value + j; ((Il2CppArrayBase<Color>)(object)val)[num] = ((Il2CppArrayBase<Color>)(object)pixels)[num2]; } } return val; } return pixels; } } public class OpenPNG { public static void SavePNGFromRawTextureData(byte[] rawTextureData, int width, int height, string outputFilePath) { SavePNGFromByteArray(ConvertARGB32ToRGBA(rawTextureData), width, height, outputFilePath); } private static byte[] ConvertARGB32ToRGBA(byte[] argb32Data) { int num = argb32Data.Length / 4; byte[] array = new byte[argb32Data.Length]; for (int i = 0; i < num; i++) { int num2 = i * 4; int num3 = i * 4; array[num3] = argb32Data[num2 + 1]; array[num3 + 1] = argb32Data[num2 + 2]; array[num3 + 2] = argb32Data[num2 + 3]; array[num3 + 3] = argb32Data[num2]; } return array; } public static void SavePNGFromByteArray(byte[] rgbaData, int width, int height, string outputFilePath) { byte[] array = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; byte[] array2 = CreateIHDRChunk(width, height); byte[] array3 = CreateIDATChunk(rgbaData); byte[] array4 = new byte[12] { 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 }; byte[] bytes = CombineChunks(array, array2, array3, array4); File.WriteAllBytes(outputFilePath, bytes); } private static byte[] CreateIHDRChunk(int width, int height) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write((uint)width); binaryWriter.Write((uint)height); binaryWriter.Write((byte)8); binaryWriter.Write((byte)6); binaryWriter.Write((byte)0); binaryWriter.Write((byte)0); binaryWriter.Write((byte)0); byte[] array = memoryStream.ToArray(); byte[] bytes = BitConverter.GetBytes(array.Length); byte[] array2 = new byte[4] { 73, 72, 68, 82 }; return CombineChunks(bytes, array2, array); } private static byte[] CreateIDATChunk(byte[] rgbaData) { byte[] bytes = BitConverter.GetBytes(rgbaData.Length); byte[] array = new byte[4] { 73, 68, 65, 84 }; return CombineChunks(bytes, array, rgbaData); } private static byte[] CombineChunks(params byte[][] chunks) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); foreach (byte[] buffer in chunks) { binaryWriter.Write(buffer); } return memoryStream.ToArray(); } }