Decompiled source of RumblePhotoAlbum v1.2.3

Mods/RumblePhotoAlbum.dll

Decompiled a week 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 System.Text;
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 ThreeDISevenZeroR.UnityGifDecoder;
using ThreeDISevenZeroR.UnityGifDecoder.Decode;
using ThreeDISevenZeroR.UnityGifDecoder.Model;
using ThreeDISevenZeroR.UnityGifDecoder.Utils;
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.2.3", "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+f3d874786d08863046c5be4e6d43a7d76368ecf4")]
[assembly: AssemblyProduct("RumblePhotoAlbum")]
[assembly: AssemblyTitle("RumblePhotoAlbum")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ThreeDISevenZeroR.UnityGifDecoder
{
	public class GifBitBlockReader
	{
		private Stream stream;

		private int currentByte;

		private int currentBitPosition;

		private int currentBufferPosition;

		private int currentBufferSize;

		private bool endReached;

		private readonly byte[] buffer;

		public GifBitBlockReader()
		{
			buffer = new byte[256];
		}

		public GifBitBlockReader(Stream stream)
			: this()
		{
			SetStream(stream);
		}

		public void SetStream(Stream stream)
		{
			this.stream = stream;
		}

		public void StartNewReading()
		{
			currentByte = 0;
			currentBitPosition = 8;
			ReadNextBlock();
		}

		public void FinishReading()
		{
			while (!endReached)
			{
				ReadNextBlock();
			}
		}

		public int ReadBits(int count)
		{
			int num = 0;
			int num2 = count;
			int num3 = 0;
			int num4 = 8 - currentBitPosition;
			while (num2 > 0)
			{
				if (currentBitPosition >= 8)
				{
					currentBitPosition = 0;
					num4 = 8;
					if (endReached)
					{
						currentByte = 0;
					}
					else
					{
						currentByte = buffer[currentBufferPosition++];
						if (currentBufferPosition == currentBufferSize)
						{
							ReadNextBlock();
						}
					}
				}
				byte b = (byte)((1 << num2) - 1 << currentBitPosition);
				int num5 = ((num4 < num2) ? num4 : num2);
				num += (b & currentByte) >> currentBitPosition << num3;
				currentBitPosition += num5;
				num2 -= num5;
				num3 += num5;
			}
			return num;
		}

		private void ReadNextBlock()
		{
			currentBufferSize = stream.ReadByte8();
			currentBufferPosition = 0;
			endReached = currentBufferSize == 0;
			if (!endReached)
			{
				stream.Read(buffer, 0, currentBufferSize);
			}
		}
	}
	public class GifCanvas
	{
		private Color32[] canvasColors;

		private Color32[] revertDisposalBuffer;

		private int canvasWidth;

		private int canvasHeight;

		private bool canvasIsEmpty;

		private Color32[] framePalette;

		private GifDisposalMethod frameDisposalMethod;

		private int frameCanvasPosition;

		private int frameCanvasRowEndPosition;

		private int frameTransparentColorIndex;

		private int frameRowCurrent;

		private int frameX;

		private int frameY;

		private int frameWidth;

		private int frameHeight;

		private int[] frameRowStart;

		private int[] frameRowEnd;

		public Color32[] Colors => canvasColors;

		public bool FlipVertically { get; set; } = true;


		public Color32 BackgroundColor { get; set; }

		public GifCanvas()
		{
			canvasIsEmpty = true;
		}

		public GifCanvas(int width, int height)
			: this()
		{
			SetSize(width, height);
		}

		public void SetSize(int width, int height)
		{
			if (width != canvasWidth || height != canvasHeight)
			{
				int num = width * height;
				canvasColors = (Color32[])(object)new Color32[num];
				frameRowStart = new int[height];
				frameRowEnd = new int[height];
				revertDisposalBuffer = null;
				canvasWidth = width;
				canvasHeight = height;
			}
			Reset();
		}

		public void Reset()
		{
			//IL_004c: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			frameDisposalMethod = GifDisposalMethod.Keep;
			frameX = 0;
			frameY = 0;
			frameWidth = canvasWidth;
			frameHeight = canvasHeight;
			if (!canvasIsEmpty)
			{
				FillWithColor(0, 0, canvasWidth, canvasHeight, new Color32(BackgroundColor.r, BackgroundColor.g, BackgroundColor.b, (byte)0));
				canvasIsEmpty = true;
			}
		}

		public void BeginNewFrame(int x, int y, int width, int height, Color32[] palette, int transparentColorIndex, bool isInterlaced, GifDisposalMethod disposalMethod)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			switch (frameDisposalMethod)
			{
			case GifDisposalMethod.ClearToBackgroundColor:
				FillWithColor(frameX, frameY, frameWidth, frameHeight, new Color32(BackgroundColor.r, BackgroundColor.g, BackgroundColor.b, (byte)0));
				break;
			case GifDisposalMethod.Revert:
				if (disposalMethod != 0)
				{
					Array.Copy(revertDisposalBuffer, 0, canvasColors, 0, revertDisposalBuffer.Length);
				}
				break;
			}
			if (disposalMethod == GifDisposalMethod.Revert)
			{
				if (revertDisposalBuffer == null)
				{
					revertDisposalBuffer = (Color32[])(object)new Color32[canvasColors.Length];
				}
				Array.Copy(canvasColors, 0, revertDisposalBuffer, 0, revertDisposalBuffer.Length);
			}
			framePalette = palette;
			frameDisposalMethod = disposalMethod;
			canvasIsEmpty = false;
			frameWidth = width;
			frameHeight = height;
			frameX = x;
			frameY = y;
			frameCanvasPosition = 0;
			frameRowCurrent = -1;
			frameCanvasRowEndPosition = -1;
			frameTransparentColorIndex = transparentColorIndex;
			RouteFrameDrawing(x, y, width, height, isInterlaced);
		}

		public void OutputPixel(int color)
		{
			//IL_006f: 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)
			if (frameCanvasPosition >= frameCanvasRowEndPosition)
			{
				frameRowCurrent++;
				frameCanvasPosition = frameRowStart[frameRowCurrent];
				frameCanvasRowEndPosition = frameRowEnd[frameRowCurrent];
			}
			if (color != frameTransparentColorIndex)
			{
				canvasColors[frameCanvasPosition] = framePalette[color];
			}
			frameCanvasPosition++;
		}

		public void FillWithColor(int x, int y, int width, int height, Color32 color)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (width == canvasWidth && height == canvasHeight)
			{
				for (int num = canvasColors.Length - 1; num >= 0; num--)
				{
					canvasColors[num] = color;
				}
				return;
			}
			int num2;
			int num3;
			if (FlipVertically)
			{
				num2 = (canvasHeight - y) * canvasWidth + x;
				num3 = num2 - canvasWidth * height;
			}
			else
			{
				num3 = y * canvasWidth + x;
				num2 = num3 + height * canvasWidth;
			}
			for (int i = num3; i < num2; i += canvasWidth)
			{
				int num4 = i + width;
				for (int j = i; j < num4; j++)
				{
					canvasColors[j] = color;
				}
			}
		}

		private void RouteFrameDrawing(int x, int y, int width, int height, bool deinterlace)
		{
			int currentRow = 0;
			if (deinterlace)
			{
				for (int i = 0; i < height; i += 8)
				{
					ScheduleRowIndex(i);
				}
				for (int j = 4; j < height; j += 8)
				{
					ScheduleRowIndex(j);
				}
				for (int k = 2; k < height; k += 4)
				{
					ScheduleRowIndex(k);
				}
				for (int l = 1; l < height; l += 2)
				{
					ScheduleRowIndex(l);
				}
			}
			else
			{
				for (int m = 0; m < height; m++)
				{
					ScheduleRowIndex(m);
				}
			}
			void ScheduleRowIndex(int row)
			{
				int num = (FlipVertically ? ((canvasHeight - 1 - (y + row)) * canvasWidth + x) : ((y + row) * canvasWidth + x));
				frameRowStart[currentRow] = num;
				frameRowEnd[currentRow] = num + width;
				currentRow++;
			}
		}
	}
	public class GifStream : IDisposable
	{
		public enum Token
		{
			Header,
			Palette,
			GraphicsControl,
			ImageDescriptor,
			Image,
			Comment,
			PlainText,
			NetscapeExtension,
			ApplicationExtension,
			EndOfFile
		}

		private Stream currentStream;

		private long headerStartPosition;

		private long firstFrameStartPosition;

		private GifHeader header;

		private GifGraphicControl graphicControl;

		private GifImageDescriptor imageDescriptor;

		private GifCanvas canvas;

		private GifLzwDictionary lzwDictionary;

		private GifBitBlockReader blockReader;

		private Color32[] globalColorTable;

		private Color32[] localColorTable;

		private readonly byte[] headerBuffer;

		private readonly byte[] colorTableBuffer;

		private readonly byte[] extensionApplicationBuffer;

		private bool nextPaletteIsGlobal;

		private const int ExtensionBlock = 33;

		private const int ImageDescriptorBlock = 44;

		private const int EndOfFile = 59;

		private const int PlainTextLabel = 1;

		private const int GraphicControlLabel = 249;

		private const int commentLabel = 254;

		private const int applicationExtensionLabel = 255;

		public bool FlipVertically
		{
			get
			{
				return canvas.FlipVertically;
			}
			set
			{
				canvas.FlipVertically = value;
			}
		}

		public bool DrawPlainTextBackground { get; set; }

		public GifHeader Header => header;

		public bool HasMoreData => CurrentToken != Token.EndOfFile;

		public Token CurrentToken { get; private set; }

		public Stream BaseStream
		{
			get
			{
				return currentStream;
			}
			set
			{
				SetStream(value);
			}
		}

		public GifStream()
		{
			lzwDictionary = new GifLzwDictionary();
			canvas = new GifCanvas();
			blockReader = new GifBitBlockReader();
			globalColorTable = (Color32[])(object)new Color32[256];
			localColorTable = (Color32[])(object)new Color32[256];
			headerBuffer = new byte[6];
			extensionApplicationBuffer = new byte[11];
			colorTableBuffer = new byte[768];
		}

		public GifStream(Stream stream)
			: this()
		{
			SetStream(stream);
		}

		public GifStream(byte[] gifBytes)
			: this(new MemoryStream(gifBytes))
		{
		}

		public GifStream(string path)
			: this(File.OpenRead(path))
		{
		}

		public void SetStream(Stream stream, bool disposePrevious = false)
		{
			if (disposePrevious)
			{
				currentStream?.Dispose();
			}
			header = default(GifHeader);
			imageDescriptor = default(GifImageDescriptor);
			graphicControl = default(GifGraphicControl);
			currentStream = stream;
			CurrentToken = Token.Header;
			blockReader.SetStream(stream);
		}

		public void Dispose()
		{
			currentStream?.Dispose();
		}

		public void SkipToken()
		{
			switch (CurrentToken)
			{
			case Token.Header:
				ReadHeader();
				break;
			case Token.Palette:
				ReadPalette();
				break;
			case Token.GraphicsControl:
				ReadGraphicsControl();
				break;
			case Token.ImageDescriptor:
				ReadImageDescriptor();
				break;
			case Token.Image:
				ReadImage();
				break;
			case Token.Comment:
				SkipComment();
				break;
			case Token.PlainText:
				SkipPlainText();
				break;
			case Token.NetscapeExtension:
				SkipNetscapeExtension();
				break;
			case Token.ApplicationExtension:
				SkipApplicationExtension();
				break;
			default:
				throw new InvalidOperationException($"Cannot skip token {CurrentToken}");
			}
		}

		public void Reset(bool skipHeader = true, bool resetCanvas = true)
		{
			long num = ((skipHeader && firstFrameStartPosition != -1) ? firstFrameStartPosition : headerStartPosition);
			if (currentStream.Position != num)
			{
				currentStream.Position = num;
			}
			SetCurrentToken(Token.Header);
			if (resetCanvas)
			{
				canvas.Reset();
			}
		}

		public GifHeader ReadHeader()
		{
			AssertToken(Token.Header);
			headerStartPosition = currentStream.Position;
			firstFrameStartPosition = -1L;
			currentStream.Read(headerBuffer, 0, headerBuffer.Length);
			if (BitUtils.CheckString(headerBuffer, "GIF87a"))
			{
				header.version = GifVersion.Gif87a;
			}
			else
			{
				if (!BitUtils.CheckString(headerBuffer, "GIF89a"))
				{
					throw new ArgumentException("Invalid or corrupted Gif file");
				}
				header.version = GifVersion.Gif89a;
			}
			header.width = currentStream.ReadInt16LittleEndian();
			header.height = currentStream.ReadInt16LittleEndian();
			byte b = currentStream.ReadByte8();
			header.globalColorTableSize = BitUtils.GetColorTableSize(b.GetBitsFromByte(0, 3));
			header.sortColors = b.GetBitFromByte(3);
			header.colorResolution = b.GetBitsFromByte(4, 3);
			header.hasGlobalColorTable = b.GetBitFromByte(7);
			header.transparentColorIndex = currentStream.ReadByte8();
			header.pixelAspectRatio = currentStream.ReadByte8();
			canvas.SetSize(header.width, header.height);
			if (header.hasGlobalColorTable)
			{
				SetCurrentToken(Token.Palette);
				nextPaletteIsGlobal = true;
			}
			else
			{
				DetermineNextToken();
			}
			return header;
		}

		public GifPalette ReadPalette()
		{
			//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)
			AssertToken(Token.Palette);
			int num = (nextPaletteIsGlobal ? header.globalColorTableSize : imageDescriptor.localColorTableSize);
			Color32[] array = (nextPaletteIsGlobal ? globalColorTable : localColorTable);
			currentStream.Read(colorTableBuffer, 0, num * 3);
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				array[i] = new Color32(colorTableBuffer[num2++], colorTableBuffer[num2++], colorTableBuffer[num2++], byte.MaxValue);
			}
			if (nextPaletteIsGlobal)
			{
				firstFrameStartPosition = currentStream.Position;
				DetermineNextToken();
			}
			else
			{
				SetCurrentToken(Token.Image);
			}
			GifPalette result = default(GifPalette);
			result.palette = array;
			result.size = num;
			result.isGlobal = nextPaletteIsGlobal;
			return result;
		}

		public GifGraphicControl ReadGraphicsControl()
		{
			AssertToken(Token.GraphicsControl);
			currentStream.AssertByte(4);
			byte b = currentStream.ReadByte8();
			int bitsFromByte = b.GetBitsFromByte(2, 3);
			graphicControl.hasTransparency = b.GetBitFromByte(0);
			graphicControl.userInput = b.GetBitFromByte(1);
			graphicControl.delayTime = currentStream.ReadInt16LittleEndian();
			graphicControl.transparentColorIndex = currentStream.ReadByte8();
			if (!graphicControl.hasTransparency)
			{
				graphicControl.transparentColorIndex = -1;
			}
			switch (bitsFromByte)
			{
			case 0:
			case 1:
				graphicControl.disposalMethod = GifDisposalMethod.Keep;
				break;
			case 2:
				graphicControl.disposalMethod = GifDisposalMethod.ClearToBackgroundColor;
				break;
			case 3:
				graphicControl.disposalMethod = GifDisposalMethod.Revert;
				break;
			default:
				throw new ArgumentException($"Invalid disposal method type: {bitsFromByte}");
			}
			currentStream.AssertByte(0);
			DetermineNextToken();
			return graphicControl;
		}

		public GifImageDescriptor ReadImageDescriptor()
		{
			AssertToken(Token.ImageDescriptor);
			imageDescriptor.left = currentStream.ReadInt16LittleEndian();
			imageDescriptor.top = currentStream.ReadInt16LittleEndian();
			imageDescriptor.width = currentStream.ReadInt16LittleEndian();
			imageDescriptor.height = currentStream.ReadInt16LittleEndian();
			byte b = currentStream.ReadByte8();
			imageDescriptor.localColorTableSize = BitUtils.GetColorTableSize(b.GetBitsFromByte(0, 3));
			imageDescriptor.isInterlaced = b.GetBitFromByte(6);
			imageDescriptor.hasLocalColorTable = b.GetBitFromByte(7);
			if (imageDescriptor.hasLocalColorTable)
			{
				nextPaletteIsGlobal = false;
				SetCurrentToken(Token.Palette);
			}
			else
			{
				SetCurrentToken(Token.Image);
			}
			return imageDescriptor;
		}

		public GifImage ReadImage()
		{
			AssertToken(Token.Image);
			Color32[] colorTable = (imageDescriptor.hasLocalColorTable ? localColorTable : globalColorTable);
			byte b = currentStream.ReadByte8();
			if (b == 0 || b > 8)
			{
				throw new ArgumentException("Invalid lzw min code size");
			}
			DecodeLzwImageToCanvas(b, imageDescriptor.left, imageDescriptor.top, imageDescriptor.width, imageDescriptor.height, colorTable, graphicControl.transparentColorIndex, imageDescriptor.isInterlaced, graphicControl.disposalMethod);
			DetermineNextToken();
			return new GifImage
			{
				colors = canvas.Colors,
				userInput = graphicControl.userInput,
				delay = graphicControl.delayTime
			};
		}

		public string ReadComment()
		{
			AssertToken(Token.Comment);
			string @string = Encoding.ASCII.GetString(BitUtils.ReadGifBlocks(currentStream));
			DetermineNextToken();
			return @string;
		}

		public void SkipComment()
		{
			SkipBlock(Token.Comment);
		}

		public GifPlainText ReadPlainText()
		{
			//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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			AssertToken(Token.PlainText);
			currentStream.AssertByte(12);
			GifPlainText gifPlainText = default(GifPlainText);
			gifPlainText.left = currentStream.ReadInt16LittleEndian();
			gifPlainText.top = currentStream.ReadInt16LittleEndian();
			gifPlainText.width = currentStream.ReadInt16LittleEndian();
			gifPlainText.height = currentStream.ReadInt16LittleEndian();
			gifPlainText.charWidth = currentStream.ReadByte8();
			gifPlainText.charHeight = currentStream.ReadByte8();
			gifPlainText.foregroundColor = globalColorTable[currentStream.ReadByte8()];
			gifPlainText.backgroundColor = globalColorTable[currentStream.ReadByte8()];
			gifPlainText.text = Encoding.ASCII.GetString(BitUtils.ReadGifBlocks(currentStream));
			gifPlainText.colors = canvas.Colors;
			if (DrawPlainTextBackground)
			{
				FillPlainTextBackground(gifPlainText);
			}
			DetermineNextToken();
			return gifPlainText;
		}

		public void SkipPlainText()
		{
			if (DrawPlainTextBackground)
			{
				ReadPlainText();
			}
			else
			{
				SkipBlock(Token.PlainText);
			}
		}

		public GifNetscapeExtension ReadNetscapeExtension()
		{
			AssertToken(Token.NetscapeExtension);
			bool hasBufferSize = false;
			bool hasLoopCount = false;
			int loopCount = 0;
			int bufferSize = 0;
			while (true)
			{
				byte b = currentStream.ReadByte8();
				if (b == 0)
				{
					break;
				}
				switch (currentStream.ReadByte8())
				{
				case 1:
					hasLoopCount = true;
					loopCount = currentStream.ReadInt16LittleEndian();
					break;
				case 2:
					hasBufferSize = true;
					bufferSize = currentStream.ReadInt32LittleEndian();
					break;
				default:
					currentStream.Seek(b - 1, SeekOrigin.Current);
					break;
				}
			}
			DetermineNextToken();
			GifNetscapeExtension result = default(GifNetscapeExtension);
			result.hasLoopCount = hasLoopCount;
			result.hasBufferSize = hasBufferSize;
			result.loopCount = loopCount;
			result.bufferSize = bufferSize;
			return result;
		}

		public void SkipNetscapeExtension()
		{
			SkipBlock(Token.NetscapeExtension);
		}

		public GifApplicationExtension ReadApplicationExtension()
		{
			AssertToken(Token.ApplicationExtension);
			List<byte[]> list = new List<byte[]>();
			string @string = Encoding.ASCII.GetString(extensionApplicationBuffer, 0, 8);
			string string2 = Encoding.ASCII.GetString(extensionApplicationBuffer, 8, 3);
			while (true)
			{
				byte b = currentStream.ReadByte8();
				if (b == 0)
				{
					break;
				}
				byte[] array = new byte[b];
				currentStream.Read(array, 0, b);
				list.Add(array);
			}
			DetermineNextToken();
			return new GifApplicationExtension
			{
				applicationIdentifier = @string,
				applicationAuthCode = string2,
				applicationData = list.ToArray()
			};
		}

		public void SkipApplicationExtension()
		{
			SkipBlock(Token.ApplicationExtension);
		}

		private void DecodeLzwImageToCanvas(int lzwMinCodeSize, int x, int y, int width, int height, Color32[] colorTable, int transparentColorIndex, bool isInterlaced, GifDisposalMethod disposalMethod)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (header.hasGlobalColorTable)
			{
				canvas.BackgroundColor = globalColorTable[header.transparentColorIndex];
			}
			canvas.BeginNewFrame(x, y, width, height, colorTable, transparentColorIndex, isInterlaced, disposalMethod);
			lzwDictionary.InitWithWordSize(lzwMinCodeSize);
			blockReader.StartNewReading();
			lzwDictionary.DecodeStream(blockReader, canvas);
			blockReader.FinishReading();
		}

		private Token DetermineNextToken()
		{
			while (true)
			{
				byte b = currentStream.ReadByte8();
				switch (b)
				{
				case 33:
					switch (currentStream.ReadByte8())
					{
					case 254:
						return SetCurrentToken(Token.Comment);
					case 1:
						return SetCurrentToken(Token.PlainText);
					case 249:
						return SetCurrentToken(Token.GraphicsControl);
					case byte.MaxValue:
					{
						currentStream.AssertByte(11);
						currentStream.Read(extensionApplicationBuffer, 0, 11);
						Token currentToken = (BitUtils.CheckString(extensionApplicationBuffer, "NETSCAPE2.0") ? Token.NetscapeExtension : Token.ApplicationExtension);
						return SetCurrentToken(currentToken);
					}
					}
					break;
				case 44:
					return SetCurrentToken(Token.ImageDescriptor);
				case 59:
					return SetCurrentToken(Token.EndOfFile);
				default:
					throw new ArgumentException($"Unknown block type {b}");
				}
				BitUtils.SkipGifBlocks(currentStream);
			}
		}

		private Token SetCurrentToken(Token token)
		{
			CurrentToken = token;
			return token;
		}

		private void FillPlainTextBackground(GifPlainText text)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			canvas.BeginNewFrame(text.left, text.top, text.width, text.height, globalColorTable, graphicControl.transparentColorIndex, imageDescriptor.isInterlaced, graphicControl.disposalMethod);
			canvas.FillWithColor(text.left, text.top, text.width, text.height, text.backgroundColor);
		}

		private void AssertToken(Token token)
		{
			if (CurrentToken != token)
			{
				throw new InvalidOperationException($"Cannot invoke this method while current token is \"{CurrentToken}\", method should be called when token is {token}");
			}
		}

		private void SkipBlock(Token token)
		{
			AssertToken(token);
			BitUtils.SkipGifBlocks(currentStream);
			DetermineNextToken();
		}
	}
}
namespace ThreeDISevenZeroR.UnityGifDecoder.Utils
{
	public static class BitUtils
	{
		public static bool CheckString(byte[] array, string s)
		{
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] != s[i])
				{
					return false;
				}
			}
			return true;
		}

		public static int ReadInt16LittleEndian(this Stream reader)
		{
			byte b = reader.ReadByte8();
			byte b2 = reader.ReadByte8();
			return (b2 << 8) + b;
		}

		public static int ReadInt32LittleEndian(this Stream reader)
		{
			byte b = reader.ReadByte8();
			byte b2 = reader.ReadByte8();
			byte b3 = reader.ReadByte8();
			byte b4 = reader.ReadByte8();
			return (b4 << 24) + (b3 << 16) + (b2 << 8) + b;
		}

		public static byte ReadByte8(this Stream reader)
		{
			int num = reader.ReadByte();
			if (num == -1)
			{
				throw new EndOfStreamException();
			}
			return (byte)num;
		}

		public static void AssertByte(this Stream reader, int expectedValue)
		{
			byte b = reader.ReadByte8();
			if (b != expectedValue)
			{
				throw new ArgumentException($"Invalid byte, expected {expectedValue}, got {b}");
			}
		}

		public static int GetColorTableSize(int data)
		{
			return 1 << data + 1;
		}

		public static int GetBitsFromByte(this byte b, int offset, int count)
		{
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				num += (b.GetBitFromByte(offset + i) ? 1 : 0) << i;
			}
			return num;
		}

		public static bool GetBitFromByte(this byte b, int offset)
		{
			return (b & (1 << offset)) != 0;
		}

		public static byte[] ReadGifBlocks(Stream reader)
		{
			List<byte> list = new List<byte>();
			while (true)
			{
				byte b = reader.ReadByte8();
				if (b == 0)
				{
					break;
				}
				byte[] array = new byte[b];
				reader.Read(array, 0, array.Length);
				list.AddRange(array);
			}
			return list.ToArray();
		}

		public static void SkipGifBlocks(Stream reader)
		{
			while (true)
			{
				byte b = reader.ReadByte8();
				if (b == 0)
				{
					break;
				}
				reader.Seek(b, SeekOrigin.Current);
			}
		}
	}
}
namespace ThreeDISevenZeroR.UnityGifDecoder.Model
{
	public class GifApplicationExtension
	{
		public string applicationIdentifier;

