Decompiled source of Cubinator v1.0.2

Mods/BW_Cubinator.dll

Decompiled 5 months ago
using 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();
	}
}