Decompiled source of CustomStamps v0.1.0

plugins/CustomStamps.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using CatLib.Assets;
using CatLib.Config;
using CatLib.DevTools;
using CatLib.Localization;
using CatLib.Logging;
using CatLib.Net;
using CatLib.Patching;
using CatLib.Threading;
using CatLib.UI;
using CustomStamps.Game;
using CustomStamps.Packs;
using CustomStamps.Patches;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CatLib contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+1b73f398a8bbe07fec967f69ef1e969788e687bd")]
[assembly: AssemblyProduct("CatLib")]
[assembly: AssemblyTitle("CustomStamps")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CustomStamps
{
	[BepInPlugin("catlib.customstamps", "Custom Stamps", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class CustomStampsPlugin : BasePlugin
	{
		public const string PacksSection = "Packs";

		public const string DevGroup = "Custom Stamps";

		public static StampLibrary Library { get; private set; }

		public static StampFactory Factory { get; private set; }

		public static StampSelection Selection { get; private set; }

		public override void Load()
		{
			CatLogger log = CatLogger.From(((BasePlugin)this).Log);
			CatSettings val = CatSettings.For((BasePlugin)(object)this);
			TextCatalog texts = val.Texts;
			CatNetwork.Declare((BasePlugin)(object)this, (SessionPolicy)3, (VersionRule)2);
			StampLibrary library = new StampLibrary(log, texts, "0.1.0");
			StampFactory factory = new StampFactory(log);
			StampSelection selection = new StampSelection(library, factory, log);
			Library = library;
			Factory = factory;
			Selection = selection;
			CatPatches patches = StampPatches.Install("catlib.customstamps", selection, log);
			library.Changed += Refresh;
			CatNetwork.ActiveModsChanged += Refresh;
			val.Button("Packs", "Create", (Action)delegate
			{
				string text = library.CreatePack();
				library.Load();
				ContentPacks.OpenFolder(text);
				Notifications.Show(texts.FormatFor(CatLanguage.Current, "stamps.Created", new object[1] { Path.GetFileName(text) }), (string)null);
			}, (string)null);
			val.Button("Packs", "Reload", (Action)delegate
			{
				library.Load();
				Notifications.Show(texts.PluralFor(CatLanguage.Current, "stamps.Reloaded", (long)library.Packs.Count, Array.Empty<object>()), (string)null);
			}, (string)null);
			val.Button("Packs", "Folder", (Action)delegate
			{
				ContentPacks.OpenFolder(ContentPacks.PluginsFolder);
			}, (string)null);
			library.Load();
			DevMenu.Command("Custom Stamps", "Game stamps in the log", (Func<string>)delegate
			{
				string text = factory.DescribeBase(StampKind.Decorative) + "\n" + factory.DescribeBase(StampKind.Weight);
				log.Info("[Stamps] " + text);
				return text.Split('\n')[0];
			}, "Writes how the game's decorative and weight stamps are made: their prefab, materials and textures. Open a level first.");
			DevMenu.Command("Custom Stamps", "Custom stamps in the log", (Func<string>)delegate
			{
				List<string> list = library.Stamps.Select((CustomStamp stamp) => $"{stamp.Key}: {stamp.Image.Width}x{stamp.Image.Height}, {(stamp.IsActive ? "active" : "paused")}").ToList();
				log.Info($"[Stamps] {library.Packs.Count} pack(s), {library.Stamps.Count} stamp(s), {factory.Built} made for the game" + ((list.Count == 0) ? string.Empty : (":\n" + string.Join("\n", list))));
				return $"{library.Packs.Count} pack(s), {library.Stamps.Count} stamp(s)";
			}, "Writes every custom stamp, its size and whether it is used in this session.");
			log.Info($"Custom Stamps {"0.1.0"} loaded with {texts.Count} translated text(s) in {string.Join(", ", texts.Languages)}, {library.Packs.Count} stamp pack(s) in {ContentPacks.PluginsFolder}" + (patches.IsActive ? string.Empty : ", the game's stamps are left as they are"));
			void Refresh()
			{
				MainThread.Post((Action)delegate
				{
					patches.Run("Refresh", (Action)selection.Refresh);
				});
			}
		}
	}
	public static class PluginMeta
	{
		public const string Guid = "catlib.customstamps";

		public const string Name = "Custom Stamps";

		public const string Version = "0.1.0";
	}
}
namespace CustomStamps.Patches
{
	public static class StampPatches
	{
		private static StampSelection _selection;

		public static CatPatches Group { get; private set; }

		public static CatPatches Install(string ownerId, StampSelection selection, CatLogger log)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_selection = selection;
			Group = new CatPatches(ownerId, log).Postfix(typeof(StampSelectionCategoryInterface), "Populate", Type.EmptyTypes, typeof(StampPatches), "PopulatePostfix").Prefix(typeof(EntityInteractableStamp), "AddStampFromNetwork", new Type[5]
			{
				typeof(string),
				typeof(int),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(bool)
			}, typeof(StampPatches), "AddFromNetworkPrefix");
			Group.Apply();
			return Group;
		}

		private static void PopulatePostfix(StampSelectionCategoryInterface __instance)
		{
			if (Group == null || !Group.IsActive)
			{
				return;
			}
			try
			{
				_selection.AfterPopulate(__instance);
			}
			catch (Exception ex)
			{
				Group.Fault("PopulatePostfix", ex);
			}
		}

		private static bool AddFromNetworkPrefix(EntityInteractableStamp __instance, string __0, int __1, Vector3 __2, Quaternion __3, bool __4)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (Group == null || !Group.IsActive)
			{
				return true;
			}
			try
			{
				return !_selection.PlaceFromNetwork(__instance, __0, __1, __2, __3, __4);
			}
			catch (Exception ex)
			{
				Group.Fault("AddFromNetworkPrefix", ex);
				return !StampFiles.IsCustomKey(__0);
			}
		}
	}
}
namespace CustomStamps.Packs
{
	public enum StampKind
	{
		Decorative,
		Weight
	}
	public sealed class CustomStamp
	{
		public ContentPack Pack { get; }

		public StampKind Kind { get; }

		public string Path { get; }

		public string Key { get; }

		public ImageData Image { get; }

		public Texture2D Texture { get; internal set; }

		public Sprite Preview { get; internal set; }

		public bool IsReady
		{
			get
			{
				if ((Object)(object)Texture != (Object)null && !((Il2CppObjectBase)Texture).WasCollected && (Object)(object)Preview != (Object)null)
				{
					return !((Il2CppObjectBase)Preview).WasCollected;
				}
				return false;
			}
		}

		public bool IsActive => Pack.IsActive;

		public CustomStamp(ContentPack pack, StampKind kind, string path, string key, ImageData image)
		{
			Pack = pack;
			Kind = kind;
			Path = path;
			Key = key;
			Image = image;
		}

		public override string ToString()
		{
			return Key;
		}
	}
	public static class StampFiles
	{
		public const string PackFile = "stamps.txt";

		public const string DecorativeFolder = "decorative";

		public const string WeightFolder = "weight";

		public const string IconFile = "icon.png";

		public const string KeyPrefix = "CustomStamps/";

		public const int MaxPerKind = 64;

		public const string NotSupported = "NotSupported";

		public const string TooMany = "TooMany";

		private static readonly HashSet<string> Images = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".jpg", ".jpeg" };

		private static readonly HashSet<string> OtherImages = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".gif", ".bmp", ".webp", ".tga", ".psd", ".tif", ".tiff", ".heic", ".avif" };

		public static string FolderOf(StampKind kind)
		{
			if (kind != StampKind.Weight)
			{
				return "decorative";
			}
			return "weight";
		}

		public static List<(StampKind Kind, string Path)> Find(string packFolder, List<(string File, string Reason)> skipped)
		{
			List<(StampKind, string)> list = new List<(StampKind, string)>();
			AddFolder(list, skipped, StampKind.Decorative, packFolder, root: true);
			AddFolder(list, skipped, StampKind.Decorative, Path.Combine(packFolder, "decorative"), root: false);
			AddFolder(list, skipped, StampKind.Weight, Path.Combine(packFolder, "weight"), root: false);
			return list;
		}

		public static string Key(string packId, StampKind kind, string path)
		{
			int num = packId.IndexOf('.');
			string text = ((num >= 0) ? packId.Substring(num + 1) : packId);
			return "CustomStamps/" + text + "/" + FolderOf(kind) + "/" + Clean(Path.GetFileNameWithoutExtension(path));
		}

		public static bool IsCustomKey(string key)
		{
			return key?.StartsWith("CustomStamps/", StringComparison.Ordinal) ?? false;
		}

		public static int Compare(string left, string right)
		{
			string text = Path.GetFileNameWithoutExtension(left) ?? string.Empty;
			string text2 = Path.GetFileNameWithoutExtension(right) ?? string.Empty;
			int i = 0;
			int j = 0;
			while (i < text.Length && j < text2.Length)
			{
				if (char.IsDigit(text[i]) && char.IsDigit(text2[j]))
				{
					int num = i;
					int num2 = j;
					for (; i < text.Length && char.IsDigit(text[i]); i++)
					{
					}
					for (; j < text2.Length && char.IsDigit(text2[j]); j++)
					{
					}
					string text3 = text.Substring(num, i - num).TrimStart('0');
					string text4 = text2.Substring(num2, j - num2).TrimStart('0');
					int num3 = text3.Length.CompareTo(text4.Length);
					if (num3 != 0)
					{
						return num3;
					}
					int num4 = string.CompareOrdinal(text3, text4);
					if (num4 != 0)
					{
						return num4;
					}
				}
				else
				{
					int num5 = char.ToLowerInvariant(text[i]).CompareTo(char.ToLowerInvariant(text2[j]));
					if (num5 != 0)
					{
						return num5;
					}
					i++;
					j++;
				}
			}
			return (text.Length - i).CompareTo(text2.Length - j);
		}

		private static void AddFolder(List<(StampKind, string)> found, List<(string File, string Reason)> skipped, StampKind kind, string folder, bool root)
		{
			if (!Directory.Exists(folder))
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (string item in Directory.EnumerateFiles(folder))
			{
				string fileName = Path.GetFileName(item);
				string extension = Path.GetExtension(item);
				if (!root || !string.Equals(fileName, "icon.png", StringComparison.OrdinalIgnoreCase))
				{
					if (Images.Contains(extension))
					{
						list.Add(item);
					}
					else if (OtherImages.Contains(extension))
					{
						skipped?.Add((Relative(folder, item, root), "NotSupported"));
					}
				}
			}
			list.Sort(Compare);
			int num = found.Count(((StampKind, string) entry) => entry.Item1 == kind);
			foreach (string item2 in list)
			{
				if (num >= 64)
				{
					skipped?.Add((Relative(folder, item2, root), "TooMany"));
					continue;
				}
				found.Add((kind, item2));
				num++;
			}
		}

		private static string Relative(string folder, string file, bool root)
		{
			if (!root)
			{
				return Path.GetFileName(folder) + "/" + Path.GetFileName(file);
			}
			return Path.GetFileName(file);
		}

		private static string Clean(string name)
		{
			StringBuilder stringBuilder = new StringBuilder(name.Length);
			foreach (char c in name)
			{
				stringBuilder.Append((char.IsLetterOrDigit(c) || c == '-' || c == '_') ? c : '_');
			}
			return stringBuilder.ToString();
		}
	}
	public sealed class StampLibrary
	{
		private sealed record Sample(StampKind Kind, string File, string Sprite, int X, int Y, int Width, int Height, string Fallback);

		private sealed class DecodedPack
		{
			public List<(StampKind Kind, string Path, string Key, ImageData Image)> Stamps { get; } = new List<(StampKind, string, string, ImageData)>();

			public List<(string File, string Reason, string Detail)> Skipped { get; } = new List<(string, string, string)>();

			public ImageData Icon { get; set; }
		}

		private sealed class MenuGalleryPair
		{
			public MenuGallery Decorative { get; }

			public MenuGallery Weight { get; }

			public MenuGalleryPair(MenuGallery decorative, MenuGallery weight)
			{
				Decorative = decorative;
				Weight = weight;
			}
		}

		public const string StampsSection = "Stamps";

		public const string DecorativeKey = "Decorative";

		public const string WeightKey = "Weight";

		public const string PackTextsPrefix = "pack.";

		public const int MaxSide = 512;

		public const float Margin = 0.02f;

		public const float OutlineShare = 0.04f;

		public const string OutlineKey = "outline";

		public const int IconGap = 12;

		public const string Duplicate = "Duplicate";

		public const string Unreadable = "Unreadable";

		public const string SampleAtlas = "sp_UI_Elements_01";

		public const float MinClearShare = 0.04f;

		public const int IconStamps = 4;

		private static readonly Sample[] Samples = new Sample[2]
		{
			new Sample(StampKind.Decorative, "cat.png", "sp_Cat_Intro_01", 13, 14, 378, 302, "cat.png"),
			new Sample(StampKind.Weight, "cat_weight.png", "sp_Cat_Intro_02", 425, 14, 378, 304, "parcel.png")
		};

		private readonly CatLogger _log;

		private readonly TextCatalog _texts;

		private readonly Dictionary<string, CustomStamp> _byKey = new Dictionary<string, CustomStamp>(StringComparer.Ordinal);

		private readonly List<CustomStamp> _stamps = new List<CustomStamp>();

		private readonly Dictionary<ContentPack, (MenuGalleryPair Galleries, int Count)> _cards = new Dictionary<ContentPack, (MenuGalleryPair, int)>();

		private int _loading;

		public ContentPackKind Kind { get; }

		public int Generation { get; private set; }

		public bool IsLoading => _loading > 0;

		public IReadOnlyList<ContentPack> Packs => ContentPacks.Of(Kind);

		public IReadOnlyList<CustomStamp> Stamps => _stamps;

		public event Action Changed;

		public StampLibrary(CatLogger log, TextCatalog texts, string version)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0062: Expected O, but got Unknown
			_log = log;
			_texts = texts;
			Kind = new ContentPackKind("catlib.customstamps", "stamps.txt", "customstamps")
			{
				Policy = (SessionPolicy)1,
				VersionRule = (VersionRule)2
			};
			Kind.Dependencies.Add("CatLib-CustomStamps-" + version);
			Kind.Folders.Add("decorative");
			Kind.Folders.Add("weight");
			Kind.Readme = Readme;
			Kind.PackChanged += delegate
			{
				RaiseChanged();
			};
		}

		public bool TryGet(string key, out CustomStamp stamp)
		{
			return _byKey.TryGetValue(key ?? string.Empty, out stamp);
		}

		public IEnumerable<CustomStamp> Active(StampKind kind)
		{
			return _stamps.Where((CustomStamp stamp) => stamp.Kind == kind && stamp.IsReady && stamp.IsActive);
		}

		public void Load()
		{
			int generation = ++Generation;
			_stamps.Clear();
			_byKey.Clear();
			_cards.Clear();
			foreach (ContentPack item in ContentPacks.Load(Kind, _log))
			{
				try
				{
					Prepare(item, generation);
				}
				catch (Exception ex)
				{
					_log.Error("Reading the stamp pack " + item.Name + " failed", ex);
				}
			}
			RaiseChanged();
		}

		public string CreatePack()
		{
			string current = CatLanguage.Current;
			string text = _texts.Find("stamps.NewPackName", current) ?? "My Stamps";
			string text2 = _texts.Find("stamps.NewPackDescription", current) ?? "My stamps for Cat Mail Co.";
			Kind.Template = _texts.FormatFor(current, "stamps.Template", new object[2] { text, text2 });
			string text3 = ContentPacks.Create(Kind, text, (string)null);
			Sample[] samples = Samples;
			foreach (Sample sample in samples)
			{
				WriteSample(sample, Path.Combine(text3, StampFiles.FolderOf(sample.Kind), sample.File));
			}
			return text3;
		}

		private void WriteSample(Sample sample, string target)
		{
			string value = sample.Sprite;
			ImageData val = default(ImageData);
			string value2 = default(string);
			if (!GameImages.TryRead(sample.Sprite, ref val, ref value2))
			{
				value = $"{"sp_UI_Elements_01"} at {sample.X},{sample.Y}";
				string value3 = default(string);
				if (!GameImages.TryReadArea("sp_UI_Elements_01", sample.X, sample.Y, sample.Width, sample.Height, ref val, ref value3))
				{
					_log.Info($"The sample stamp {sample.File} is the copy in the mod: {value2}; {value3}");
					Copy(sample.Fallback, target);
					return;
				}
			}
			if (ClearShare(val) < 0.04f)
			{
				_log.Info($"The sample stamp {sample.File} is the copy in the mod: the game's {value} is not a drawing on a clear background");
				Copy(sample.Fallback, target);
				return;
			}
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(target) ?? ".");
				File.WriteAllBytes(target, val.Trimmed(0, (byte)8).ToPng());
				_log.Info($"The sample stamp {sample.File} is the game's {value}, {val.Width}x{val.Height}");
			}
			catch (Exception ex)
			{
				_log.Warning("The sample stamp " + sample.File + " could not be written: " + ex.Message);
			}
		}

		public string Summary(ContentPack pack, string language)
		{
			(MenuGalleryPair, int) value;
			int num = (_cards.TryGetValue(pack, out value) ? value.Item2 : 0);
			return _texts.PluralFor(language, "stamps.Summary", (long)num, Array.Empty<object>());
		}

		private void Prepare(ContentPack pack, int generation)
		{
			ContentPacks.CopyTexts(_texts, "pack.", pack);
			List<(string, string)> list = new List<(string, string)>();
			List<(StampKind Kind, string Path)> files = StampFiles.Find(pack.Folder, list);
			CatSettings settings = pack.Settings;
			MenuGallery decorative = ((settings != null) ? settings.Gallery("Stamps", "Decorative", (string)null) : null);
			CatSettings settings2 = pack.Settings;
			MenuGallery weight = ((settings2 != null) ? settings2.Gallery("Stamps", "Weight", (string)null) : null);
			_cards[pack] = (new MenuGalleryPair(decorative, weight), files.Count);
			if (pack.Settings != null)
			{
				pack.Settings.Summary = (string language) => Summary(pack, language);
			}
			foreach (var item in list)
			{
				pack.AddProblem(Problem(item.Item1, item.Item2));
			}
			Interlocked(ref _loading, 1);
			bool outline = HasOutline(pack.File.Get("outline", (string)null));
			Task.Run(() => Decode(pack, files, outline)).ContinueWith(delegate(Task<DecodedPack> task)
			{
				MainThread.Post((Action)delegate
				{
					Interlocked(ref _loading, -1);
					if (generation == Generation)
					{
						if (task.IsFaulted)
						{
							_log.Error("Reading the images of " + pack.Name + " failed", task.Exception?.GetBaseException());
						}
						else
						{
							Finish(pack, task.Result);
						}
					}
				});
			});
		}

		public static bool HasOutline(string value)
		{
			if (value != null)
			{
				if (!value.Equals("no", StringComparison.OrdinalIgnoreCase) && !value.Equals("false", StringComparison.OrdinalIgnoreCase) && !value.Equals("off", StringComparison.OrdinalIgnoreCase))
				{
					return !(value == "0");
				}
				return false;
			}
			return true;
		}

		public static ImageData Prepare(ImageData image, bool outline)
		{
			ImageData obj = image.Trimmed(0, (byte)8);
			float num = 0.02f + (outline ? 0.04f : 0f);
			ImageData val = obj.Scaled((int)(512f * (1f - 2f * num)));
			float num2 = (float)Math.Max(val.Width, val.Height) / (1f - 2f * num);
			int num3 = (outline ? ((int)Math.Round(num2 * 0.04f)) : 0);
			int num4 = (int)Math.Ceiling(num2 * 0.02f);
			ImageData val2 = ((num3 > 0) ? val.Outlined(num3, byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)128) : val);
			return val2.Padded(val2.Width + num4 * 2, val2.Height + num4 * 2).PaddedToAspect(1f);
		}

		private static DecodedPack Decode(ContentPack pack, List<(StampKind Kind, string Path)> files, bool outline)
		{
			DecodedPack decodedPack = new DecodedPack();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			ImageData image = default(ImageData);
			string item4 = default(string);
			foreach (var file in files)
			{
				StampKind item = file.Kind;
				string item2 = file.Path;
				string text = StampFiles.Key(pack.Id, item, item2);
				string item3 = Path.GetRelativePath(pack.Folder, item2).Replace('\\', '/');
				if (!hashSet.Add(text))
				{
					decodedPack.Skipped.Add((item3, "Duplicate", null));
				}
				else if (!ImageData.TryRead(item2, ref image, ref item4))
				{
					decodedPack.Skipped.Add((item3, "Unreadable", item4));
				}
				else
				{
					decodedPack.Stamps.Add((item, item2, text, Prepare(image, outline)));
				}
			}
			List<ImageData> list = decodedPack.Stamps.Select(((StampKind Kind, string Path, string Key, ImageData Image) stamp) => stamp.Image).Take(4).ToList();
			decodedPack.Icon = ((list.Count == 0) ? null : ImageData.Collage((IReadOnlyList<ImageData>)list, 256, 12));
			return decodedPack;
		}

		private void Finish(ContentPack pack, DecodedPack decoded)
		{
			foreach (var item in decoded.Skipped)
			{
				pack.AddProblem(Problem(item.File, item.Reason, item.Detail));
			}
			List<CustomStamp> list = new List<CustomStamp>();
			foreach (var (kind, path, text, val) in decoded.Stamps)
			{
				try
				{
					CustomStamp customStamp = new CustomStamp(pack, kind, path, text, val);
					customStamp.Texture = val.ToTexture("Custom stamp " + text, true);
					customStamp.Preview = ImageData.ToSprite(customStamp.Texture, (string)null);
					list.Add(customStamp);
					_byKey[text] = customStamp;
				}
				catch (Exception ex)
				{
					_log.Warning("The stamp " + text + " could not be made: " + ex.Message);
				}
			}
			_stamps.AddRange(list);
			if (_cards.TryGetValue(pack, out (MenuGalleryPair, int) value))
			{
				_cards[pack] = (value.Item1, list.Count);
				MenuGallery decorative = value.Item1.Decorative;
				if (decorative != null)
				{
					decorative.SetImages(from stamp in list
						where stamp.Kind == StampKind.Decorative
						select stamp.Preview);
				}
				MenuGallery weight = value.Item1.Weight;
				if (weight != null)
				{
					weight.SetImages(from stamp in list
						where stamp.Kind == StampKind.Weight
						select stamp.Preview);
				}
			}
			if (decoded.Icon != null)
			{
				pack.UseGeneratedIcon(decoded.Icon);
			}
			_log.Info($"{pack.Name}: {list.Count((CustomStamp stamp) => stamp.Kind == StampKind.Decorative)} decorative and {list.Count((CustomStamp stamp) => stamp.Kind == StampKind.Weight)} weight stamp(s)" + ((decoded.Skipped.Count == 0) ? string.Empty : $", {decoded.Skipped.Count} file(s) left out"));
			RaiseChanged();
		}

		private string Problem(string file, string reason, string detail = null)
		{
			string current = CatLanguage.Current;
			return reason switch
			{
				"NotSupported" => _texts.FormatFor(current, "stamps.NotSupported", new object[1] { file }), 
				"TooMany" => _texts.FormatFor(current, "stamps.TooMany", new object[2] { file, 64 }), 
				"Duplicate" => _texts.FormatFor(current, "stamps.Duplicate", new object[1] { file }), 
				_ => _texts.FormatFor(current, "stamps.Unreadable", new object[2]
				{
					file,
					detail ?? string.Empty
				}), 
			};
		}

		private string Readme(ContentPack pack)
		{
			List<CustomStamp> source = _stamps.Where((CustomStamp stamp) => stamp.Pack == pack).ToList();
			int value = source.Count((CustomStamp stamp) => stamp.Kind == StampKind.Decorative);
			int value2 = source.Count((CustomStamp stamp) => stamp.Kind == StampKind.Weight);
			return "A stamp pack for [Custom Stamps](https://thunderstore.io/c/cat-mail-co/p/CatLib/CustomStamps/): " + $"{value} decorative and {value2} weight stamp(s). Every player in a game needs the same pack to see its stamps.";
		}

		private void Copy(string resource, string target)
		{
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomStamps.Template." + resource);
				if (stream == null)
				{
					return;
				}
				Directory.CreateDirectory(Path.GetDirectoryName(target) ?? ".");
				using FileStream destination = File.Create(target);
				stream.CopyTo(destination);
			}
			catch (Exception ex)
			{
				_log.Warning("The sample stamp " + resource + " could not be copied: " + ex.Message);
			}
		}

		private void RaiseChanged()
		{
			try
			{
				this.Changed?.Invoke();
			}
			catch (Exception ex)
			{
				_log.Error("A handler of the stamp packs failed", ex);
			}
		}

		private static void Interlocked(ref int value, int delta)
		{
			System.Threading.Interlocked.Add(ref value, delta);
		}

		public static float ClearShare(ImageData image)
		{
			int num = 0;
			byte[] rgba = image.Rgba;
			for (int i = 3; i < rgba.Length; i += 4)
			{
				if (rgba[i] < 8)
				{
					num++;
				}
			}
			return (float)num / (float)(image.Width * image.Height);
		}
	}
}
namespace CustomStamps.Game
{
	public sealed class StampFactory
	{
		public const string HolderName = "CatLib Custom Stamps";