		public string applicationAuthCode;

		public byte[][] applicationData;
	}
	public enum GifDisposalMethod
	{
		Keep,
		ClearToBackgroundColor,
		Revert
	}
	public struct GifGraphicControl
	{
		public bool userInput;

		public GifDisposalMethod disposalMethod;

		public int delayTime;

		public bool hasTransparency;

		public int transparentColorIndex;
	}
	public struct GifHeader
	{
		public GifVersion version;

		public int width;

		public int height;

		public bool hasGlobalColorTable;

		public int globalColorTableSize;

		public int transparentColorIndex;

		public bool sortColors;

		public int colorResolution;

		public int pixelAspectRatio;
	}
	public class GifImage
	{
		public bool userInput;

		public Color32[] colors;

		public int delay;

		public int DelayMs => delay * 10;

		public float SafeDelayMs => (delay > 1) ? DelayMs : 100;

		public float DelaySeconds => (float)delay / 100f;

		public float SafeDelaySeconds => SafeDelayMs / 1000f;
	}
	public struct GifImageDescriptor
	{
		public int left;

		public int top;

		public int width;

		public int height;

		public bool isInterlaced;

		public bool hasLocalColorTable;

		public int localColorTableSize;
	}
	public struct GifNetscapeExtension
	{
		public bool hasLoopCount;

