Decompiled source of RumblePhotoAlbum v1.1.1

Mods/RumblePhotoAlbum.dll

Decompiled a day ago
using System;
using System.Collections;
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 HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppRUMBLE.Interactions.InteractionBase;
using Il2CppRUMBLE.Players;
using Il2CppRUMBLE.Recording.LCK;
using Il2CppRUMBLE.Serialization;
using Il2CppRUMBLE.Tutorial.MoveLearning;
using Il2CppRUMBLE.Utilities;
using Il2CppTMPro;
using MelonLoader;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RumbleModUI;
using RumbleModdingAPI;
using RumblePhotoAlbum;
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: MelonInfo(typeof(MainClass), "RumblePhotoAlbum", "1.1.1", "Kalamart", null)]
[assembly: VerifyLoaderVersion(0, 6, 5, true)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 255, 31, 90)]
[assembly: MelonAuthorColor(255, 255, 31, 90)]
[assembly: AssemblyDescription("Decorate your environment with framed pictures")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("621d30a5-8fa1-4d87-9826-92c0149b033e")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("RumblePhotoAlbum")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d3d788d03562a8357f133dd892794e9ba4cb054a")]
[assembly: AssemblyProduct("RumblePhotoAlbum")]
[assembly: AssemblyTitle("RumblePhotoAlbum")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RumblePhotoAlbum;

public class PictureData : MainClass.PictureDataInternal
{
	public void delete()
	{
		PhotoAPI.DeletePicture(this);
	}
}
public class PhotoAPI : MainClass
{
	public static PictureData CreatePicture(string path, Vector3 position, Vector3 rotation, float width = 0f, float height = 0f, float? padding = null, float? thickness = null, Color? color = null, bool? alpha = null)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		PictureData pictureData = new PictureData
		{
			path = path,
			position = position,
			rotation = rotation,
			width = width,
			height = width,
			padding = (padding ?? MainClass.defaultPadding),
			thickness = (thickness ?? MainClass.defaultThickness),
			color = (Color)(((??)color) ?? MainClass.defaultColor),
			alpha = (alpha ?? MainClass.enableAlpha)
		};
		MainClass.CreatePictureBlock(ref pictureData, MainClass.photoAlbum.transform);
		return pictureData;
	}

	public static void DeletePicture(PictureData pictureData)
	{
		MainClass.deletePicture(pictureData, keepFile: true);
	}
}
public class MainClass : MelonMod
{
	[HarmonyPatch(typeof(PlayerController), "Initialize", new Type[] { typeof(Player) })]
	private static class PlayerSpawnPatch
	{
		private static void Postfix(ref PlayerController __instance, ref Player player)
		{
			if (Players.GetLocalPlayer() == player)
			{
				InitGrabbing();
				initializeRockCam();
			}
		}
	}

	[HarmonyPatch(typeof(LCKTabletUtility), "TakePhoto", new Type[] { })]
	private static class PhotoTakenPatch
	{
		private static bool Prefix(ref LCKTabletUtility __instance)
		{
			PhotoPrintingIndex = 0;
			return true;
		}
	}

	public class PictureDataInternal
	{
		public string path;

		public Vector3 position;

		public Vector3 rotation;

		public float width = 0f;

		public float height = 0f;

		public float padding = defaultPadding;

		public float thickness = defaultThickness;

		public Color color = defaultColor;

		public bool alpha = false;

		public bool visible = true;

		public GameObject obj = null;

		public JToken jsonConfig = null;
	}

	[CompilerGenerated]
	private sealed class <LoadAlbum>d__7 : IEnumerator<WaitForSeconds>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private WaitForSeconds <>2__current;

		public string sceneName;

		private JArray <album>5__1;

		private JToken <sceneObj>5__2;

		private JArray <cleanedAlbum>5__3;

		private string <json>5__4;

		private Exception <ex>5__5;

		private IEnumerator<JToken> <>s__6;

		private JToken <entry>5__7;

		private PictureData <pictureData>5__8;

		private Exception <ex>5__9;

		private Exception <ex>5__10;

		WaitForSeconds IEnumerator<WaitForSeconds>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <LoadAlbum>d__7(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<album>5__1 = null;
			<sceneObj>5__2 = null;
			<cleanedAlbum>5__3 = null;
			<json>5__4 = null;
			<ex>5__5 = null;
			<>s__6 = null;
			<entry>5__7 = null;
			<pictureData>5__8 = null;
			<ex>5__9 = null;
			<ex>5__10 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Expected O, but got Unknown
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Invalid comparison between Unknown and I4
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Log("Reading from disk");
					PicturesList = new List<PictureData>();
					<album>5__1 = null;
					<sceneObj>5__2 = null;
					try
					{
						if (!File.Exists(fullPath))
						{
							LogWarn("Creating new configuration file at: " + fullPath + ".");
							root = new JObject();
						}
						else
						{
							<json>5__4 = File.ReadAllText(fullPath);
							root = JObject.Parse(<json>5__4);
							<json>5__4 = null;
						}
						if (!root.TryGetValue(sceneName, ref <sceneObj>5__2) || (int)<sceneObj>5__2.Type != 1)
						{
							LogWarn("No valid entry found for scene \"" + sceneName + "\". Creating an empty object.");
							<sceneObj>5__2 = (JToken)new JObject();
							root[sceneName] = <sceneObj>5__2;
						}
						ref JArray reference = ref <album>5__1;
						JToken obj = <sceneObj>5__2[(object)"album"];
						reference = (JArray)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()));
						photoAlbum = new GameObject();
						((Object)photoAlbum).name = "PhotoAlbum";
					}
					catch (Exception ex)
					{
						<ex>5__5 = ex;
						LogError("Failed to load or parse config.json: " + <ex>5__5.Message);
					}
					if (<album>5__1 == null || <sceneObj>5__2 == null)
					{
						return false;
					}
					<cleanedAlbum>5__3 = new JArray();
					<>s__6 = <album>5__1.GetEnumerator();
					<>1__state = -3;
					break;
				case 1:
					<>1__state = -3;
					<entry>5__7 = null;
					break;
				}
				while (<>s__6.MoveNext())
				{
					<entry>5__7 = <>s__6.Current;
					try
					{
						<pictureData>5__8 = ParsePictureData(<entry>5__7);
						Log("Creating picture " + <pictureData>5__8.path);
						if (<pictureData>5__8 == null)
						{
							continue;
						}
						CreatePictureBlock(ref <pictureData>5__8, photoAlbum.transform);
						if ((Object)(object)<pictureData>5__8.obj != (Object)null)
						{
							<cleanedAlbum>5__3.Add(<entry>5__7);
							<pictureData>5__8.jsonConfig = <cleanedAlbum>5__3[((JContainer)<cleanedAlbum>5__3).Count - 1];
						}
						else
						{
							LogWarn("Removed missing file: " + <pictureData>5__8.path);
						}
						<pictureData>5__8 = null;
						goto IL_02db;
					}
					catch (Exception ex)
					{
						<ex>5__9 = ex;
						LogError("Failed to parse entry: " + <ex>5__9.Message);
					}
					continue;
					IL_02db:
					<>2__current = new WaitForSeconds(0.02f);
					<>1__state = 1;
					return true;
				}
				<>m__Finally1();
				<>s__6 = null;
				try
				{
					reloadStash();
					<sceneObj>5__2[(object)"album"] = (JToken)(object)<cleanedAlbum>5__3;
					File.WriteAllText(fullPath, ((JToken)root).ToString((Formatting)1));
					stashJson = (JArray)root[currentScene][(object)"stash"];
					albumJson = (JArray)root[currentScene][(object)"album"];
				}
				catch (Exception ex)
				{
					<ex>5__10 = ex;
					LogError("Failed to update configuration file: " + <ex>5__10.Message);
				}
				return false;
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		private void <>m__Finally1()
		{
			<>1__state = -1;
			if (<>s__6 != null)
			{
				<>s__6.Dispose();
			}
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <RunMailTubeAnimation>d__76 : IEnumerator<WaitForSeconds>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private WaitForSeconds <>2__current;

		private PictureData <pictureData>5__1;

		WaitForSeconds IEnumerator<WaitForSeconds>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <RunMailTubeAnimation>d__76(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<pictureData>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<pictureData>5__1 = new PictureData();
				<pictureData>5__1.path = ((object)stashJson[0]).ToString();
				stashJson.RemoveAt(0);
				<pictureData>5__1.padding = defaultPadding;
				<pictureData>5__1.thickness = defaultThickness;
				<pictureData>5__1.color = defaultColor;
				<pictureData>5__1.rotation = new Vector3(0f, 180f, 0f);
				mailTubePicture = new PictureData();
				mailTubePicture.jsonConfig = (JToken)new JObject();
				mailTubePicture.jsonConfig[(object)"path"] = JToken.op_Implicit(<pictureData>5__1.path);
				mailTubePicture = <pictureData>5__1;
				CreatePictureBlock(ref mailTubePicture, mailTubeHandle.transform);
				animationRunning = true;
				mailTube.ExecuteMailTubeAnimation();
				SetPreviewSlabVisibility(visible: false);
				<>2__current = new WaitForSeconds(7f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (mailTubePicture != null)
				{
					mailTubePicture.obj.transform.SetParent(photoAlbum.transform, true);
					mailTubePicture.obj.transform.localScale = Vector3.one;
				}
				<>2__current = new WaitForSeconds(2f);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				SetPreviewSlabVisibility(visible: true);
				animationRunning = false;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private const string UserDataPath = "UserData/RumblePhotoAlbum";

	private const string picturesFolder = "pictures";

	private const string configFile = "config.json";

	private const float imageOffset = 0.001f;

	private static JObject root = null;

	private static string fullPath = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "config.json");

	private Mod Mod = new Mod();

	private static bool[] grip = new bool[2];

	private static bool[] holding = new bool[2];

	private static GameObject[] hand = (GameObject[])(object)new GameObject[2];

	private static PictureData currentlyModified = null;

	private static GameObject resizingHandle = null;

	private const float hold_distance = 0.05f;

	private static GameObject AlbumInteractionItems = null;

	private static GameObject friendButton = null;

	private static GameObject gearMarketButton = null;

	private static GameObject mailTubeObj = null;

	private static GameObject rockCamButton = null;

	private static Transform rockCamTf = null;

	private static GameObject rockCamHandle = null;

	private static PictureData rockCamPicture = null;

	private static bool rockCamInitialized = false;

	private static int PhotoPrintingIndex = 0;

	private static MailTube mailTube = null;

	private static GameObject mailTubeHandle = null;

	private static PictureData mailTubePicture = null;

	private static Transform purchaseSlab = null;

	private static bool animationRunning = false;

	private static JArray stashJson;

	private static JArray albumJson;

	private const float mailTubeScale = 0.505f;

	private const float maxPictureSize = 5f;

	protected static float defaultSize = 0.5f;

	protected static float defaultThickness = 0.01f;

	protected static float defaultPadding = 0.01f;

	protected static Color defaultColor = new Color(0.48f, 0.8f, 0.76f);

	protected static bool enableAlpha = false;

	protected static bool visibility = true;

	protected static bool buttonsVisibility = true;

	protected static GameObject photoAlbum = null;

	protected static string currentScene = "";

	private static List<PictureData> PicturesList = null;

	private static void EnsureUserDataFolders()
	{
		string path = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures");
		Directory.CreateDirectory("UserData/RumblePhotoAlbum");
		Directory.CreateDirectory(path);
	}

	[IteratorStateMachine(typeof(<LoadAlbum>d__7))]
	private static IEnumerator<WaitForSeconds> LoadAlbum(string sceneName)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LoadAlbum>d__7(0)
		{
			sceneName = sceneName
		};
	}

	private static void reloadStash()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Expected O, but got Unknown
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Expected O, but got Unknown
		JObject val = (JObject)root[currentScene];
		? val2 = (JArray)val["stash"];
		if ((int)val2 == 0)
		{
			val2 = new JArray();
		}
		JArray val3 = (JArray)val2;
		JToken obj = val["album"];
		JArray source = (JArray)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()));
		HashSet<string> other = new HashSet<string>(from e in (IEnumerable<JToken>)source
			where e[(object)"path"] != null
			select ((object)e[(object)"path"]).ToString());
		HashSet<string> hashSet = new HashSet<string>();
		foreach (JToken item in val3)
		{
			string text = ((object)item).ToString();
			if (!File.Exists(text))
			{
				string path = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures", text);
				if (!File.Exists(path))
				{
					LogWarn("Removed missing file from stash: " + text);
				}
				else
				{
					hashSet.Add(text);
				}
			}
		}
		HashSet<string> hashSet2 = new HashSet<string>(hashSet);
		hashSet2.UnionWith(other);
		string path2 = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures");
		HashSet<string> hashSet3 = new HashSet<string>(Directory.Exists(path2) ? (from f in Directory.GetFiles(path2)
			where f.EndsWith(".png") || f.EndsWith(".jpg") || f.EndsWith(".jpeg")
			select (f)) : Enumerable.Empty<string>());
		foreach (string item2 in hashSet3)
		{
			string fileName = Path.GetFileName(item2);
			if (!hashSet2.Contains(fileName))
			{
				hashSet.Add(fileName);
			}
		}
		val["stash"] = (JToken)new JArray((object)hashSet);
	}

	private static PictureData ParsePictureData(JToken pictureJson)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Invalid comparison between Unknown and I4
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		if (pictureJson == null || (int)pictureJson.Type != 1)
		{
			throw new ArgumentException("Invalid JSON object for PictureData.");
		}
		JObject val = (JObject)pictureJson;
		PictureData pictureData = new PictureData();
		pictureData.path = ((JToken)val).Value<string>((object)"path");
		if (string.IsNullOrEmpty(pictureData.path))
		{
			throw new ArgumentException("Missing field \"path\"");
		}
		pictureData.position = ParseVector3(val["position"], "position");
		pictureData.rotation = ParseVector3(val["rotation"], "rotation");
		pictureData.width = Math.Min(((JToken)val).Value<float?>((object)"width").GetValueOrDefault(), 5f);
		pictureData.height = Math.Min(((JToken)val).Value<float?>((object)"height").GetValueOrDefault(), 5f);
		pictureData.padding = ((JToken)val).Value<float?>((object)"padding") ?? defaultPadding;
		pictureData.thickness = ((JToken)val).Value<float?>((object)"thickness") ?? defaultThickness;
		pictureData.color = defaultColor;
		JToken token = default(JToken);
		if (val.TryGetValue("color", ref token))
		{
			pictureData.color = ParseColor(token);
		}
		pictureData.alpha = ((JToken)val).Value<bool?>((object)"alpha") ?? enableAlpha;
		pictureData.visible = ((JToken)val).Value<bool?>((object)"visible") ?? visibility;
		return pictureData;
	}

	private static Vector3 ParseVector3(JToken token, string fieldName)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Invalid comparison between Unknown and I4
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		if (token == null)
		{
			throw new ArgumentException("Missing field \"" + fieldName + "\"");
		}
		if ((int)token.Type != 2)
		{
			throw new ArgumentException(fieldName + "' must be an array [x, y, z] (got " + ((object)token).ToString() + ")");
		}
		float[] array = token.ToObject<float[]>();
		if (array.Length != 3)
		{
			throw new ArgumentException(fieldName + "' must have exactly 3 elements (got " + ((object)token).ToString() + ")");
		}
		return new Vector3(array[0], array[1], array[2]);
	}

	private static Color ParseColor(JToken token)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Invalid comparison between Unknown and I4
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if ((int)token.Type == 2)
		{
			float[] array = token.ToObject<float[]>();
			if (array.Length >= 3)
			{
				return new Color(array[0], array[1], array[2], (array.Length >= 4) ? array[3] : 1f);
			}
		}
		else if ((int)token.Type == 8)
		{
			string hex = ((object)token).ToString();
			return Hex2Color(hex);
		}
		throw new ArgumentException("PictureData: 'color' must be [r,g,b,a?] or hex string.");
	}

	private static Color Hex2Color(string hex)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		Color result = default(Color);
		if (ColorUtility.TryParseHtmlString(hex, ref result))
		{
			return result;
		}
		throw new ArgumentException("PictureData: 'color' must be [r,g,b,a?] or hex string.");
	}

	protected static void CreatePictureBlock(ref PictureData pictureData, Transform parent)
	{
		//IL_008a: 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_019d: Expected O, but got Unknown
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		string path = pictureData.path;
		if (!File.Exists(path))
		{
			string text = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures", pictureData.path);
			if (!File.Exists(text))
			{
				Log("file doesn't exist");
				return;
			}
			path = text;
		}
		Texture2D val = null;
		val = ((!pictureData.alpha) ? LoadTexture(path) : LoadFlattenedTexture(path, pictureData.color));
		int layer = (pictureData.visible ? LayerMask.NameToLayer("UI") : LayerMask.NameToLayer("PlayerFade"));
		float num = (float)((Texture)val).height / (float)((Texture)val).width;
		if (pictureData.width == 0f && pictureData.height == 0f)
		{
			if (num > 1f)
			{
				pictureData.height = defaultSize;
			}
			else
			{
				pictureData.width = defaultSize;
			}
		}
		if (pictureData.width == 0f)
		{
			pictureData.width = (pictureData.height - 2f * pictureData.padding) / num + 2f * pictureData.padding;
		}
		else
		{
			pictureData.height = (pictureData.width - 2f * pictureData.padding) * num + 2f * pictureData.padding;
		}
		GameObject val2 = new GameObject();
		val2.layer = layer;
		((Object)val2).name = "PictureBlock: " + Path.GetFileNameWithoutExtension(pictureData.path);
		val2.transform.SetParent(parent, false);
		val2.transform.localPosition = pictureData.position;
		val2.transform.localRotation = Quaternion.Euler(pictureData.rotation);
		GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)3);
		val3.layer = layer;
		((Object)val3).name = "frame";
		val3.transform.SetParent(val2.transform, false);
		val3.transform.localScale = new Vector3(pictureData.width, pictureData.height, pictureData.thickness);
		val3.transform.localPosition = new Vector3(0f, 0f, pictureData.thickness / 2f);
		Renderer component = val3.GetComponent<Renderer>();
		component.material.shader = Shader.Find("Shader Graphs/RUMBLE_Prop");
		component.material.SetColor("_Overlay", pictureData.color);
		GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)5);
		val4.layer = layer;
		((Object)val4).name = "picture";
		val4.transform.SetParent(val2.transform, false);
		val4.transform.localScale = new Vector3(pictureData.width - 2f * pictureData.padding, pictureData.height - 2f * pictureData.padding, 1f);
		val4.transform.localPosition = new Vector3(0f, 0f, -0.001f);
		val4.transform.localRotation = Quaternion.identity;
		Renderer component2 = val4.GetComponent<Renderer>();
		component2.material.shader = Shader.Find("Shader Graphs/RUMBLE_Prop");
		component2.material.SetTexture("_Albedo", (Texture)(object)val);
		pictureData.obj = val2;
		pictureData = pictureData;
		PicturesList.Add(pictureData);
		CreateActionButtons(pictureData);
	}

	private static void CreateActionButtons(PictureData pictureData)
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		GameObject gameObject = ((Component)pictureData.obj.transform.GetChild(0)).gameObject;
		float num = pictureData.width / 6f;
		Vector3 localScale = default(Vector3);
		((Vector3)(ref localScale))..ctor(10f * num, pictureData.thickness / 0.03f, 10f * num);
		float num2 = pictureData.height / 2f + num * 0.6f;
		GameObject val = new GameObject();
		((Object)val).name = "actionButtons";
		val.transform.localScale = Vector3.one;
		Action action = delegate
		{
			stashPicture(pictureData);
		};
		GameObject val2 = NewFriendButton("stash", "Stash", action);
		val2.transform.localScale = localScale;
		val2.transform.SetParent(val.transform, true);
		val2.transform.localPosition = new Vector3((0f - pictureData.width) / 2f + num / 2f, 0f, 0f);
		val2.transform.localRotation = Quaternion.Euler(new Vector3(90f, 90f, -90f));
		action = delegate
		{
			togglePictureVisibility(pictureData);
		};
		GameObject val3 = NewFriendButton("visibility", pictureData.visible ? "Hide" : "Show", action);
		val3.transform.localScale = localScale;
		val3.transform.SetParent(val.transform, true);
		val3.transform.localPosition = new Vector3(0f, 0f, 0f);
		val3.transform.localRotation = Quaternion.Euler(new Vector3(90f, 90f, -90f));
		action = delegate
		{
			deletePicture(pictureData, keepFile: false);
		};
		GameObject val4 = NewFriendButton("delete", "Delete", action);
		val4.transform.localScale = localScale;
		val4.transform.SetParent(val.transform, true);
		val4.transform.localPosition = new Vector3(pictureData.width / 2f - num / 2f, 0f, 0f);
		val4.transform.localRotation = Quaternion.Euler(new Vector3(90f, 90f, -90f));
		val.transform.SetParent(gameObject.transform);
		val.transform.localScale = new Vector3(1f / gameObject.transform.localScale.x, 1f / gameObject.transform.localScale.y, 1f / gameObject.transform.localScale.z);
		val.transform.localPosition = new Vector3(0f, num2 / pictureData.height, 0f);
		val.transform.localRotation = Quaternion.Euler(Vector3.zero);
		val.SetActive(false);
	}

	private static Texture2D LoadTexture(string path)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		byte[] array = File.ReadAllBytes(path);
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
		ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array));
		return val;
	}

	private static Texture2D LoadFlattenedTexture(string path, Color background)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Expected O, but got Unknown
		byte[] array = File.ReadAllBytes(path);
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
		ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array));
		Color[] array2 = Il2CppArrayBase<Color>.op_Implicit((Il2CppArrayBase<Color>)(object)val.GetPixels());
		Color[] array3 = (Color[])(object)new Color[array2.Length];
		for (int i = 0; i < array2.Length; i++)
		{
			Color val2 = array2[i];
			float a = val2.a;
			array3[i] = new Color(val2.r * a + background.r * (1f - a), val2.g * a + background.g * (1f - a), val2.b * a + background.b * (1f - a));
		}
		Texture2D val3 = new Texture2D(((Texture)val).width, ((Texture)val).height, (TextureFormat)3, false);
		val3.SetPixels(Il2CppStructArray<Color>.op_Implicit(array3));
		val3.Apply();
		return val3;
	}

	private static void UpdatePictureConfig(PictureData pictureData)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0046: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Expected O, but got Unknown
		if (pictureData.jsonConfig != null)
		{
			Vector3 position = pictureData.obj.transform.position;
			Vector3 eulerAngles = pictureData.obj.transform.eulerAngles;
			JToken jsonConfig = pictureData.jsonConfig;
			JArray val = new JArray();
			val.Add(JToken.op_Implicit(position.x));
			val.Add(JToken.op_Implicit(position.y));
			val.Add(JToken.op_Implicit(position.z));
			jsonConfig[(object)"position"] = (JToken)val;
			JToken jsonConfig2 = pictureData.jsonConfig;
			JArray val2 = new JArray();
			val2.Add(JToken.op_Implicit(eulerAngles.x));
			val2.Add(JToken.op_Implicit(eulerAngles.y));
			val2.Add(JToken.op_Implicit(eulerAngles.z));
			jsonConfig2[(object)"rotation"] = (JToken)val2;
			if (pictureData.jsonConfig[(object)"height"] != null)
			{
				pictureData.jsonConfig[(object)"height"] = JToken.op_Implicit(pictureData.height);
			}
			else
			{
				pictureData.jsonConfig[(object)"width"] = JToken.op_Implicit(pictureData.width);
			}
			if (pictureData.jsonConfig[(object)"visible"] != null || pictureData.visible != visibility)
			{
				pictureData.jsonConfig[(object)"visible"] = JToken.op_Implicit(pictureData.visible);
			}
			File.WriteAllText(fullPath, ((JToken)root).ToString((Formatting)1));
		}
	}

	private void InitModUI()
	{
		UI.instance.UI_Initialized += OnUIInit;
		SetUIOptions();
		ReadModUIOptions();
	}

	private void SetUIOptions()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Expected O, but got Unknown
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Expected O, but got Unknown
		Mod.ModName = "RumblePhotoAlbum";
		Mod.ModVersion = "1.1.1";
		Mod.SetFolder("RumblePhotoAlbum");
		Mod.AddToList("Default frame color", "#7accc2", "You can set the frame color individually by adding a \"color\" field to the picture's JSON config.", new Tags());
		Mod.AddToList("Default frame padding", 0.01f, "You can set the frame padding individually by adding a \"padding\" field to the picture's JSON config.", new Tags());
		Mod.AddToList("Default frame thickness", 0.01f, "You can set the frame thickness individually by adding a \"thickness\" field to the picture's JSON config.", new Tags());
		Mod.AddToList("Default picture size", 0.5f, "This is the default size of the pictures when they spawn. It will not change the pictures that are already positioned.", new Tags());
		Mod.AddToList("Enable transparency", false, 0, "WARNING: this option adds a lag spike on picture creation.\nTo lower the effect, you can enable transparency individually by adding a boolean field \"alpha\" to the picture's JSON config.", new Tags());
		Mod.AddToList("Show on camera", true, 0, "If disabled, this will hide all pictures from legacy camera, as well as LIV and Rock Cam.\nYou can hide/show any individual picture by clicking the corresponding button while holding it.", new Tags());
		Mod.AddToList("Show action buttons", true, 0, "If disabled, the 3 buttons on the held picture won't appear.", new Tags());
		Mod.GetFromFile();
	}

	private void OnUIInit()
	{
		Mod.ModSaved += OnUISaved;
		UI.instance.AddMod(Mod);
	}

	private void ReadModUIOptions()
	{
		//IL_001c: 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)
		defaultColor = Hex2Color((string)Mod.Settings[0].SavedValue);
		defaultPadding = (float)Mod.Settings[1].SavedValue;
		defaultThickness = (float)Mod.Settings[2].SavedValue;
		defaultSize = (float)Mod.Settings[3].SavedValue;
		enableAlpha = (bool)Mod.Settings[4].SavedValue;
		visibility = (bool)Mod.Settings[5].SavedValue;
		buttonsVisibility = (bool)Mod.Settings[6].SavedValue;
	}

	private void OnUISaved()
	{
		ReadModUIOptions();
		Object.Destroy((Object)(object)photoAlbum);
		MelonCoroutines.Start((IEnumerator)LoadAlbum(currentScene));
	}

	private static void InitGrabbing()
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		Transform child = ((Component)Players.GetPlayerController()).gameObject.transform.GetChild(2);
		grip[0] = false;
		grip[1] = false;
		holding[0] = false;
		holding[1] = false;
		hand[0] = ((Component)child.GetChild(1)).gameObject;
		hand[1] = ((Component)child.GetChild(2)).gameObject;
		currentlyModified = null;
		resizingHandle = new GameObject("ResizingHandle");
		resizingHandle.transform.SetParent(child, true);
	}

	private static void ProcessGrabbing()
	{
		if ((ProcessGrabbing(0) || ProcessGrabbing(1)) && currentlyModified != null)
		{
			UpdatePictureParent(currentlyModified);
			if (!holding[0] && !holding[1])
			{
				GameObject gameObject = ((Component)currentlyModified.obj.transform.GetChild(0).GetChild(0)).gameObject;
				gameObject.SetActive(false);
				currentlyModified = null;
			}
		}
	}

	private static bool ProcessGrabbing(int index)
	{
		bool flag = CheckIfGripChanged(index);
		if (flag)
		{
			bool flag2 = holding[index];
			UpdateHolding(index);
			flag = holding[index] != flag2;
		}
		return flag;
	}

	private static bool CheckIfGripChanged(int index)
	{
		bool flag = false;
		switch (index)
		{
		case 0:
			flag = LeftController.GetTrigger() > 0.5f || LeftController.GetGrip() > 0.5f;
			break;
		case 1:
			flag = RightController.GetTrigger() > 0.5f || RightController.GetGrip() > 0.5f;
			break;
		}
		bool result = flag != grip[index];
		if (flag && !grip[index])
		{
			grip[index] = true;
		}
		else if (!flag && grip[index])
		{
			grip[index] = false;
		}
		return result;
	}

	private static void UpdateHolding(int index)
	{
		if (PicturesList == null)
		{
			return;
		}
		if (!grip[index])
		{
			holding[index] = false;
			return;
		}
		if (currentlyModified != null)
		{
			float num = DistanceToPictureSurface(hand[index], currentlyModified);
			holding[index] = num < 0.05f;
			return;
		}
		float num2 = 0.05f;
		foreach (PictureData pictures in PicturesList)
		{
			if (pictures.obj == null)
			{
				LogWarn("Framed picture " + pictures.path + " has no GameObject associated with it.");
				continue;
			}
			float num3 = DistanceToPictureSurface(hand[index], pictures);
			if (num3 < num2)
			{
				holding[index] = true;
				num2 = num3;
				currentlyModified = pictures;
				if (buttonsVisibility)
				{
					GameObject gameObject = ((Component)currentlyModified.obj.transform.GetChild(0).GetChild(0)).gameObject;
					gameObject.SetActive(true);
				}
				if (pictures == mailTubePicture)
				{
					mailTubePicture = null;
					albumJson.Add(pictures.jsonConfig);
				}
				if (pictures == rockCamPicture)
				{
					rockCamPicture = null;
					albumJson.Add(pictures.jsonConfig);
				}
			}
		}
	}

	private static float DistanceToPictureSurface(GameObject hand, PictureData pictureData)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: 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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = hand.transform.position;
		Transform child = pictureData.obj.transform.GetChild(0);
		Vector3 position2 = child.position;
		Quaternion rotation = child.rotation;
		Vector3 val = new Vector3(pictureData.width, pictureData.height, pictureData.thickness) * 0.5f;
		Vector3 val2 = Quaternion.Inverse(rotation) * (position - position2);
		float num = Mathf.Max(0f, Mathf.Abs(val2.x) - val.x);
		float num2 = Mathf.Max(0f, Mathf.Abs(val2.y) - val.y);
		float num3 = Mathf.Max(0f, Mathf.Abs(val2.z) - val.z);
		if (num == 0f && num2 == 0f && num3 == 0f)
		{
			return 0f;
		}
		return Mathf.Sqrt(num * num + num2 * num2 + num3 * num3);
	}

	private static void UpdatePictureParent(PictureData pictureData)
	{
		if (holding[0])
		{
			if (holding[1])
			{
				UpdateResizingHandle();
				pictureData.obj.transform.SetParent(resizingHandle.transform, true);
			}
			else
			{
				pictureData.obj.transform.SetParent(hand[0].transform, true);
			}
		}
		else if (holding[1])
		{
			pictureData.obj.transform.SetParent(hand[1].transform, true);
		}
		else
		{
			pictureData.obj.transform.SetParent(photoAlbum.transform, true);
			UpdatePictureConfig(pictureData);
		}
	}

	private static void UpdateResizingIfNeeded()
	{
		if (holding[0] && holding[1])
		{
			UpdateResizingHandle();
			UpdatePictureSize(currentlyModified);
		}
	}

	private static void UpdateResizingHandle()
	{
		//IL_001c: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: 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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		Transform transform = hand[0].transform;
		Transform transform2 = hand[1].transform;
		Vector3 localPosition = (transform.localPosition + transform2.localPosition) * 0.5f;
		Vector3 val = transform2.localPosition - transform.localPosition;
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Quaternion val2 = Quaternion.Slerp(transform.localRotation, transform2.localRotation, 0.5f);
		val = Vector3.ProjectOnPlane(val2 * Vector3.up, normalized);
		Vector3 normalized2 = ((Vector3)(ref val)).normalized;
		val = Vector3.Cross(normalized, normalized2);
		Vector3 normalized3 = ((Vector3)(ref val)).normalized;
		normalized2 = Vector3.Cross(normalized3, normalized);
		Quaternion localRotation = Quaternion.LookRotation(normalized3, normalized2);
		float num = Vector3.Distance(transform.localPosition, transform2.localPosition);
		float num2 = currentlyModified.obj.transform.localScale.x * num;
		Transform child = currentlyModified.obj.transform.GetChild(0);
		float num3 = Math.Max(child.localScale.x, child.localScale.y);
		float num4 = Math.Min(num3, 5f / num2) / num3;
		resizingHandle.transform.localScale = Vector3.one * num * num4;
		resizingHandle.transform.localPosition = localPosition;
		resizingHandle.transform.localRotation = localRotation;
	}

	private static void UpdatePictureSize(PictureData pictureData)
	{
		//IL_000c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		float num = pictureData.obj.transform.localScale.x * resizingHandle.transform.localScale.x;
		Transform child = pictureData.obj.transform.GetChild(0);
		Transform child2 = pictureData.obj.transform.GetChild(1);
		float num2 = child2.localScale.y / child2.localScale.x;
		float num3 = child.localScale.x - 2f * pictureData.padding / num;
		child2.localScale = new Vector3(num3, num3 * num2, 1f);
		child.localScale = new Vector3(child.localScale.x, child2.localScale.y + 2f * pictureData.padding / num, pictureData.thickness / num);
		pictureData.width = child.localScale.x * num;
		pictureData.height = child.localScale.y * num;
		((Component)child).transform.localPosition = new Vector3(0f, 0f, pictureData.thickness / (2f * num));
		((Component)child2).transform.localPosition = new Vector3(0f, 0f, -0.001f / num);
	}

	private static void initializeInteractionObjects()
	{
		rockCamInitialized = false;
		if (currentScene == "Loader")
		{
			return;
		}
		if (currentScene == "Gym")
		{
			if (AlbumInteractionItems == null)
			{
				initializeGlobals();
			}
			initializeGymObjects();
		}
		else if (currentScene == "Park")
		{
			initializeParkObjects();
		}
		initializeRockCam();
	}

	private static void initializeGlobals()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		AlbumInteractionItems = new GameObject();
		((Object)AlbumInteractionItems).name = "AlbumInteractionItems";
		Object.DontDestroyOnLoad((Object)(object)AlbumInteractionItems);
		friendButton = Object.Instantiate<GameObject>(Button.GetGameObject());
		((Object)friendButton).name = "friendButton";
		friendButton.SetActive(false);
		((Behaviour)friendButton.GetComponent<InteractionButton>()).enabled = true;
		((Component)friendButton.transform.GetChild(4)).gameObject.SetActive(false);
		GameObject val = Create.NewText();
		TextMeshPro component = val.GetComponent<TextMeshPro>();
		((TMP_Text)component).alignment = (TextAlignmentOptions)514;
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(1f, 0.98f, 0.75f);
		((Graphic)component).color = val2;
		((TMP_Text)component).colorGradient = new VertexGradient(val2);
		((TMP_Text)component).fontSize = 0.4f;
		((Object)component).name = "text";
		val.transform.SetParent(friendButton.transform, false);
		val.transform.localPosition = new Vector3(0f, 0.015f, 0f);
		val.transform.localRotation = Quaternion.Euler(new Vector3(90f, 180f, 0f));
		friendButton.transform.SetParent(AlbumInteractionItems.transform);
		gearMarketButton = Object.Instantiate<GameObject>(OneButtonLayout.GetGameObject());
		((Object)gearMarketButton).name = "gearMarketButton";
		gearMarketButton.SetActive(false);
		((Behaviour)((Component)gearMarketButton.transform.GetChild(0)).gameObject.GetComponent<InteractionTouch>()).enabled = true;
		gearMarketButton.transform.SetParent(AlbumInteractionItems.transform);
		mailTubeObj = Object.Instantiate<GameObject>(MailTube.GetGameObject());
		((Object)mailTubeObj).name = "mailTube";
		mailTubeObj.SetActive(false);
		mailTubeObj.transform.SetParent(AlbumInteractionItems.transform);
		rockCamTf = ((Component)Players.GetPlayerController()).gameObject.transform.GetChild(10).GetChild(2);
		rockCamButton = Object.Instantiate<GameObject>(((Component)rockCamTf.GetChild(2).GetChild(0).GetChild(1)
			.GetChild(4)
			.GetChild(0)).gameObject);
		((Object)rockCamButton).name = "rockCamButton";
		rockCamButton.SetActive(false);
		rockCamButton.transform.SetParent(AlbumInteractionItems.transform);
	}

	private static void initializeRockCam()
	{
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Expected O, but got Unknown
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (rockCamInitialized || rockCamButton == null || gearMarketButton == null)
			{
				return;
			}
			PlayerController playerController = Players.GetPlayerController();
			if (playerController != null)
			{
				rockCamPicture = null;
				rockCamTf = ((Component)playerController).gameObject.transform.GetChild(10).GetChild(2);
				Action action = delegate
				{
					PrintPhoto();
				};
				GameObject val = NewRockCamButton("printButton", "Print photo", action);
				val.transform.SetParent(rockCamTf.GetChild(2).GetChild(0), true);
				val.transform.localPosition = new Vector3(-0.08f, 0.034f, 0.143f);
				val.transform.localRotation = Quaternion.Euler(new Vector3(90f, 0f, 0f));
				rockCamHandle = new GameObject();
				((Object)rockCamHandle).name = "printHandle";
				rockCamHandle.transform.localScale = Vector3.one;
				rockCamHandle.transform.SetParent(rockCamTf.GetChild(2).GetChild(0), true);
				rockCamHandle.transform.localPosition = new Vector3(0f, 0.079f, 0.22f);
				rockCamHandle.transform.localRotation = Quaternion.Euler(new Vector3(-50f, 180f, 0f));
				PhotoPrintingIndex = 0;
				rockCamInitialized = true;
			}
		}
		catch (Exception)
		{
			rockCamInitialized = false;
		}
	}

	private static void initializeGymObjects()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		mailTube = MailTube.GetGameObject().GetComponent<MailTube>();
		Action action = delegate
		{
			SpawnPicture();
		};
		GameObject val = NewGearMarketButton("spawnButton", "Spawn picture", action);
		GameObject gameObject = Gearmarket.GetGameObject();
		val.transform.SetParent(gameObject.transform);
		val.transform.localPosition = new Vector3(0.075f, 1.1f, 0.19f);
		val.transform.localRotation = Quaternion.Euler(new Vector3(270f, 270f, 0f));
		initializeMailTubeObjects();
	}

	private static void stashPicture(PictureData pictureData)
	{
		if (pictureData.jsonConfig != null)
		{
			pictureData.jsonConfig.Remove();
		}
		Object.Destroy((Object)(object)pictureData.obj);
		currentlyModified = null;
		stashJson.Add(JToken.op_Implicit(pictureData.path));
		PicturesList.Remove(pictureData);
		File.WriteAllText(fullPath, ((JToken)root).ToString((Formatting)1));
		Log("Stashed a picture");
	}

	private static void togglePictureVisibility(PictureData pictureData)
	{
		pictureData.visible = !pictureData.visible;
		int layer = (pictureData.visible ? LayerMask.NameToLayer("UI") : LayerMask.NameToLayer("PlayerFade"));
		((Component)pictureData.obj.transform.GetChild(0)).gameObject.layer = layer;
		((Component)pictureData.obj.transform.GetChild(1)).gameObject.layer = layer;
		Transform child = pictureData.obj.transform.GetChild(0).GetChild(0).GetChild(1);
		TextMeshPro component = ((Component)child.GetChild(6)).gameObject.GetComponent<TextMeshPro>();
		((TMP_Text)component).SetText(pictureData.visible ? "Hide" : "Show");
		Log("Made a picture " + (pictureData.visible ? "visible" : "invisible") + " to all cameras");
	}

	protected static void deletePicture(PictureData pictureData, bool keepFile)
	{
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Expected O, but got Unknown
		if (pictureData.jsonConfig != null)
		{
			pictureData.jsonConfig.Remove();
			File.WriteAllText(fullPath, ((JToken)root).ToString((Formatting)1));
		}
		Object.Destroy((Object)(object)pictureData.obj);
		currentlyModified = null;
		PicturesList.Remove(pictureData);
		if (File.Exists(pictureData.path) || keepFile)
		{
			return;
		}
		string path = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures", pictureData.path);
		if (!File.Exists(path))
		{
			return;
		}
		bool flag = false;
		foreach (KeyValuePair<string, JToken> item in root)
		{
			JArray val = (JArray)item.Value[(object)"album"];
			foreach (JToken item2 in val)
			{
				if (item2.Value<string>((object)"path") == pictureData.path)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				break;
			}
		}
		if (flag)
		{
			Log("File not deleted because it's used elsewhere: " + pictureData.path);
			return;
		}
		File.Delete(path);
		Log("Deleted file: " + pictureData.path);
	}

	private static void initializeParkObjects()
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		mailTube = NewMailTube().GetComponent<MailTube>();
		((Object)((Component)mailTube).gameObject).name = "mailTube";
		((Component)mailTube).transform.position = new Vector3(-13.3f, -5.88f, 4.71f);
		((Component)mailTube).transform.rotation = Quaternion.Euler(new Vector3(0f, 180f, 0f));
		Action action = delegate
		{
			SpawnPicture();
		};
		GameObject val = NewGearMarketButton("spawnButton", "Spawn picture", action);
		val.transform.position = new Vector3(-13.19f, -4.68f, 5.42f);
		val.transform.rotation = Quaternion.Euler(new Vector3(-90f, 35f, 0f));
		initializeMailTubeObjects();
	}

	private static void initializeMailTubeObjects()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		//IL_0050: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		animationRunning = false;
		mailTubePicture = null;
		purchaseSlab = ((Component)mailTube).gameObject.transform.GetChild(5);
		mailTubeHandle = new GameObject();
		((Object)mailTubeHandle).name = "mailTubeHandle";
		mailTubeHandle.transform.localScale = 0.505f * Vector3.one;
		mailTubeHandle.transform.SetParent(purchaseSlab, true);
		mailTubeHandle.transform.localPosition = Vector3.zero;
		mailTubeHandle.transform.localRotation = Quaternion.Euler(Vector3.zero);
	}

	private static GameObject NewFriendButton(string name, string text, Action action)
	{
		GameObject val = Object.Instantiate<GameObject>(friendButton);
		val.SetActive(true);
		((Object)val).name = name;
		val.GetComponent<InteractionButton>().onPressed.AddListener(UnityAction.op_Implicit(action));
		TextMeshPro component = ((Component)val.transform.GetChild(6)).gameObject.GetComponent<TextMeshPro>();
		((TMP_Text)component).SetText(text);
		return val;
	}

	private static GameObject NewMailTube()
	{
		GameObject val = Object.Instantiate<GameObject>(mailTubeObj);
		val.SetActive(true);
		return val;
	}

	private static GameObject NewGearMarketButton(string name, string text, Action action)
	{
		GameObject val = Object.Instantiate<GameObject>(gearMarketButton);
		val.SetActive(true);
		((Object)val).name = name;
		((InteractionBase)((Component)val.transform.GetChild(0)).gameObject.GetComponent<InteractionTouch>()).onEndInteraction.AddListener(UnityAction.op_Implicit(action));
		TextMeshPro component = ((Component)val.transform.GetChild(0).GetChild(3)).gameObject.GetComponent<TextMeshPro>();
		((TMP_Text)component).fontSize = 0.6f;
		((TMP_Text)component).m_text = text;
		return val;
	}

	private static GameObject NewRockCamButton(string name, string text, Action action)
	{
		GameObject val = Object.Instantiate<GameObject>(rockCamButton);
		val.SetActive(true);
		((Object)val).name = name;
		val.GetComponent<InteractionButton>().onPressed.AddListener(UnityAction.op_Implicit(action));
		TextMeshPro component = ((Component)val.transform.GetChild(1)).gameObject.GetComponent<TextMeshPro>();
		((TMP_Text)component).m_text = text;
		return val;
	}

	private static string GetNthMostRecentPhoto(string sourceFolder, int n)
	{
		string path = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures");
		List<string> list = (from f in Directory.GetFiles(sourceFolder, "*.*")
			where f.EndsWith(".png") || f.EndsWith(".jpg") || f.EndsWith(".jpeg")
			select f).OrderByDescending(File.GetCreationTime).ToList();
		if (n >= list.Count)
		{
			return null;
		}
		string text = list[n];
		string fileName = Path.GetFileName(text);
		string destFileName = Path.Combine(path, fileName);
		File.Copy(text, destFileName, overwrite: true);
		return fileName;
	}

	private static void PrintPhoto()
	{
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Expected O, but got Unknown
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		if (rockCamPicture == null)
		{
			RecordingConfiguration configuration = Singleton<RecordingCamera>.instance.configuration;
			LCKTabletUtility component = ((Component)rockCamTf).gameObject.GetComponent<LCKTabletUtility>();
			string sourceFolder = Path.Combine(configuration.LCKSavePath, component.photosFolderName);
			string nthMostRecentPhoto = GetNthMostRecentPhoto(sourceFolder, PhotoPrintingIndex);
			PhotoPrintingIndex++;
			if (nthMostRecentPhoto == null)
			{
				LogWarn("No photo to print");
				return;
			}
			PictureData pictureData = new PictureData();
			pictureData.path = nthMostRecentPhoto;
			pictureData.padding = defaultPadding;
			pictureData.thickness = defaultThickness;
			pictureData.color = defaultColor;
			rockCamPicture = new PictureData();
			rockCamPicture.jsonConfig = (JToken)new JObject();
			rockCamPicture.jsonConfig[(object)"path"] = JToken.op_Implicit(pictureData.path);
			rockCamPicture = pictureData;
			CreatePictureBlock(ref rockCamPicture, rockCamHandle.transform);
			rockCamPicture.obj.transform.localPosition = new Vector3(0f, pictureData.height / 2f, 0f);
		}
	}

	private static void SpawnPicture()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		if (!animationRunning && mailTubePicture == null)
		{
			reloadStash();
			stashJson = (JArray)root[currentScene][(object)"stash"];
			if (stashJson != null && ((JContainer)stashJson).Count == 0)
			{
				LogWarn("No pictures in stash, cannot spawn new picture");
			}
			else
			{
				MelonCoroutines.Start((IEnumerator)RunMailTubeAnimation());
			}
		}
	}

	private static void SetPreviewSlabVisibility(bool visible)
	{
		if (purchaseSlab != null)
		{
			((Component)purchaseSlab.GetChild(0)).gameObject.SetActive(visible);
			((Component)purchaseSlab.GetChild(1)).gameObject.SetActive(visible);
			((Component)purchaseSlab.GetChild(2)).gameObject.SetActive(visible);
		}
	}

	[IteratorStateMachine(typeof(<RunMailTubeAnimation>d__76))]
	private static IEnumerator<WaitForSeconds> RunMailTubeAnimation()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <RunMailTubeAnimation>d__76(0);
	}

	private static void Log(string msg)
	{
		MelonLogger.Msg(msg);
	}

	private static void LogWarn(string msg)
	{
		MelonLogger.Warning(msg);
	}

	private static void LogError(string msg)
	{
		MelonLogger.Error(msg);
	}

	public override void OnLateInitializeMelon()
	{
		EnsureUserDataFolders();
		Calls.onMapInitialized += OnMapInitialized;
	}

	private void OnMapInitialized()
	{
		initializeInteractionObjects();
		MelonCoroutines.Start((IEnumerator)LoadAlbum(currentScene));
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		currentScene = sceneName;
		if (sceneName == "Loader")
		{
			InitModUI();
		}
	}

	public override void OnFixedUpdate()
	{
		if (currentScene != "Loader")
		{
			try
			{
				ProcessGrabbing();
			}
			catch (Exception ex)
			{
				LogError("Error in OnFixedUpdate: " + ex.Message);
			}
		}
	}

	public override void OnUpdate()
	{
		if (currentScene != "Loader")
		{
			try
			{
				UpdateResizingIfNeeded();
			}
			catch (Exception ex)
			{
				LogError("Error in OnUpdate: " + ex.Message);
			}
		}
	}
}
public static class BuildInfo
{
	public const string ModName = "RumblePhotoAlbum";

	public const string ModVersion = "1.1.1";

	public const string Description = "Decorate your environment with framed pictures";

	public const string Author = "Kalamart";

	public const string Company = "";
}