		public const float AspectTolerance = 0.02f;

		private readonly CatLogger _log;

		private readonly Dictionary<string, StampData> _built = new Dictionary<string, StampData>(StringComparer.Ordinal);

		private readonly HashSet<string> _failed = new HashSet<string>(StringComparer.Ordinal);

		private readonly HashSet<StampKind> _described = new HashSet<StampKind>();

		private GameObject _holder;

		private int _generation = -1;

		public int Built => _built.Count;

		public StampFactory(CatLogger log)
		{
			_log = log;
		}

		public bool IsCustom(StampData data)
		{
			if ((Object)(object)data != (Object)null)
			{
				return StampFiles.IsCustomKey(SafeName((Object)(object)data));
			}
			return false;
		}

		public StampData Get(CustomStamp stamp, int generation)
		{
			if (generation != _generation)
			{
				_built.Clear();
				_failed.Clear();
				_generation = generation;
			}
			if (_built.TryGetValue(stamp.Key, out var value) && (Object)(object)value != (Object)null && !((Il2CppObjectBase)value).WasCollected && (Object)(object)value._StampPrefab_k__BackingField != (Object)null)
			{
				return value;
			}
			if (_failed.Contains(stamp.Key) || !stamp.IsReady)
			{
				return null;
			}
			StampData val = Build(stamp);
			if ((Object)(object)val == (Object)null)
			{
				_failed.Add(stamp.Key);
				return null;
			}
			_built[stamp.Key] = val;
			return val;
		}