		public bool hasBufferSize;

		public int loopCount;

		public int bufferSize;
	}
	public struct GifPalette
	{
		public Color32[] palette;

		public int size;

		public bool isGlobal;
	}
	public struct GifPlainText
	{
		public int left;

		public int top;

		public int width;

		public int height;

		public int charWidth;

		public int charHeight;

		public Color32 backgroundColor;

		public Color32 foregroundColor;

		public string text;

		public Color32[] colors;
	}
	public enum GifVersion
	{
		Gif89a,
		Gif87a
	}
}
namespace ThreeDISevenZeroR.UnityGifDecoder.Decode
{
	public class GifLzwDictionary
	{
		private readonly int[] dictionaryEntryOffsets;

		private readonly int[] dictionaryEntrySizes;

		private byte[] dictionaryHeap;

		private int dictionarySize;

		private int dictionaryHeapPosition;

		private int initialDictionarySize;

		private int initialLzwCodeSize;

		private int initialDictionaryHeapPosition;

		private int nextLzwCodeGrowth;

		private int currentMinLzwCodeSize;

		private int codeSize;

		private int clearCodeId;

		private int stopCodeId;

		private int lastCodeId;

		private bool isFull;

		public GifLzwDictionary()
		{
			dictionaryEntryOffsets = new int[4096];
			dictionaryEntrySizes = new int[4096];
			dictionaryHeap = new byte[32768];
		}

