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();
}
}