		public static StampData BaseFor(StampKind kind)
		{
			if (!Singleton<GameManager>.HasInstance())
			{
				return null;
			}
			GameManager instance = Singleton<GameManager>.Instance;
			Il2CppReferenceArray<StampData> val = ((kind == StampKind.Weight) ? instance.WeightStamps : instance.DecorativeStamps);
			if (val == null)
			{
				return null;
			}
			foreach (StampData item in (Il2CppArrayBase<StampData>)(object)val)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item._StampPrefab_k__BackingField != (Object)null)
				{
					return item;
				}
			}
			return null;
		}

		public string DescribeBase(StampKind kind)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			StampData val = BaseFor(kind);
			if ((Object)(object)val == (Object)null)
			{
				return $"{kind}: the game has no such stamps loaded, open a level first";
			}
			StampHelper stampPrefab_k__BackingField = val._StampPrefab_k__BackingField;
			MeshRenderer mainRenderer_k__BackingField = stampPrefab_k__BackingField._MainRenderer_k__BackingField;
			List<string> list = new List<string>
			{
				$"{kind}: {((Object)val).name} ({((MemberInfo)((Object)val).GetIl2CppType()).Name}, type {val.StampType}), prefab {((Object)stampPrefab_k__BackingField).name}, renderer {(((Object)(object)mainRenderer_k__BackingField == (Object)null) ? "none" : ((Object)mainRenderer_k__BackingField).name)}",
				"  start " + StampLook.Describe(stampPrefab_k__BackingField._StartMaterial_k__BackingField),
				"  feedback " + StampLook.Describe(stampPrefab_k__BackingField._FeedbackMaterial_k__BackingField),
				"  shared " + (((Object)(object)mainRenderer_k__BackingField == (Object)null) ? "none" : StampLook.Describe(((Renderer)mainRenderer_k__BackingField).sharedMaterial))
			};
			foreach (MeshFilter componentsInChild in ((Component)stampPrefab_k__BackingField).GetComponentsInChildren<MeshFilter>(true))
			{
				Mesh sharedMesh = componentsInChild.sharedMesh;
				string item;
				if (!((Object)(object)sharedMesh == (Object)null))
				{
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(57, 8);
					defaultInterpolatedStringHandler.AppendLiteral("  mesh ");
					defaultInterpolatedStringHandler.AppendFormatted(((Object)sharedMesh).name);
					defaultInterpolatedStringHandler.AppendLiteral(" on ");
					defaultInterpolatedStringHandler.AppendFormatted(((Object)componentsInChild).name);
					defaultInterpolatedStringHandler.AppendLiteral(": ");
					defaultInterpolatedStringHandler.AppendFormatted(sharedMesh.vertexCount);
					defaultInterpolatedStringHandler.AppendLiteral(" vertices, ");
					defaultInterpolatedStringHandler.AppendFormatted(sharedMesh.subMeshCount);
					defaultInterpolatedStringHandler.AppendLiteral(" part(s), bounds ");
					Bounds bounds = sharedMesh.bounds;
					defaultInterpolatedStringHandler.AppendFormatted<Vector3>(((Bounds)(ref bounds)).center);
					defaultInterpolatedStringHandler.AppendLiteral(" size ");
					bounds = sharedMesh.bounds;
					defaultInterpolatedStringHandler.AppendFormatted<Vector3>(((Bounds)(ref bounds)).size);
					defaultInterpolatedStringHandler.AppendLiteral(", ");
					defaultInterpolatedStringHandler.AppendFormatted(sharedMesh.isReadable ? "readable" : "not readable");
					defaultInterpolatedStringHandler.AppendLiteral(", scale ");
					defaultInterpolatedStringHandler.AppendFormatted<Vector3>(((Component)componentsInChild).transform.localScale);
					item = defaultInterpolatedStringHandler.ToStringAndClear();
				}
				else
				{
					item = "  mesh filter " + ((Object)componentsInChild).name + " without a mesh";
				}
				list.Add(item);
			}
			Sprite stampPreviewSprite_k__BackingField = val._StampPreviewSprite_k__BackingField;
			object item2;
			if (!((Object)(object)stampPreviewSprite_k__BackingField == (Object)null))
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(23, 4);
				defaultInterpolatedStringHandler2.AppendLiteral("  preview sprite ");
				defaultInterpolatedStringHandler2.AppendFormatted(((Object)stampPreviewSprite_k__BackingField).name);
				defaultInterpolatedStringHandler2.AppendLiteral(" ");
				Rect rect = stampPreviewSprite_k__BackingField.rect;
				defaultInterpolatedStringHandler2.AppendFormatted(((Rect)(ref rect)).width);
				defaultInterpolatedStringHandler2.AppendLiteral("x");
				rect = stampPreviewSprite_k__BackingField.rect;
				defaultInterpolatedStringHandler2.AppendFormatted(((Rect)(ref rect)).height);
				defaultInterpolatedStringHandler2.AppendLiteral(" of ");
				Texture2D texture = stampPreviewSprite_k__BackingField.texture;
				defaultInterpolatedStringHandler2.AppendFormatted((texture != null) ? ((Object)texture).name : null);
				item2 = defaultInterpolatedStringHandler2.ToStringAndClear();
			}
			else
			{
				item2 = "  no preview sprite";
			}
			list.Add((string)item2);
			Texture val2 = StampLook.FindImageTexture(stampPrefab_k__BackingField._StartMaterial_k__BackingField ?? ((mainRenderer_k__BackingField != null) ? ((Renderer)mainRenderer_k__BackingField).sharedMaterial : null), val, new List<string>());
			list.Add(((Object)(object)val2 == (Object)null) ? "  no stamp image texture found" : $"  stamp image texture {((Object)val2).name} {val2.width}x{val2.height}");
			return string.Join("\n", list);
		}

		private StampData Build(CustomStamp stamp)
		{
			StampData val = BaseFor(stamp.Kind);
			if ((Object)(object)val == (Object)null)
			{
				_log.Warning(stamp.Key + " waits: the game has no " + stamp.Kind.ToString().ToLowerInvariant() + " stamps loaded yet");
				return null;
			}
			List<string> list = new List<string>();
			GameObject val2 = null;
			try
			{
				EnsureHolder();
				val2 = Object.Instantiate<GameObject>(((Component)val._StampPrefab_k__BackingField).gameObject, _holder.transform, false);
				((Object)val2).name = stamp.Key;
				StampHelper component = val2.GetComponent<StampHelper>();
				if ((Object)(object)component == (Object)null)
				{
					throw new InvalidOperationException("the copy of the stamp prefab has no StampHelper");
				}
				Texture2D texture = stamp.Texture;
				if (!StampLook.Apply(component, val, texture, list, out var original))
				{
					throw new InvalidOperationException(string.Join("; ", list));
				}
				float num = ((original.height > 0) ? ((float)original.width / (float)original.height) : 1f);
				if (Math.Abs(num - 1f) > 0.02f)
				{
					Texture2D texture2 = stamp.Image.PaddedToAspect(num).ToTexture("Custom stamp " + stamp.Key + " " + num.ToString("0.00"), true);
					list.Clear();
					Object.DestroyImmediate((Object)(object)val2);
					val2 = Object.Instantiate<GameObject>(((Component)val._StampPrefab_k__BackingField).gameObject, _holder.transform, false);
					((Object)val2).name = stamp.Key;
					component = val2.GetComponent<StampHelper>();
					if (!StampLook.Apply(component, val, texture2, list, out var _))
					{
						throw new InvalidOperationException(string.Join("; ", list));
					}
				}
				if (StampMesh.Fit(component, list) == 0)
				{
					list.Add("no mesh to show the picture on");
				}
				StampData obj = Object.Instantiate<StampData>(val);
				((Object)obj).name = stamp.Key;
				((Object)obj).hideFlags = (HideFlags)32;
				obj._StampPrefab_k__BackingField = component;
				obj._StampPreviewSprite_k__BackingField = stamp.Preview;
				if (_described.Add(stamp.Kind))
				{
					_log.Info($"Custom {stamp.Kind.ToString().ToLowerInvariant()} stamps copy {((Object)val).name}: {string.Join("; ", list)}");
				}
				return obj;
			}
			catch (Exception ex)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					Object.Destroy((Object)(object)val2);
				}
				_log.Warning($"The stamp {stamp.Key} could not be made from {((Object)val).name}: {ex.Message}");
				return null;
			}
		}

		private void EnsureHolder()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (!((Object)(object)_holder != (Object)null) || ((Il2CppObjectBase)_holder).WasCollected)
			{
				_holder = new GameObject("CatLib Custom Stamps");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
			}
		}

		private static string SafeName(Object value)
		{
			try
			{
				return (value == (Object)null) ? null : value.name;
			}
			catch (Exception)
			{
				return null;
			}
		}
	}
	internal static class StampLook
	{
		public static readonly string[] KnownTextureNames = new string[14]
		{
			"_BaseMap", "_MainTex", "_BaseColorMap", "_Albedo", "_AlbedoMap", "_MainTexture", "_Texture", "_Tex", "_StampTexture", "_Stamp",
			"_Image", "_Sprite", "_Decal", "_DecalTex"
		};

		public static bool Apply(StampHelper helper, StampData baseData, Texture2D texture, List<string> report, out Texture original)
		{
			original = null;
			MeshRenderer val = helper._MainRenderer_k__BackingField ?? ((Component)helper).GetComponentInChildren<MeshRenderer>(true);
			if ((Object)(object)val == (Object)null)
			{
				report.Add("the stamp prefab has no mesh renderer");
				return false;
			}
			Material val2 = helper._StartMaterial_k__BackingField ?? ((Renderer)val).sharedMaterial;
			if ((Object)(object)val2 == (Object)null)
			{
				report.Add("the stamp prefab has no material");
				return false;
			}
			original = FindImageTexture(val2, baseData, report);
			if ((Object)(object)original == (Object)null)
			{
				report.Add("no texture of the stamp image was found in " + Describe(val2));
				return false;
			}
			Material val3 = Replace(val2, original, texture, report, "start material");
			if (val3 == val2)
			{
				return false;
			}
			helper._StartMaterial_k__BackingField = val3;
			foreach (Renderer componentsInChild in ((Component)helper).GetComponentsInChildren<Renderer>(true))
			{
				Il2CppReferenceArray<Material> sharedMaterials = componentsInChild.sharedMaterials;
				bool flag = false;
				for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; i++)
				{
					Material val4 = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[i];
					if (!((Object)(object)val4 == (Object)null))
					{
						Material val5 = ((((Il2CppObjectBase)val4).Pointer == ((Il2CppObjectBase)val2).Pointer) ? val3 : Replace(val4, original, texture, report, "material of " + ((Object)componentsInChild).name));
						if (val5 != val4)
						{
							((Il2CppArrayBase<Material>)(object)sharedMaterials)[i] = val5;
							flag = true;
						}
					}
				}
				if (flag)
				{
					componentsInChild.sharedMaterials = sharedMaterials;
				}
			}
			Material feedbackMaterial_k__BackingField = helper._FeedbackMaterial_k__BackingField;
			if ((Object)(object)feedbackMaterial_k__BackingField != (Object)null)
			{
				helper._FeedbackMaterial_k__BackingField = Replace(feedbackMaterial_k__BackingField, original, texture, report, "feedback material");
			}
			return true;
		}

		public static Texture FindImageTexture(Material material, StampData baseData, List<string> report)
		{
			object value;
			if (baseData == null)
			{
				value = null;
			}
			else
			{
				Sprite stampPreviewSprite_k__BackingField = baseData._StampPreviewSprite_k__BackingField;
				value = ((stampPreviewSprite_k__BackingField != null) ? stampPreviewSprite_k__BackingField.texture : null);
			}
			string text = SafeName((Object)value);
			Texture val = null;
			try
			{
				val = material.mainTexture;
			}
			catch (Exception)
			{
			}
			Texture val2 = null;
			int num = -1;
			int num2 = -1;
			foreach (var item3 in Textures(material))
			{
				string item = item3.Name;
				Texture item2 = item3.Texture;
				int num3 = 0;
				if (text != null && SafeName((Object)(object)item2) == text)
				{
					num3 += 4;
				}
				if ((Object)(object)val != (Object)null && ((Il2CppObjectBase)item2).Pointer == ((Il2CppObjectBase)val).Pointer)
				{
					num3 += 2;
				}
				if (item.IndexOf("Base", StringComparison.OrdinalIgnoreCase) >= 0 || item.IndexOf("Main", StringComparison.OrdinalIgnoreCase) >= 0 || item.IndexOf("Albedo", StringComparison.OrdinalIgnoreCase) >= 0 || item.IndexOf("Stamp", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					num3++;
				}
				int num4 = item2.width * item2.height;
				if (num3 > num || (num3 == num && num4 > num2))
				{
					val2 = item2;
					num = num3;
					num2 = num4;
				}
			}
			if ((Object)(object)val2 == (Object)null && (Object)(object)val != (Object)null)
			{
				val2 = val;
			}
			return val2;
		}

		public static string Describe(Material material)
		{
			if ((Object)(object)material == (Object)null)
			{
				return "no material";
			}
			string value;
			try
			{
				value = (((Object)(object)material.shader == (Object)null) ? "?" : ((Object)material.shader).name);
			}
			catch (Exception)
			{
				value = "?";
			}
			List<string> list = (from pair in Textures(material)
				select $"{pair.Name}={SafeName((Object)(object)pair.Texture)} {pair.Texture.width}x{pair.Texture.height}").ToList();
			return $"material {((Object)material).name} with shader {value}, textures: {((list.Count == 0) ? "none" : string.Join(", ", list))}";
		}

		public static IEnumerable<(string Name, Texture Texture)> Textures(Material material)
		{
			List<string> list = PropertyNames(material);
			HashSet<string> seen = new HashSet<string>(StringComparer.Ordinal);
			foreach (string item in list)
			{
				if (!seen.Add(item))
				{
					continue;
				}
				Texture val = null;
				try
				{
					if (material.HasTexture(item))
					{
						val = material.GetTexture(item);
					}
				}
				catch (Exception)
				{
					val = null;
				}
				if ((Object)(object)val != (Object)null)
				{
					yield return (Name: item, Texture: val);
				}
			}
		}

		private static Material Replace(Material material, Texture original, Texture2D texture, List<string> report, string what)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			List<string> list = new List<string>();
			Material val = new Material(material);
			foreach (var item in Textures(material))
			{
				var (text, _) = item;
				if (((Il2CppObjectBase)item.Texture).Pointer == ((Il2CppObjectBase)original).Pointer)
				{
					val.SetTexture(text, (Texture)(object)texture);
					list.Add(text);
				}
			}
			if (list.Count == 0)
			{
				try
				{
					if ((Object)(object)material.mainTexture != (Object)null && ((Il2CppObjectBase)material.mainTexture).Pointer == ((Il2CppObjectBase)original).Pointer)
					{
						val.mainTexture = (Texture)(object)texture;
						list.Add("mainTexture");
					}
				}
				catch (Exception)
				{
				}
			}
			if (list.Count == 0)
			{
				Object.Destroy((Object)(object)val);
				return material;
			}
			((Object)val).name = ((Object)material).name + " (custom stamp)";
			((Object)val).hideFlags = (HideFlags)32;
			report.Add(what + ": " + string.Join(", ", list));
			return val;
		}

		private static List<string> PropertyNames(Material material)
		{
			List<string> list = new List<string>();
			try
			{
				Il2CppStringArray texturePropertyNames = material.GetTexturePropertyNames();
				if (texturePropertyNames != null)
				{
					foreach (string item in (Il2CppArrayBase<string>)(object)texturePropertyNames)
					{
						list.Add(item);
					}
				}
			}
			catch (Exception)
			{
			}
			list.AddRange(KnownTextureNames);
			return list;
		}

		private static string SafeName(Object value)
		{
			try
			{
				return (value == (Object)null) ? null : value.name;
			}
			catch (Exception)
			{
				return null;
			}
		}
	}
	internal static class StampMesh
	{
		public const float FaceOffsetShare = 0.002f;

		private static readonly Dictionary<IntPtr, Mesh> Quads = new Dictionary<IntPtr, Mesh>();

		public static int Fit(StampHelper helper, List<string> report)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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)
			int num = 0;
			foreach (MeshFilter componentsInChild in ((Component)helper).GetComponentsInChildren<MeshFilter>(true))
			{
				Mesh sharedMesh = componentsInChild.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null)
				{
					continue;
				}
				if (!Quads.TryGetValue(((Il2CppObjectBase)sharedMesh).Pointer, out var value) || (Object)(object)value == (Object)null || ((Il2CppObjectBase)value).WasCollected)
				{
					value = Build(sharedMesh, out var how);
					Quads[((Il2CppObjectBase)sharedMesh).Pointer] = value;
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(41, 4);
					defaultInterpolatedStringHandler.AppendLiteral("mesh ");
					defaultInterpolatedStringHandler.AppendFormatted(((Object)sharedMesh).name);
					defaultInterpolatedStringHandler.AppendLiteral(" of ");
					defaultInterpolatedStringHandler.AppendFormatted(sharedMesh.vertexCount);
					defaultInterpolatedStringHandler.AppendLiteral(" vertices, bounds ");
					Bounds bounds = sharedMesh.bounds;
					defaultInterpolatedStringHandler.AppendFormatted<Vector3>(((Bounds)(ref bounds)).size);
					defaultInterpolatedStringHandler.AppendLiteral(", replaced by ");
					defaultInterpolatedStringHandler.AppendFormatted(how);
					report.Add(defaultInterpolatedStringHandler.ToStringAndClear());
				}
				componentsInChild.sharedMesh = value;
				MeshRenderer component = ((Component)componentsInChild).GetComponent<MeshRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					Il2CppReferenceArray<Material> sharedMaterials = ((Renderer)component).sharedMaterials;
					if (sharedMaterials != null && ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length > 1)
					{
						((Renderer)component).sharedMaterials = Il2CppReferenceArray<Material>.op_Implicit((Material[])(object)new Material[1] { ((Il2CppArrayBase<Material>)(object)sharedMaterials)[0] });
					}
				}
				num++;
			}
			return num;
		}

		private static Mesh Build(Mesh original, out string how)
		{
			string problem;
			try
			{
				Mesh val = CopyFromGpu(original, out how, out problem);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			catch (Exception ex)
			{
				problem = ex.Message;
			}
			Mesh result = Square(original, out how);
			how = how + " on both sides, its own data could not be read: " + problem;
			return result;
		}

		private static Mesh CopyFromGpu(Mesh source, out string how, out string problem)
		{
			//IL_0025: 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_0067: 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_0098: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: 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)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Expected O, but got Unknown
			how = null;
			problem = null;
			int vertexCount = source.vertexCount;
			if (vertexCount < 3 || !source.HasVertexAttribute((VertexAttribute)4))
			{
				problem = "it has no picture coordinates";
				return null;
			}
			if ((int)source.GetVertexAttributeFormat((VertexAttribute)0) != 0 || source.GetVertexAttributeDimension((VertexAttribute)0) < 3)
			{
				problem = $"positions are stored as {source.GetVertexAttributeFormat((VertexAttribute)0)}";
				return null;
			}
			VertexAttributeFormat vertexAttributeFormat = source.GetVertexAttributeFormat((VertexAttribute)4);
			if (source.GetVertexAttributeDimension((VertexAttribute)4) < 2 || SizeOf(vertexAttributeFormat) == 0)
			{
				problem = $"picture coordinates are stored as {vertexAttributeFormat}";
				return null;
			}
			for (int i = 0; i < source.subMeshCount; i++)
			{
				if ((int)source.GetTopology(i) != 0)
				{
					problem = $"part {i} is made of {source.GetTopology(i)}";
					return null;
				}
			}
			List<byte[]> list = new List<byte[]>();
			for (int j = 0; j < source.vertexBufferCount; j++)
			{
				list.Add(ReadBuffer(source.GetVertexBufferImpl(j), source.GetVertexBufferStride(j) * vertexCount));
			}
			GraphicsBuffer indexBufferImpl = source.GetIndexBufferImpl();
			int num = (((int)source.indexFormat == 0) ? 2 : 4);
			int num2 = indexBufferImpl.count * indexBufferImpl.stride / num;
			byte[] value = ReadBuffer(indexBufferImpl, num2 * num);
			int stride;
			int offset;
			byte[] value2 = Attribute(source, list, (VertexAttribute)0, out stride, out offset);
			int stride2;
			int offset2;
			byte[] data = Attribute(source, list, (VertexAttribute)4, out stride2, out offset2);
			Vector3[] array = (Vector3[])(object)new Vector3[vertexCount];
			Vector2[] array2 = (Vector2[])(object)new Vector2[vertexCount];
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue);
			Vector2 val3 = default(Vector2);
			for (int k = 0; k < vertexCount; k++)
			{
				int num3 = k * stride + offset;
				array[k] = new Vector3(BitConverter.ToSingle(value2, num3), BitConverter.ToSingle(value2, num3 + 4), BitConverter.ToSingle(value2, num3 + 8));
				int num4 = k * stride2 + offset2;
				((Vector2)(ref val3))..ctor(Component(data, num4, vertexAttributeFormat), Component(data, num4 + SizeOf(vertexAttributeFormat), vertexAttributeFormat));
				array2[k] = val3;
				val = Vector2.Min(val, val3);
				val2 = Vector2.Max(val2, val3);
			}
			Bounds bounds = source.bounds;
			Bounds val4 = default(Bounds);
			((Bounds)(ref val4))..ctor(array[0], Vector3.zero);
			Vector3[] array3 = array;
			foreach (Vector3 val5 in array3)
			{
				((Bounds)(ref val4)).Encapsulate(val5);
			}
			if (Vector3.Distance(((Bounds)(ref val4)).min, ((Bounds)(ref bounds)).min) > 0.001f || Vector3.Distance(((Bounds)(ref val4)).max, ((Bounds)(ref bounds)).max) > 0.001f)
			{
				problem = $"the data from the video card does not match the mesh ({((Bounds)(ref val4)).min}..{((Bounds)(ref val4)).max}, expected {((Bounds)(ref bounds)).min}..{((Bounds)(ref bounds)).max})";
				return null;
			}
			Vector2 val6 = val2 - val;
			if (val6.x <= 1E-06f || val6.y <= 1E-06f)
			{
				problem = "its picture coordinates cover no area";
				return null;
			}
			for (int m = 0; m < vertexCount; m++)
			{
				array2[m] = new Vector2((array2[m].x - val.x) / val6.x, (array2[m].y - val.y) / val6.y);
			}
			List<int> list2 = new List<int>();
			for (int n = 0; n < source.subMeshCount; n++)
			{
				SubMeshDescriptor subMesh = source.GetSubMesh(n);
				for (int num5 = ((SubMeshDescriptor)(ref subMesh)).indexStart; num5 < ((SubMeshDescriptor)(ref subMesh)).indexStart + ((SubMeshDescriptor)(ref subMesh)).indexCount && num5 < num2; num5++)
				{
					int num6 = ((num == 2) ? BitConverter.ToUInt16(value, num5 * 2) : BitConverter.ToInt32(value, num5 * 4));
					list2.Add(num6 + ((SubMeshDescriptor)(ref subMesh)).baseVertex);
				}
			}
			Mesh val7 = new Mesh
			{
				name = "CatLib custom stamp " + ((Object)source).name,
				hideFlags = (HideFlags)32,
				vertices = Il2CppStructArray<Vector3>.op_Implicit(array),
				uv = Il2CppStructArray<Vector2>.op_Implicit(array2),
				triangles = Il2CppStructArray<int>.op_Implicit(list2.ToArray())
			};
			val7.RecalculateNormals();
			val7.RecalculateTangents();
			val7.RecalculateBounds();
			how = $"copied from the video card with its picture area {val.x:0.###}..{val2.x:0.###} x {val.y:0.###}..{val2.y:0.###} stretched to the whole picture, {list2.Count / 3} triangle(s)";
			return val7;
		}

		private static byte[] Attribute(Mesh source, List<byte[]> streams, VertexAttribute attribute, out int stride, out int offset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			int vertexAttributeStream = source.GetVertexAttributeStream(attribute);
			stride = source.GetVertexBufferStride(vertexAttributeStream);
			offset = source.GetVertexAttributeOffset(attribute);
			return streams[vertexAttributeStream];
		}

		private static int SizeOf(VertexAttributeFormat format)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected I4, but got Unknown
			return (int)format switch
			{
				0 => 4, 
				1 => 2, 
				4 => 2, 
				2 => 1, 
				_ => 0, 
			};
		}

		private static float Component(byte[] data, int at, VertexAttributeFormat format)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected I4, but got Unknown
			return (int)format switch
			{
				0 => BitConverter.ToSingle(data, at), 
				1 => (float)BitConverter.Int16BitsToHalf(BitConverter.ToInt16(data, at)), 
				4 => (float)(int)BitConverter.ToUInt16(data, at) / 65535f, 
				_ => (float)(int)data[at] / 255f, 
			};
		}

		private static byte[] ReadBuffer(GraphicsBuffer buffer, int bytes)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			try
			{
				Il2CppStructArray<byte> val = new Il2CppStructArray<byte>((long)bytes);
				buffer.InternalGetData(new Array(((Il2CppObjectBase)val).Pointer), 0, 0, bytes, 1);
				byte[] array = new byte[bytes];
				for (int i = 0; i < bytes; i++)
				{
					array[i] = ((Il2CppArrayBase<byte>)(object)val)[i];
				}
				return array;
			}
			finally
			{
				buffer.Release();
			}
		}

		private static Mesh Square(Mesh original, out string how)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_002d: 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_0036: 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_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_0045: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_0156: Expected O, but got Unknown
			//IL_0065: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = original.bounds;
			if (!TryAxes(original, out var across, out var up, out how))
			{
				AxesFromBounds(((Bounds)(ref bounds)).extents, out across, out up);
				how = "a square laid along its bounds";
			}
			Vector3 val = Vector3.Cross(across, up);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			float num = Math.Max(Projected(extents, across), Projected(extents, up));
			if (num <= 0f)
			{
				num = Math.Max(extents.x, Math.Max(extents.y, extents.z));
			}
			float offset = num * 2f * 0.002f;
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			Vector3[] array2 = (Vector3[])(object)new Vector3[8];
			Vector2[] array3 = (Vector2[])(object)new Vector2[8];
			int[] array4 = new int[12];
			Face(((Bounds)(ref bounds)).center, normalized, up, num, offset, 0, array, array2, array3, array4);
			Face(((Bounds)(ref bounds)).center, -normalized, up, num, offset, 4, array, array2, array3, array4);
			Mesh val2 = new Mesh
			{
				name = "CatLib custom stamp " + ((Object)original).name,
				hideFlags = (HideFlags)32,
				vertices = Il2CppStructArray<Vector3>.op_Implicit(array),
				normals = Il2CppStructArray<Vector3>.op_Implicit(array2),
				uv = Il2CppStructArray<Vector2>.op_Implicit(array3),
				triangles = Il2CppStructArray<int>.op_Implicit(array4)
			};
			val2.RecalculateTangents();
			val2.RecalculateBounds();
			return val2;
		}

		private static void Face(Vector3 center, Vector3 normal, Vector3 up, float half, float offset, int first, Vector3[] vertices, Vector3[] normals, Vector2[] uvs, int[] triangles)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_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_0094: 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_0097: 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_00a1: 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_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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Cross(up, -normal);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = center + normal * offset;
			vertices[first] = val2 - normalized * half - up * half;
			vertices[first + 1] = val2 - normalized * half + up * half;
			vertices[first + 2] = val2 + normalized * half + up * half;
			vertices[first + 3] = val2 + normalized * half - up * half;
			uvs[first] = new Vector2(0f, 0f);
			uvs[first + 1] = new Vector2(0f, 1f);
			uvs[first + 2] = new Vector2(1f, 1f);
			uvs[first + 3] = new Vector2(1f, 0f);
			for (int i = 0; i < 4; i++)
			{
				normals[first + i] = normal;
			}
			int num = first / 4 * 6;
			triangles[num] = first;
			triangles[num + 1] = first + 1;
			triangles[num + 2] = first + 2;
			triangles[num + 3] = first;
			triangles[num + 4] = first + 2;
			triangles[num + 5] = first + 3;
		}

		private static bool TryAxes(Mesh mesh, out Vector3 across, out Vector3 up, out string how)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0011: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_013d: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0156: 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_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			across = Vector3.zero;
			up = Vector3.zero;
			how = null;
			if (!mesh.isReadable)
			{
				return false;
			}
			try
			{
				Il2CppStructArray<Vector3> vertices = mesh.vertices;
				Il2CppStructArray<Vector2> uv = mesh.uv;
				Il2CppStructArray<int> triangles = mesh.triangles;
				if (vertices == null || uv == null || triangles == null || ((Il2CppArrayBase<Vector2>)(object)uv).Length != ((Il2CppArrayBase<Vector3>)(object)vertices).Length)
				{
					return false;
				}
				for (int i = 0; i + 2 < ((Il2CppArrayBase<int>)(object)triangles).Length; i += 3)
				{
					Vector3 val = ((Il2CppArrayBase<Vector3>)(object)vertices)[((Il2CppArrayBase<int>)(object)triangles)[i]];
					Vector3 val2 = ((Il2CppArrayBase<Vector3>)(object)vertices)[((Il2CppArrayBase<int>)(object)triangles)[i + 1]] - val;
					Vector3 val3 = ((Il2CppArrayBase<Vector3>)(object)vertices)[((Il2CppArrayBase<int>)(object)triangles)[i + 2]] - val;
					Vector2 val4 = ((Il2CppArrayBase<Vector2>)(object)uv)[((Il2CppArrayBase<int>)(object)triangles)[i]];
					Vector2 val5 = ((Il2CppArrayBase<Vector2>)(object)uv)[((Il2CppArrayBase<int>)(object)triangles)[i + 1]] - val4;
					Vector2 val6 = ((Il2CppArrayBase<Vector2>)(object)uv)[((Il2CppArrayBase<int>)(object)triangles)[i + 2]] - val4;
					float num = val5.x * val6.y - val6.x * val5.y;
					if (!(Math.Abs(num) < 1E-09f))
					{
						Vector3 val7 = (val2 * val6.y - val3 * val5.y) / num;
						Vector3 val8 = (val3 * val5.x - val2 * val6.x) / num;
						if (!(((Vector3)(ref val7)).sqrMagnitude < 1E-12f) && !(((Vector3)(ref val8)).sqrMagnitude < 1E-12f))
						{
							across = ((Vector3)(ref val7)).normalized;
							Vector3 val9 = val8 - across * Vector3.Dot(across, val8);
							up = ((Vector3)(ref val9)).normalized;
							how = "a square turned like its picture";
							return ((Vector3)(ref up)).sqrMagnitude > 0.5f;
						}
					}
				}
			}
			catch (Exception)
			{
			}
			return false;
		}

		private static void AxesFromBounds(Vector3 extents, out Vector3 across, out Vector3 up)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a4: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[3]
			{
				Vector3.right,
				Vector3.up,
				Vector3.forward
			};
			float[] array2 = new float[3] { extents.x, extents.y, extents.z };
			int num = 0;
			for (int i = 1; i < 3; i++)
			{
				if (array2[i] < array2[num])
				{
					num = i;
				}
			}
			List<Vector3> list = new List<Vector3>();
			for (int j = 0; j < 3; j++)
			{
				if (j != num)
				{
					list.Add(array[j]);
				}
			}
			across = list[0];
			up = list[1];
		}

		private static float Projected(Vector3 extents, Vector3 axis)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			return Math.Abs(extents.x * axis.x) + Math.Abs(extents.y * axis.y) + Math.Abs(extents.z * axis.z);
		}
	}
	public sealed class StampSelection
	{
		private readonly StampLibrary _library;

		private readonly StampFactory _factory;

		private readonly CatLogger _log;

		private readonly HashSet<string> _unknown = new HashSet<string>(StringComparer.Ordinal);

		public int Added { get; private set; }

		public StampSelection(StampLibrary library, StampFactory factory, CatLogger log)
		{
			_library = library;
			_factory = factory;
			_log = log;
		}

		public static StampKind? KindOf(StampCategory category)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)category != 1)
			{
				if ((int)category == 3)
				{
					return StampKind.Decorative;
				}
				return null;
			}
			return StampKind.Weight;
		}

		public void AfterPopulate(StampSelectionCategoryInterface category)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			StampKind? stampKind = KindOf(category.LinkedStampCategory);
			if (!stampKind.HasValue)
			{
				return;
			}
			int num = 0;
			foreach (CustomStamp item in _library.Active(stampKind.Value))
			{
				StampData val = _factory.Get(item, _library.Generation);
				if (!((Object)(object)val == (Object)null))
				{
					category.InstantiateStampItem(val);
					num++;
				}
			}
			Added = num;
		}

		public void Refresh()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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)
			if (!Singleton<InterfaceManager>.HasInstance())
			{
				return;
			}
			StampSelectionInterface stampSelectionInterface = Singleton<InterfaceManager>.Instance.StampSelectionInterface;
			if ((Object)(object)stampSelectionInterface == (Object)null || !stampSelectionInterface._isInitialized)
			{
				return;
			}
			StampSelectableItemInterface currentSelectedStampItem = stampSelectionInterface.CurrentSelectedStampItem;
			StampData val = (((Object)(object)currentSelectedStampItem == (Object)null) ? null : currentSelectedStampItem.StampData);
			if (_factory.IsCustom(val) && (!_library.TryGet(((Object)val).name, out var stamp) || !stamp.IsActive))
			{
				stampSelectionInterface.ClearSelectedStamp();
			}
			Dictionary<StampCategory, StampSelectionCategoryInterface> stampSelectionCategories = stampSelectionInterface._stampSelectionCategories;
			if (stampSelectionCategories == null)
			{
				return;
			}
			StampCategory[] array = (StampCategory[])(object)new StampCategory[2]
			{
				(StampCategory)3,
				(StampCategory)1
			};
			foreach (StampCategory val2 in array)
			{
				if (stampSelectionCategories.ContainsKey(val2))
				{
					stampSelectionCategories[val2].Populate();
				}
			}
		}

		public bool PlaceFromNetwork(EntityInteractableStamp stamps, string key, int identifier, Vector3 position, Quaternion rotation, bool fromPlayer)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (!StampFiles.IsCustomKey(key))
			{
				return false;
			}
			if (!_library.TryGet(key, out var stamp))
			{
				if (_unknown.Add(key))
				{
					_log.Info(key + " is a stamp of a pack this game does not have" + (_library.IsLoading ? " or has not read yet" : string.Empty) + ", it is not shown");
				}
				return true;
			}
			StampData val = _factory.Get(stamp, _library.Generation);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			Place(stamps, val, identifier, position, rotation, fromPlayer);
			return true;
		}

		private static void Place(EntityInteractableStamp stamps, StampData data, int identifier, Vector3 position, Quaternion rotation, bool fromPlayer)
		{
			//IL_001a: 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_005b: 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_0079: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			StampHelper val = Object.Instantiate<StampHelper>(data._StampPrefab_k__BackingField, stamps._StampsParent_k__BackingField);
			Transform transform = ((Component)val).transform;
			transform.localRotation = rotation;
			transform.localPosition = position;
			Entity linkedEntity_k__BackingField = stamps._LinkedEntity_k__BackingField;
			EntityProperties val2 = (((Object)(object)linkedEntity_k__BackingField == (Object)null) ? null : linkedEntity_k__BackingField.Properties);
			float num = (((Object)(object)val2 == (Object)null) ? 1f : val2.StampSizeMultiplier);
			transform.localScale = Vector3.one * num;
			if (Singleton<VFXManager>.HasInstance())
			{
				Singleton<VFXManager>.Instance.PlayStampingVFX(transform.position, transform.rotation);
			}
			if (fromPlayer)
			{
				val.StartStampingFeedback();
			}
			if (stamps._stampNextIdentifier <= identifier)
			{
				stamps._stampNextIdentifier = identifier + 1;
			}
			StampInstance val3 = new StampInstance(identifier, val, data, false);
			if ((Object)(object)val3._StampObject_k__BackingField == (Object)null)
			{
				val3._StampObject_k__BackingField = ((Component)val).gameObject;
			}
			stamps._stampInstances.Add(val3);
			StampAddedHandler stampAdded = stamps.StampAdded;
			if (stampAdded != null)
			{
				stampAdded.Invoke(val3);
			}
			stamps.CheckOnboardingValidation();
		}
	}
}