		public void InitWithWordSize(int minLzwCodeSize)
		{
			if (currentMinLzwCodeSize != minLzwCodeSize)
			{
				currentMinLzwCodeSize = minLzwCodeSize;
				dictionaryHeapPosition = 0;
				dictionarySize = 0;
				int num = 1 << minLzwCodeSize;
				for (int i = 0; i < num; i++)
				{
					dictionaryEntryOffsets[i] = dictionaryHeapPosition;
					dictionaryEntrySizes[i] = 1;
					dictionaryHeap[dictionaryHeapPosition++] = (byte)i;
				}
				initialDictionarySize = num + 2;
				initialLzwCodeSize = minLzwCodeSize + 1;
				initialDictionaryHeapPosition = dictionaryHeapPosition;
				clearCodeId = num;
				stopCodeId = num + 1;
			}
			Clear();
		}

		public void Clear()
		{
			codeSize = initialLzwCodeSize;
			dictionarySize = initialDictionarySize;
			dictionaryHeapPosition = initialDictionaryHeapPosition;
			nextLzwCodeGrowth = 1 << codeSize;
			isFull = false;
			lastCodeId = -1;
		}

		public void DecodeStream(GifBitBlockReader reader, GifCanvas c)
		{
			while (true)
			{
				int num = reader.ReadBits(codeSize);
				if (num == clearCodeId)
				{
					Clear();
					continue;
				}
				if (num == stopCodeId)
				{
					break;
				}
				if (num < dictionarySize)
				{
					if (lastCodeId >= 0)
					{
						CreateNewCode(lastCodeId, num);
					}
					lastCodeId = num;
				}
				else
				{
					lastCodeId = CreateNewCode(lastCodeId, lastCodeId);
				}
				int num2 = dictionaryEntryOffsets[lastCodeId];
				int num3 = dictionaryEntrySizes[lastCodeId];
				int num4 = num2 + num3;
				for (int i = num2; i < num4; i++)
				{
					c.OutputPixel(dictionaryHeap[i]);
				}
			}
		}

		public int CreateNewCode(int baseEntry, int deriveEntry)
		{
			if (isFull)
			{
				return -1;
			}
			int num = dictionaryEntryOffsets[baseEntry];
			int num2 = dictionaryEntrySizes[baseEntry];
			int num3 = dictionaryHeapPosition;
			int num4 = num2 + 1;
			int num5 = num3 + num4;
			if (dictionaryHeap.Length < num5)
			{
				Array.Resize(ref dictionaryHeap, Math.Max(dictionaryHeap.Length * 2, num5));
			}
			if (num2 < 12)
			{
				int num6 = num + num2;
				for (int i = num; i < num6; i++)
				{
					dictionaryHeap[dictionaryHeapPosition++] = dictionaryHeap[i];
				}
			}
			else
			{
				Buffer.BlockCopy(dictionaryHeap, num, dictionaryHeap, dictionaryHeapPosition, num2);
				dictionaryHeapPosition += num2;
			}
			dictionaryHeap[dictionaryHeapPosition++] = ((deriveEntry < initialDictionarySize) ? ((byte)deriveEntry) : dictionaryHeap[dictionaryEntryOffsets[deriveEntry]]);
			int num7 = dictionarySize++;
			dictionaryEntryOffsets[num7] = num3;
			dictionaryEntrySizes[num7] = num4;
			if (dictionarySize >= nextLzwCodeGrowth)
			{
				codeSize++;
				nextLzwCodeGrowth = ((codeSize == 12) ? int.MaxValue : (1 << codeSize));
			}
			if (dictionarySize >= 4096)
			{
				isFull = true;
			}
			return num7;
		}
	}
}
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.CreatePicture(ref pictureData, MainClass.photoAlbum.transform);
			return pictureData;
		}

		public static void DeletePicture(PictureData pictureData)
		{
			MainClass.deletePicture(pictureData, keepFile: true);
		}
	}
	public class MainClass : MelonMod
	{
		private class FrameData
		{
			public Texture2D texture;

			public WaitForSeconds delay;
		}

		private class GifData
		{
			public Renderer renderer;

			public GifStream gifStream;

			public FrameData firstFrame;

			public string path;
		}

		[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 <ListenForFlatLandButton>d__112 : IEnumerator<WaitForSeconds>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private WaitForSeconds <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					GameObject.Find("FlatLand/FlatLandButton/Button").GetComponent<InteractionButton>().onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
					{
						MelonCoroutines.Start((IEnumerator)OnFlatLandEntered());
					}));
					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();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadAlbum>d__13 : 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 WaitForSeconds <wait>5__3;

			private JArray <cleanedAlbum>5__4;

			private string <json>5__5;

			private Exception <ex>5__6;

			private IEnumerator<JToken> <>s__7;

			private JToken <entry>5__8;

			private PictureData <pictureData>5__9;

			private Exception <ex>5__10;

			private Exception <ex>5__11;

			private Exception <ex>5__12;

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

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

			[DebuggerHidden]
			public <LoadAlbum>d__13(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;
				<wait>5__3 = null;
				<cleanedAlbum>5__4 = null;
				<json>5__5 = null;
				<ex>5__6 = null;
				<>s__7 = null;
				<entry>5__8 = null;
				<pictureData>5__9 = null;
				<ex>5__10 = null;
				<ex>5__11 = null;
				<ex>5__12 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0408: Expected O, but got Unknown
				//IL_0421: Unknown result type (might be due to invalid IL or missing references)
				//IL_042b: Expected O, but got Unknown
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Expected O, but got Unknown
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Expected O, but got Unknown
				//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: Expected O, but got Unknown
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Invalid comparison between Unknown and I4
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Expected O, but got Unknown
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Expected O, but got Unknown
				//IL_013d: 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");
						gifsLoading = false;
						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__5 = File.ReadAllText(fullPath);
								root = JObject.Parse(<json>5__5);
								<json>5__5 = 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__6 = ex;
							LogError("Failed to load or parse config.json: " + <ex>5__6.Message);
						}
						if (<album>5__1 == null || <sceneObj>5__2 == null)
						{
							return false;
						}
						<wait>5__3 = new WaitForSeconds(spawningFrequency);
						gifs = new List<GifData>();
						gifsPlaying = false;
						gifsLoading = true;
						<cleanedAlbum>5__4 = new JArray();
						<>s__7 = <album>5__1.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<pictureData>5__9 = null;
						<entry>5__8 = null;
						break;
					}
					while (<>s__7.MoveNext())
					{
						<entry>5__8 = <>s__7.Current;
						<pictureData>5__9 = null;
						try
						{
							<pictureData>5__9 = ParsePictureData(<entry>5__8);
							Log("Creating picture " + <pictureData>5__9.path);
							if (<pictureData>5__9 == null)
							{
								continue;
							}
						}
						catch (Exception ex)
						{
							<ex>5__10 = ex;
							LogError("Failed to parse entry: " + <ex>5__10.Message);
							continue;
						}
						try
						{
							CreatePicture(ref <pictureData>5__9, photoAlbum.transform);
							<cleanedAlbum>5__4.Add(<entry>5__8);
							<pictureData>5__9.jsonConfig = <cleanedAlbum>5__4[((JContainer)<cleanedAlbum>5__4).Count - 1];
						}
						catch (Exception ex)
						{
							<ex>5__11 = ex;
							LogError("Failed to parse entry: " + <ex>5__11.Message);
							if (<ex>5__11.Message != "file doesn't exist")
							{
								<cleanedAlbum>5__4.Add(<entry>5__8);
								<pictureData>5__9.jsonConfig = <cleanedAlbum>5__4[((JContainer)<cleanedAlbum>5__4).Count - 1];
							}
							continue;
						}
						<>2__current = <wait>5__3;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__7 = null;
					gifsPlaying = true;
					MelonCoroutines.Start((IEnumerator)PlayAllGifs());
					try
					{
						reloadStash();
						<sceneObj>5__2[(object)"album"] = (JToken)(object)<cleanedAlbum>5__4;
						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__12 = ex;
						LogError("Failed to update configuration file: " + <ex>5__12.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__7 != null)
				{
					<>s__7.Dispose();
				}
			}

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

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

			private WaitForSeconds <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Log("Loading into FlatLand");
					<>2__current = new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					currentScene = "FlatLand";
					initializeInteractionObjects();
					MelonCoroutines.Start((IEnumerator)LoadAlbum(currentScene));
					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();
			}
		}

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

			private WaitForSeconds <>2__current;

			private WaitForSeconds <wait>5__1;

			private int <gifIndex>5__2;

			private GifData <gifData>5__3;

			private List<FrameData> <frames>5__4;

			private int <index>5__5;

			private FrameData <frame>5__6;

			private Exception <ex>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<wait>5__1 = null;
				<gifData>5__3 = null;
				<frames>5__4 = null;
				<frame>5__6 = null;
				<ex>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (gifs == null || gifs.Count == 0)
					{
						gifsLoading = false;
						return false;
					}
					Log("Starting coroutine to load all gifs");
					<wait>5__1 = new WaitForSeconds(gifDecodingFrequency);
					<gifIndex>5__2 = 0;
					goto IL_0204;
				case 1:
					<>1__state = -1;
					<frame>5__6 = ReadGifFrame(<gifData>5__3.gifStream);
					if (<frame>5__6 != null)
					{
						<frames>5__4.Add(<frame>5__6);
					}
					<frame>5__6 = null;
					goto IL_011a;
				case 2:
					{
						<>1__state = -1;
						<gifData>5__3 = null;
						<frames>5__4 = null;
						goto IL_0204;
					}
					IL_0204:
					if (!gifsPlaying || gifs == null || <gifIndex>5__2 >= gifs.Count)
					{
						break;
					}
					<gifData>5__3 = gifs[<gifIndex>5__2];
					<frames>5__4 = new List<FrameData>();
					<frames>5__4.Add(<gifData>5__3.firstFrame);
					<index>5__5 = 0;
					goto IL_011a;
					IL_011a:
					if (<gifData>5__3.gifStream.HasMoreData)
					{
						<>2__current = <wait>5__1;
						<>1__state = 1;
						return true;
					}
					try
					{
						if (<gifData>5__3.renderer != null)
						{
							Object.Destroy((Object)(object)((Component)((Component)<gifData>5__3.renderer).gameObject.transform.parent.GetChild(2)).gameObject);
							Log("Starting coroutine to play gif: " + <gifData>5__3.path);
							MelonCoroutines.Start((IEnumerator)PlayGif(<gifData>5__3.renderer, <frames>5__4, <gifData>5__3.path));
						}
					}
					catch (Exception ex)
					{
						<ex>5__7 = ex;
					}
					<gifIndex>5__2++;
					<>2__current = <wait>5__1;
					<>1__state = 2;
					return true;
				}
				if (<gifIndex>5__2 == gifs.Count)
				{
					gifs = new List<GifData>();
				}
				gifsLoading = false;
				Log("Stopping coroutine to load all gifs");
				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();
			}
		}

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

			private WaitForSeconds <>2__current;

			public Renderer renderer;

			public List<FrameData> frames;

			public string path;

			private int <i>5__1;

			private FrameData <frame>5__2;

			private Exception <ex>5__3;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<frame>5__2 = null;
				<ex>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__1 = 0;
					break;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					<i>5__1 = (<i>5__1 + 1) % frames.Count;
					<frame>5__2 = null;
					break;
				}
				if (gifsPlaying)
				{
					<frame>5__2 = frames[<i>5__1];
					if ((Object)(object)<frame>5__2.texture == (Object)null)
					{
						<i>5__1 = (<i>5__1 + 1) % frames.Count;
						<>2__current = <frame>5__2.delay;
						<>1__state = 1;
						return true;
					}
					try
					{
						renderer.material.SetTexture("_Albedo", (Texture)(object)<frame>5__2.texture);
					}
					catch (Exception ex)
					{
						<ex>5__3 = ex;
					}
					<>2__current = <frame>5__2.delay;
					<>1__state = 2;
					return true;
				}
				Log("Stopping coroutine to play gif: " + path);
				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();
			}
		}

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

			private WaitForSeconds <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0084: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Expected O, but got Unknown
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Expected O, but got Unknown
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Expected O, but got Unknown
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					mailTubePicture = new PictureData();
					mailTubePicture.path = ((object)stashJson[0]).ToString();
					stashJson.RemoveAt(0);
					mailTubePicture.padding = defaultPadding;
					mailTubePicture.thickness = defaultThickness;
					mailTubePicture.color = defaultColor;
					mailTubePicture.rotation = new Vector3(0f, 180f, 0f);
					mailTubePicture.jsonConfig = (JToken)new JObject();
					mailTubePicture.jsonConfig[(object)"path"] = JToken.op_Implicit(mailTubePicture.path);
					CreatePicture(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 static List<GifData> gifs = null;

		private static bool gifsLoading = false;

		private static bool gifsPlaying = false;

		private static float gifSpeed = 1f;

		private static float spawningFrequency = 0.02f;

		private static float gifDecodingFrequency = 0.01f;

		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 = new PictureData[2];

		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 bool flatlandFound = false;

		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__13))]
		private static IEnumerator<WaitForSeconds> LoadAlbum(string sceneName)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAlbum>d__13(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") || f.EndsWith(".gif")
				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 CreatePicture(ref PictureData pictureData, Transform parent)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			string text = pictureData.path;
			if (!File.Exists(text))
			{
				string text2 = Path.Combine(Application.dataPath, "..", "UserData/RumblePhotoAlbum", "pictures", pictureData.path);
				if (!File.Exists(text2))
				{
					throw new Exception("file doesn't exist");
				}
				text = text2;
			}
			if (pictureData.path.EndsWith(".gif", StringComparison.OrdinalIgnoreCase))
			{
				CreateGifBlock(text, ref pictureData, parent);
				return;
			}
			Texture2D val = null;
			val = ((!pictureData.alpha) ? LoadTexture(text) : LoadFlattenedTexture(text, pictureData.color));
			CreatePictureBlock(ref pictureData, parent, val);
		}

		private static Renderer CreatePictureBlock(ref PictureData pictureData, Transform parent, Texture2D imageTexture)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: 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_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			int layer = (pictureData.visible ? LayerMask.NameToLayer("UI") : LayerMask.NameToLayer("PlayerFade"));
			float num = (float)((Texture)imageTexture).height / (float)((Texture)imageTexture).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 val = new GameObject();
			val.layer = layer;
			((Object)val).name = "PictureBlock: " + Path.GetFileNameWithoutExtension(pictureData.path);
			val.transform.SetParent(parent, false);
			val.transform.localPosition = pictureData.position;
			val.transform.localRotation = Quaternion.Euler(pictureData.rotation);
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			val2.layer = layer;
			((Object)val2).name = "frame";
			val2.transform.SetParent(val.transform, false);
			val2.transform.localScale = new Vector3(pictureData.width, pictureData.height, pictureData.thickness);
			val2.transform.localPosition = new Vector3(0f, 0f, pictureData.thickness / 2f);
			Renderer component = val2.GetComponent<Renderer>();
			component.material.shader = Shader.Find("Shader Graphs/RUMBLE_Prop");
			component.material.SetColor("_Overlay", pictureData.color);
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)5);
			val3.layer = layer;
			((Object)val3).name = "picture";
			val3.transform.SetParent(val.transform, false);
			val3.transform.localScale = new Vector3(pictureData.width - 2f * pictureData.padding, pictureData.height - 2f * pictureData.padding, 1f);
			val3.transform.localPosition = new Vector3(0f, 0f, -0.001f);
			val3.transform.localRotation = Quaternion.identity;
			Renderer component2 = val3.GetComponent<Renderer>();
			component2.material.shader = Shader.Find("Shader Graphs/RUMBLE_Prop");
			component2.material.SetTexture("_Albedo", (Texture)(object)imageTexture);
			pictureData.obj = val;
			pictureData = pictureData;
			PicturesList.Add(pictureData);
			CreateActionButtons(pictureData);
			return component2;
		}

		private static void CreateGifBlock(string filePath, ref PictureData pictureData, Transform parent)
		{
			//IL_005f: 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_00c8: 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)
			GifStream gifStream = new GifStream(filePath);
			FrameData frameData = null;
			while (frameData == null && gifStream.HasMoreData)
			{
				frameData = ReadGifFrame(gifStream);
			}
			Renderer val = CreatePictureBlock(ref pictureData, parent, frameData.texture);
			GameObject val2 = Create.NewText();
			TextMeshPro component = val2.GetComponent<TextMeshPro>();
			((TMP_Text)component).text = "Loading...";
			((TMP_Text)component).fontSize = 1f;
			((Graphic)component).color = Color.black;
			((Object)val2).name = "loadingText";
			val2.transform.SetParent(((Component)val).gameObject.transform.parent, true);
			val2.transform.localPosition = new Vector3(0f, 0f, -0.002f);
			val2.transform.localRotation = Quaternion.Euler(new Vector3(0f, 0f, 0f));
			if (gifs != null)
			{
				gifs.Add(new GifData
				{
					renderer = val,
					gifStream = gifStream,
					firstFrame = frameData,
					path = pictureData.path
				});
				if (!gifsLoading)
				{
					gifsLoading = true;
					gifsPlaying = true;
					MelonCoroutines.Start((IEnumerator)PlayAllGifs());
				}
			}
		}

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

		[IteratorStateMachine(typeof(<PlayGif>d__25))]
		private static IEnumerator<WaitForSeconds> PlayGif(Renderer renderer, List<FrameData> frames, string path)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PlayGif>d__25(0)
			{
				renderer = renderer,
				frames = frames,
				path = path
			};
		}

		private static FrameData ReadGifFrame(GifStream gifStream)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			switch (gifStream.CurrentToken)
			{
			case GifStream.Token.Image:
			{
				GifImage gifImage = gifStream.ReadImage();
				Texture2D val = new Texture2D(gifStream.Header.width, gifStream.Header.height, (TextureFormat)5, false);
				val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit(gifImage.colors));
				val.Apply();
				float num = gifImage.SafeDelaySeconds / gifSpeed - 0.01f;
				if (num < 0.001f)
				{
					num = 0.001f;
				}
				return new FrameData
				{
					texture = val,
					delay = new WaitForSeconds(num)
				};
			}
			default:
				gifStream.SkipToken();
				break;
			case GifStream.Token.EndOfFile:
				break;
			}
			return null;
		}

		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
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			Mod.ModName = "RumblePhotoAlbum";
			Mod.ModVersion = "1.2.3";
			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.AddToList("Picture creation frequency", 0.02f, "How long to wait between picture spawning during the scene initialization. The bigger the number, the longer it will take for all the pictures to appear!.", new Tags());
			Mod.AddToList("GIF playing speed", 1f, "The hardcoded mimimum delay between frames is 1000ms, so there is a maximum speed.", new Tags());
			Mod.AddToList("GIF decoding frequency", 0.01f, "How long to wait between parsing two consecutives frames in a GIF. Smaller number means faster loading, but also higher performance impact during scene initialization.", 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;
			spawningFrequency = (float)Mod.Settings[7].SavedValue;
			gifSpeed = (float)Mod.Settings[8].SavedValue;
			gifDecodingFrequency = (float)Mod.Settings[9].SavedValue;
		}

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

		private static void InitGrabbing()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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[0] = null;
			currentlyModified[1] = null;
			resizingHandle = new GameObject("ResizingHandle");
			resizingHandle.transform.SetParent(child, true);
		}

		private static void ProcessGrabbing()
		{
			if (!ProcessGrabbingPerHand(0) && !ProcessGrabbingPerHand(1))
			{
				return;
			}
			bool flag = currentlyModified[0] == currentlyModified[1];
			for (int i = 0; i < 2; i++)
			{
				if (currentlyModified[i] == null)
				{
					continue;
				}
				PictureData pictureData = currentlyModified[i];
				UpdatePictureParent(pictureData);
				GameObject gameObject = ((Component)pictureData.obj.transform.GetChild(0).GetChild(0)).gameObject;
				if (!holding[i])
				{
					if (!flag || !holding[1 - i])
					{
						gameObject.SetActive(false);
						if (flag)
						{
							currentlyModified[1 - i] = null;
						}
					}
					currentlyModified[i] = null;
				}
				else if (!flag && holding[1 - i])
				{
					gameObject.SetActive(false);
				}
				else
				{
					gameObject.SetActive(true);
				}
			}
		}

		private static bool ProcessGrabbingPerHand(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;
			}
			bool flag = false;
			if (currentlyModified[1 - index] != null)
			{
				float num = DistanceToPictureSurface(hand[index], currentlyModified[1 - index]);
				holding[index] = num < 0.05f;
				if (num < 0.05f)
				{
					currentlyModified[index] = currentlyModified[1 - index];
					flag = true;
				}
			}
			if (flag)
			{
				return;
			}
			float num2 = 0.05f;
			int num3 = -1;
			for (int i = 0; i < PicturesList.Count; i++)
			{
				PictureData pictureData = PicturesList[i];
				if (pictureData.obj == null)
				{
					LogWarn("Framed picture " + pictureData.path + " has no GameObject associated with it.");
					continue;
				}
				float num4 = DistanceToPictureSurface(hand[index], pictureData);
				if (num4 < num2)
				{
					holding[index] = true;
					num2 = num4;
					num3 = i;
				}
			}
			if (num3 != -1)
			{
				PictureData pictureData2 = PicturesList[num3];
				currentlyModified[index] = pictureData2;
				if (buttonsVisibility)
				{
					GameObject gameObject = ((Component)pictureData2.obj.transform.GetChild(0).GetChild(0)).gameObject;
					gameObject.SetActive(true);
				}
				if (pictureData2 == mailTubePicture)
				{
					mailTubePicture = null;
					albumJson.Add(pictureData2.jsonConfig);
				}
				if (pictureData2 == rockCamPicture)
				{
					rockCamPicture = null;
					albumJson.Add(pictureData2.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] && currentlyModified[0] == pictureData)
			{
				if (holding[1] && currentlyModified[1] == pictureData)
				{
					UpdateResizingHandle();
					pictureData.obj.transform.SetParent(resizingHandle.transform, true);
				}
				else
				{
					pictureData.obj.transform.SetParent(hand[0].transform, true);
				}
			}
			else if (holding[1] && currentlyModified[1] == pictureData)
			{
				pictureData.obj.transform.SetParent(hand[1].transform, true);
			}
			else
			{
				pictureData.obj.transform.SetParent(photoAlbum.transform, true);
				UpdatePictureConfig(pictureData);
			}
		}

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

		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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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[0].obj.transform.localScale.x * num;
			Transform child = currentlyModified[0].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();
			}
			else if (currentScene == "FlatLand")
			{
				initializeFlatLandObjects();
			}
			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.Ge