Decompiled source of DeliverySaver v1.1.0

DeliverySaver.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using DeliverySaver;
using Il2CppFluffyUnderware.DevTools.Extensions;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Phone.Delivery;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
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(Core), "DeliverySaver", "1.1.0", "Coco", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DeliverySaver")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+65843d626b518a3043b842ecef01f7363028f066")]
[assembly: AssemblyProduct("DeliverySaver")]
[assembly: AssemblyTitle("DeliverySaver")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 DeliverySaver
{
	internal enum EntryAction
	{
		Overwrite,
		None
	}
	internal class EntryRegister
	{
		public GameObject gameObject;

		public ImmutableEntry newEntry;

		public ImmutableEntry originalEntry;

		public EntryAction action = EntryAction.None;

		public EntryRegister(GameObject gameObject, ImmutableEntry newEntry, ImmutableEntry originalEntry)
		{
			this.gameObject = gameObject;
			this.newEntry = newEntry;
			this.originalEntry = originalEntry;
		}
	}
	internal class Comparator
	{
		private static Comparator _instance;

		private List<EntryRegister> _entries = new List<EntryRegister>();

		private Transform _templates;

		public GameObject gameObject;

		public static Comparator Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new Comparator();
				}
				return _instance;
			}
		}

		public void Init()
		{
			AssetsManager.Instance.LoadAssetBundleFromResources("Comparator", "ui.comparator");
			AssetsManager.Instance.LoadAssetBundleFromResources("EntriesDiff", "ui.entriesdiff");
		}

		public void Instantiate()
		{
			gameObject = AssetsManager.Instance.Instantiate("Comparator");
			gameObject.transform.SetParent((Transform)(object)((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).appContainer, false);
			Button component = ((Component)gameObject.transform.Find("Original/Close")).GetComponent<Button>();
			((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit((Action)OnClose));
			Button component2 = ((Component)gameObject.transform.Find("Original/Buttons/Confirm")).GetComponent<Button>();
			((UnityEvent)component2.onClick).AddListener(UnityAction.op_Implicit((Action)OnConfirm));
			Button component3 = ((Component)gameObject.transform.Find("Original/Buttons/OverwriteAll")).GetComponent<Button>();
			((UnityEvent)component3.onClick).AddListener(UnityAction.op_Implicit((Action)OnOverwriteAll));
			gameObject.SetActive(false);
			_templates = gameObject.transform.Find("Original/Scroll/View/Templates");
		}

		private void OnConfirm()
		{
			foreach (EntryRegister entry in _entries)
			{
				if (entry.action == EntryAction.Overwrite)
				{
					TemplateManager.Instance.SetEntry(entry.newEntry);
				}
			}
			Clear();
		}

		private void OnOverwriteAll()
		{
			foreach (EntryRegister entry in _entries)
			{
				TemplateManager.Instance.SetEntry(entry.newEntry);
			}
			Clear();
		}

		private void Clear()
		{
			foreach (EntryRegister entry in _entries)
			{
				entry.newEntry.Destroy();
				entry.originalEntry.Destroy();
				ObjectExt.Destroy((Object)(object)entry.gameObject);
			}
			_entries.Clear();
			gameObject.SetActive(false);
		}

		private void OnClose()
		{
			Clear();
		}

		private void UpdateAction(bool value, int index)
		{
			if (value)
			{
				_entries[index].action = EntryAction.Overwrite;
			}
			else
			{
				_entries[index].action = EntryAction.None;
			}
		}

		public void Compare(List<EntryData> newData, List<EntryData> originalData)
		{
			List<EntryData> list = originalData.OrderBy((EntryData d) => newData.IndexOf(d)).ToList();
			for (int i = 0; i < newData.Count; i++)
			{
				Compare(newData[i], list[i]);
			}
		}

		public void Compare(EntryData newData, EntryData originalData)
		{
			GameObject val = AssetsManager.Instance.Instantiate("EntriesDiff");
			Toggle component = ((Component)val.transform.Find("arrow")).GetComponent<Toggle>();
			ImmutableEntry immutableEntry = new ImmutableEntry(newData, val.transform);
			immutableEntry.gameObject.transform.SetSiblingIndex(0);
			ImmutableEntry originalEntry = new ImmutableEntry(originalData, val.transform);
			val.transform.SetParent(_templates, false);
			_entries.Add(new EntryRegister(val, immutableEntry, originalEntry));
			gameObject.SetActive(true);
			int index = _entries.Count - 1;
			Action<bool> action = delegate(bool toggle)
			{
				UpdateAction(toggle, index);
			};
			((UnityEvent<bool>)(object)component.onValueChanged).AddListener(UnityAction<bool>.op_Implicit(action));
		}
	}
	internal static class GUIUtils
	{
		public static void RebuildLayout(VerticalLayoutGroup vls)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)vls).GetComponent<RectTransform>());
		}

		public static void RebuildLayout(GridLayoutGroup gls)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)gls).GetComponent<RectTransform>());
		}

		public static void RebuildLayout(HorizontalLayoutGroup hls)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)hls).GetComponent<RectTransform>());
		}

		public static void MarkRebuildLayout(VerticalLayoutGroup vls)
		{
			LayoutRebuilder.MarkLayoutRootForRebuild(((Component)vls).GetComponent<RectTransform>());
		}

		public static void MarkRebuildLayout(GridLayoutGroup gls)
		{
			LayoutRebuilder.MarkLayoutRootForRebuild(((Component)gls).GetComponent<RectTransform>());
		}

		public static void MarkRebuildLayout(HorizontalLayoutGroup hls)
		{
			LayoutRebuilder.MarkLayoutRootForRebuild(((Component)hls).GetComponent<RectTransform>());
		}
	}
	internal class IngredientData
	{
		public int baseQuantity;

		public uint id;

		public IngredientData(uint id, int baseQuantity)
		{
			this.id = id;
			this.baseQuantity = baseQuantity;
		}

		public static IngredientData FromListingEntry(ListingEntry entry)
		{
			return new IngredientData(IngredientRegister.Instance.GetItemID(((ItemDefinition)entry.MatchingListing.Item).ID), int.Parse(entry.QuantityInput.text));
		}
	}
	internal class Ingredient
	{
		private string _name;

		private int _price;

		private int _stackLimit;

		private uint _id;

		private int _baseQuantity;

		private ImmutableEntry _parent;

		private Text _content;

		private GameObject _root;

		public int baseQuantity
		{
			get
			{
				return _baseQuantity;
			}
			set
			{
				_baseQuantity = value;
				RebuildContent(_parent.multiplier);
			}
		}

		public int price => _price;

		public int stackLimit => _stackLimit;

		public string name => _name;

		public uint id => _id;

		public Ingredient(ListingEntry entry, ImmutableEntry parent)
		{
			_id = IngredientRegister.Instance.GetItemID(((ItemDefinition)entry.MatchingListing.Item).ID);
			_stackLimit = ((ItemDefinition)entry.MatchingListing.Item).StackLimit;
			_name = entry.ItemNameLabel.text;
			_price = int.Parse(entry.ItemPriceLabel.text.Replace("$", ""));
			_baseQuantity = int.Parse(entry.QuantityInput.text);
			_parent = parent;
			_root = AssetsManager.Instance.Instantiate("Component");
			_root.transform.SetParent(parent.gameObject.transform.Find("Content"), false);
			Transform val = _root.transform.Find("Image");
			((Component)val).GetComponent<RawImage>().texture = ((Graphic)entry.Icon).mainTexture;
			Transform val2 = _root.transform.Find("Content");
			_content = ((Component)val2).GetComponent<Text>();
			_content.text = entry.QuantityInput.text + "x " + _name;
		}

		public int QuantityMultipliedBy(float multiplier)
		{
			return (int)((float)_baseQuantity * multiplier);
		}

		public void RebuildContent(float multiplier)
		{
			int value = QuantityMultipliedBy(multiplier);
			_content.text = $"{value}x {_name}";
		}

		public void Destroy()
		{
			ObjectExt.Destroy((Object)(object)_root);
		}
	}
	internal class EntryData : IEquatable<EntryData>
	{
		public string title;

		public float multiplier;

		private string _shopName;

		private List<IngredientData> _ingredients;

		public string shopName => _shopName;

		public List<IngredientData> ingredients => _ingredients;

		public EntryData(string title, float multiplier, string shopName, List<IngredientData> ingredients)
		{
			this.title = title;
			this.multiplier = multiplier;
			_shopName = shopName;
			_ingredients = ingredients;
		}

		public static EntryData FromDeliveryShop(string title, float multiplier, DeliveryShop shop)
		{
			List<IngredientData> list = new List<IngredientData>();
			Enumerator<ListingEntry> enumerator = shop.listingEntries.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ListingEntry current = enumerator.Current;
				if (current.QuantityInput.text != "0")
				{
					list.Add(IngredientData.FromListingEntry(current));
				}
			}
			return new EntryData(title, multiplier, ((Object)shop).name, list);
		}

		public bool Equals(EntryData other)
		{
			return title == other.title;
		}

		public override int GetHashCode()
		{
			return title.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj is EntryData)
			{
				return Equals((EntryData)obj);
			}
			return base.Equals(obj);
		}
	}
	internal class Entry : ImmutableEntry
	{
		private InputUI _changeNameInput;

		protected override string _prefabName => "Entry";

		public Entry(EntryData data, Transform parent)
			: base(data, parent)
		{
		}

		public Entry(string title, DeliveryShop shop, Transform parent)
			: base(title, shop, parent)
		{
		}

		protected override void Init(string title, DeliveryShop shop, Transform parent)
		{
			base.Init(title, shop, parent);
			Action action = delegate
			{
				ApplyEntryToShop();
			};
			((UnityEvent)base.gameObject.GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action));
			Transform val = base.gameObject.transform.Find("Head/Header/ChangeNameInput");
			_changeNameInput = new InputUI(((Component)val).GetComponent<InputField>());
			InputUI changeNameInput = _changeNameInput;
			changeNameInput.OnSubmit = (Func<string, bool>)Delegate.Combine(changeNameInput.OnSubmit, new Func<string, bool>(ChangeTitle));
			Action action2 = delegate
			{
				OnTitleEdit();
			};
			((UnityEvent)((Component)base.gameObject.transform.Find("Head/Header/Title")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action2));
			Transform val2 = base.gameObject.transform.Find("Head/Header/CloseButton");
			Action action3 = delegate
			{
				Close();
			};
			((UnityEvent)((Component)val2).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action3));
			Transform val3 = base.gameObject.transform.Find("Head/Header/UploadIcon");
			Action action4 = delegate
			{
				OnSingleExportClick();
			};
			((UnityEvent)((Component)val3).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action4));
			InputUI multiplyInputUI = _multiplyInputUI;
			multiplyInputUI.OnEndEdit = (Action<string>)Delegate.Combine(multiplyInputUI.OnEndEdit, new Action<string>(HandleMultiplicationInputBase));
			InputUI multiplyInputUI2 = _multiplyInputUI;
			multiplyInputUI2.OnSubmit = (Func<string, bool>)Delegate.Combine(multiplyInputUI2.OnSubmit, new Func<string, bool>(HandleMultiplicationInput));
			_multiplyInputUI.clearAfterSubmit = false;
		}

		private void OnTitleEdit()
		{
			_changeNameInput.InputField.text = _title;
			_changeNameInput.Activate();
		}

		private void OnSingleExportClick()
		{
			Seeder.Instance.SeedToClipboard(new List<EntryData> { ToEntryData() });
			Notification.Instance.Show("Seed copied to clipboard");
		}

		private void HandleMultiplicationInputBase(string value)
		{
			try
			{
				float num = float.Parse(value.Replace(".", ","));
				multiplier = num;
				TemplateManager.Instance.UpdateEntry(this);
			}
			catch (FormatException)
			{
				Notification.Instance.Show("Invalid multiplier value");
				UpdateMultiplierInput();
			}
			catch (ArgumentNullException)
			{
				Notification.Instance.Show("Multiplier value is empty");
				UpdateMultiplierInput();
			}
			catch (OverflowException)
			{
				Notification.Instance.Show("Multiplier value is too large");
				UpdateMultiplierInput();
			}
		}

		private bool HandleMultiplicationInput(string value)
		{
			HandleMultiplicationInputBase(value);
			return true;
		}

		private void ApplyEntryToShop()
		{
			List<Ingredient> list = new List<Ingredient>(_ingredients);
			Enumerator<ListingEntry> enumerator = _shop.listingEntries.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ListingEntry current = enumerator.Current;
				if (list.Count > 0 && list[0].name == current.ItemNameLabel.text)
				{
					current.QuantityInput.text = list[0].QuantityMultipliedBy(_multiplier).ToString();
					list.RemoveAt(0);
				}
				else
				{
					current.QuantityInput.text = "0";
				}
				current.QuantityInput.SendOnSubmit();
			}
			_shop.SetIsExpanded(true);
		}

		private void Close()
		{
			Destroy();
			TemplateManager.Instance.RemoveEntry(this);
		}

		private bool ChangeTitle(string value)
		{
			string oldTitle = _title;
			_title = value;
			_textTitle.text = value;
			TemplateManager.Instance.UpdateEntryTitle(oldTitle, this);
			return true;
		}
	}
	internal class ImmutableEntry
	{
		protected string _title;

		protected DeliveryShop _shop;

		protected Text _price;

		protected float _multiplier;

		protected Text _textTitle;

		protected GameObject _gameObject;

		protected List<Ingredient> _ingredients = new List<Ingredient>();

		protected GameObject _tooLarge;

		protected GameObject _insufficientBalance;

		protected string _shopName;

		protected Transform _parent;

		protected Image _headerImage;

		protected Text _shopGo;

		protected InputUI _multiplyInputUI;

		protected virtual string _prefabName => "ImmutableEntry";

		public string title => _title;

		public string shopName => _shopName;

		public virtual float multiplier
		{
			get
			{
				return _multiplier;
			}
			set
			{
				_multiplier = value;
				UpdateMultiplierInput();
				UpdateIngredientWithMultiplier();
			}
		}

		public GameObject gameObject => _gameObject;

		protected void UpdateMultiplierInput()
		{
			_multiplyInputUI.InputField.text = _multiplier.ToString().Replace(",", ".");
		}

		public ImmutableEntry(EntryData data, Transform parent)
		{
			DeliveryShop shop = PlayerSingleton<DeliveryApp>.Instance.GetShop(data.shopName);
			Init(data.title, shop, parent);
			AddIngredientFromEntryData(data);
			multiplier = data.multiplier;
		}

		public ImmutableEntry(string title, DeliveryShop shop, Transform parent)
		{
			Init(title, shop, parent);
			Enumerator<ListingEntry> enumerator = _shop.listingEntries.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ListingEntry current = enumerator.Current;
				if (current.QuantityInput.text != "0")
				{
					AddIngredient(current);
				}
			}
			multiplier = 1f;
		}

		protected virtual void Init(string title, DeliveryShop shop, Transform parent)
		{
			_parent = parent;
			_gameObject = AssetsManager.Instance.Instantiate(_prefabName);
			_gameObject.transform.SetParent(_parent, false);
			_textTitle = ((Component)_gameObject.transform.Find("Head/Header/Title")).GetComponent<Text>();
			_headerImage = ((Component)_gameObject.transform.Find("Head/Background")).GetComponent<Image>();
			_shopGo = ((Component)_gameObject.transform.Find("Head/ShopName")).GetComponent<Text>();
			Set(title, shop);
			_tooLarge = ((Component)_gameObject.transform.Find("Footer/TooLarge")).gameObject;
			_insufficientBalance = ((Component)_gameObject.transform.Find("Footer2/InsufficientBalance")).gameObject;
			_price = ((Component)_gameObject.transform.Find("Footer2/TotalCost")).GetComponent<Text>();
			Transform val = gameObject.transform.Find("Footer/Multiplier/MultiplierInput");
			_multiplyInputUI = new InputUI(((Component)val).GetComponent<InputField>());
		}

		protected void AddIngredientFromEntryData(EntryData data)
		{
			DeliveryShop shop = PlayerSingleton<DeliveryApp>.Instance.GetShop(data.shopName);
			List<IngredientData> list = new List<IngredientData>(data.ingredients);
			Enumerator<ListingEntry> enumerator = shop.listingEntries.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ListingEntry current = enumerator.Current;
				if (list.Count == 0)
				{
					break;
				}
				if (((ItemDefinition)current.MatchingListing.Item).ID == IngredientRegister.Instance.GetItemName(list[0].id))
				{
					AddIngredientWithQuantity(current, list[0].baseQuantity);
					list.RemoveAt(0);
				}
			}
		}

		protected void Set(string title, DeliveryShop shop)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			_title = title;
			_shop = shop;
			_shopName = ((Object)shop).name;
			_textTitle.text = title;
			((Graphic)((Component)_headerImage).GetComponent<Image>()).color = ((Graphic)shop.HeaderImage).color;
			_shopGo.text = ((Object)shop).name;
		}

		public EntryData ToEntryData()
		{
			List<IngredientData> list = new List<IngredientData>();
			foreach (Ingredient ingredient in _ingredients)
			{
				list.Add(new IngredientData(ingredient.id, ingredient.baseQuantity));
			}
			return new EntryData(_title, _multiplier, _shopName, list);
		}

		protected void UpdateIngredientWithMultiplier()
		{
			int num = 0;
			int num2 = 0;
			foreach (Ingredient ingredient in _ingredients)
			{
				int num3 = ingredient.QuantityMultipliedBy(_multiplier);
				ingredient.RebuildContent(_multiplier);
				num += ingredient.price * num3;
				num2 += (int)Math.Ceiling((double)num3 / (double)ingredient.stackLimit);
			}
			if (num2 > 16)
			{
				_tooLarge.SetActive(true);
			}
			else
			{
				_tooLarge.SetActive(false);
			}
			if ((float)num > NetworkSingleton<MoneyManager>.Instance.onlineBalance)
			{
				_insufficientBalance.SetActive(true);
			}
			else
			{
				_insufficientBalance.SetActive(false);
			}
			_price.text = "Total cost: $" + (200 + num).ToString("n0", CultureInfo.InvariantCulture);
		}

		protected void AddIngredientWithQuantity(ListingEntry entry, int quantity)
		{
			_ingredients.Add(new Ingredient(entry, this));
			_ingredients.Last().baseQuantity = quantity;
		}

		protected void AddIngredient(ListingEntry component)
		{
			_ingredients.Add(new Ingredient(component, this));
		}

		public void SetDataFromEntryData(EntryData data)
		{
			DeliveryShop shop = PlayerSingleton<DeliveryApp>.Instance.GetShop(data.shopName);
			Set(data.title, shop);
			List<IngredientData> list = new List<IngredientData>(data.ingredients);
			foreach (Ingredient ingredient in _ingredients)
			{
				ingredient.Destroy();
			}
			_ingredients.Clear();
			AddIngredientFromEntryData(data);
			multiplier = data.multiplier;
			TemplateManager.Instance.template.RebuildEveryLayout();
		}

		public void Destroy()
		{
			_ingredients.Clear();
			ObjectExt.Destroy((Object)(object)gameObject);
		}
	}
	internal enum AssetAccessType
	{
		FileSystem,
		Resources
	}
	internal abstract class Asset
	{
		public string name { get; }

		public string path { get; private set; }

		public AssetAccessType assetAccessType { get; }

		public bool valid { get; private set; } = true;


		public Asset(AssetAccessType assetAccessType, string name, string path)
		{
			this.assetAccessType = assetAccessType;
			this.name = name;
			switch (assetAccessType)
			{
			case AssetAccessType.FileSystem:
				LoadFromFile(path);
				break;
			case AssetAccessType.Resources:
				LoadFromResources(path);
				break;
			default:
				throw new ArgumentOutOfRangeException("assetAccessType", assetAccessType, null);
			}
		}

		private void LoadFromFile(string path)
		{
			this.path = Path.Combine(ModConfig.AssetPath, path);
			if (!File.Exists(this.path))
			{
				Melon<Core>.Logger.Warning("Cannot find asset " + this.path);
				valid = false;
			}
			else
			{
				LoadFromFileBase(this.path);
			}
		}

		private void LoadFromResources(string path)
		{
			this.path = AssetsManager.Instance.resourcesPrefix + path;
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(this.path);
			if (stream == null)
			{
				Melon<Core>.Logger.Warning("Cannot find asset " + this.path);
				valid = false;
			}
			else
			{
				LoadFromResourcesBase(stream);
			}
		}

		protected abstract void LoadFromFileBase(string path);

		protected abstract void LoadFromResourcesBase(Stream stream);

		public abstract void Unload();
	}
	internal class AssetBundle : Asset
	{
		public Il2CppAssetBundle assetBundle { get; private set; }

		public AssetBundle(AssetAccessType assetAccessType, string name, string path)
			: base(assetAccessType, name, path)
		{
			if (assetBundle == null)
			{
				Melon<Core>.Logger.Warning("Cannot load asset " + base.path);
			}
		}

		public GameObject Instantiate()
		{
			if (base.valid)
			{
				GameObject val = assetBundle.LoadAsset<GameObject>(base.name);
				if ((Object)(object)val == (Object)null)
				{
					throw new Exception($"Asset bundle prefab {base.name} is null on instantiation. Please verify that {base.name} match the exported unity gameobject name in the editor");
				}
				return Object.Instantiate<GameObject>(val);
			}
			return null;
		}

		public override void Unload()
		{
			if (base.valid)
			{
				assetBundle.Unload(true);
			}
		}

		protected override void LoadFromFileBase(string path)
		{
			assetBundle = Il2CppAssetBundleManager.LoadFromFile(path);
		}

		protected override void LoadFromResourcesBase(Stream stream)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			MemoryStream val = new MemoryStream(Il2CppStructArray<byte>.op_Implicit(array));
			assetBundle = Il2CppAssetBundleManager.LoadFromStream((Stream)(object)val);
			((Stream)val).Close();
		}
	}
	internal class AssetFile : Asset
	{
		public string content { get; private set; }

		public AssetFile(AssetAccessType assetAccessType, string name, string path)
			: base(assetAccessType, name, path)
		{
			if (string.IsNullOrEmpty(content))
			{
				Melon<Core>.Logger.Warning("Cannot load asset " + base.path);
			}
		}

		public override void Unload()
		{
			content = "";
		}

		protected override void LoadFromFileBase(string path)
		{
			content = File.ReadAllText(path);
		}

		protected override void LoadFromResourcesBase(Stream stream)
		{
			using StreamReader streamReader = new StreamReader(stream);
			content = streamReader.ReadToEnd();
		}
	}
	internal class AssetsManager
	{
		private List<Asset> assets = new List<Asset>();

		private static AssetsManager _instance;

		public string resourcesPrefix = "";

		public static AssetsManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new AssetsManager();
				}
				return _instance;
			}
		}

		private AssetsManager()
		{
		}

		public void LoadAssetBundleFromPath(string name, string path)
		{
			assets.Add(new AssetBundle(AssetAccessType.FileSystem, name, path));
		}

		public void LoadAssetBundleFromResources(string name, string path)
		{
			assets.Add(new AssetBundle(AssetAccessType.Resources, name, path));
		}

		public void LoadFileFromPath(string name, string path)
		{
			assets.Add(new AssetFile(AssetAccessType.FileSystem, name, path));
		}

		public void LoadFileFromResources(string name, string path)
		{
			assets.Add(new AssetFile(AssetAccessType.Resources, name, path));
		}

		public AssetBundle GetAssetBundle(string name)
		{
			foreach (Asset asset in assets)
			{
				if (asset.name == name && asset is AssetBundle)
				{
					return (AssetBundle)asset;
				}
			}
			Melon<Core>.Logger.Warning("Get: Cannot find asset " + name);
			return null;
		}

		public AssetFile GetAssetFile(string name)
		{
			foreach (Asset asset in assets)
			{
				if (asset.name == name && asset is AssetFile)
				{
					return (AssetFile)asset;
				}
			}
			Melon<Core>.Logger.Warning("Get: Cannot find asset " + name);
			return null;
		}

		public void RemoveAsset(string name)
		{
			foreach (Asset asset in assets)
			{
				if (asset.name == name)
				{
					asset.Unload();
					assets.Remove(asset);
					return;
				}
			}
			Melon<Core>.Logger.Warning("Remove: Cannot find asset " + name);
		}

		public GameObject Instantiate(string name)
		{
			foreach (Asset asset in assets)
			{
				if (asset.name == name && asset is AssetBundle)
				{
					return ((AssetBundle)asset).Instantiate();
				}
			}
			Melon<Core>.Logger.Warning("Instantiate: Cannot find asset " + name);
			return null;
		}
	}
	public class Core : MelonMod
	{
		private string _scene;

		private bool _loaded = false;

		private DeliveryShop _deliveryShop = null;

		private bool _errorMode = false;

		private InputUI templateSeedInput = null;

		private InputUI templateNameInput = null;

		public override void OnInitializeMelon()
		{
			try
			{
				if (!Directory.Exists(ModConfig.ModRootFile))
				{
					Directory.CreateDirectory(ModConfig.ModRootFile);
				}
				AssetsManager.Instance.resourcesPrefix = "DeliverySaver.assets.";
				TemplateManager.Instance.Init();
				AssetsManager.Instance.LoadFileFromResources("Signature", "signature.txt");
				AssetsManager.Instance.LoadAssetBundleFromResources("SaveButton", "ui.savebutton");
				AssetsManager.Instance.LoadAssetBundleFromResources("TemplateName", "ui.templatename");
				AssetsManager.Instance.LoadAssetBundleFromResources("Notification", "ui.notification");
				AssetsManager.Instance.LoadAssetBundleFromResources("TemplateSeed", "ui.templateseed");
				Comparator.Instance.Init();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("There is a issue pls report it to the developer");
				((MelonBase)this).LoggerInstance.Error((object)ex);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_scene = sceneName;
			if (_scene != "Main")
			{
				_errorMode = false;
				_loaded = false;
			}
		}

		public override void OnApplicationQuit()
		{
			try
			{
				TemplateManager.Instance.Save();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("There is a issue pls report it to the developer");
				((MelonBase)this).LoggerInstance.Error((object)ex);
			}
		}

		public override void OnUpdate()
		{
			if (_scene == "Main" && _loaded && !_errorMode)
			{
				TemplateManager.Instance.template.OnUpdate();
			}
			if (!(_scene == "Main") || _errorMode || _loaded)
			{
				return;
			}
			try
			{
				if (Object.op_Implicit((Object)(object)PlayerSingleton<DeliveryApp>.Instance) && Object.op_Implicit((Object)(object)NetworkSingleton<GameManager>.Instance) && Object.op_Implicit((Object)(object)NetworkSingleton<MoneyManager>.Instance) && NetworkSingleton<GameManager>.Instance.seed != 0 && (Object)(object)((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).appIconButton != (Object)null && Object.op_Implicit((Object)(object)Singleton<SaveManager>.Instance))
				{
					InitSaveListener();
					IngredientRegister.Instance.Synchronize();
					TemplateManager.Instance.CreateTemplateGameObject();
					InitTemplateName();
					InitTemplateSeed();
					AddAppSaveButton(PlayerSingleton<DeliveryApp>.Instance);
					AddNotificationPanel(PlayerSingleton<DeliveryApp>.Instance);
					TemplateManager.Instance.Load();
					Comparator.Instance.Instantiate();
					_loaded = true;
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("There is a issue pls report it to the developer");
				((MelonBase)this).LoggerInstance.Error((object)ex);
				_errorMode = true;
			}
		}

		private void InitSaveListener()
		{
			Action action = delegate
			{
				TemplateManager.Instance.Save();
			};
			Singleton<SaveManager>.Instance.onSaveStart.AddListener(UnityAction.op_Implicit(action));
		}

		private void InitTemplateSeed()
		{
			templateSeedInput = new InputUI("TemplateSeed", "InputName");
			InputUI inputUI = templateSeedInput;
			inputUI.OnSubmit = (Func<string, bool>)Delegate.Combine(inputUI.OnSubmit, new Func<string, bool>(OnSeedEnter));
			Action action = delegate
			{
				templateSeedInput.Deactivate();
			};
			((UnityEvent)((Component)templateSeedInput.gameObject.transform.Find("Close")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action));
			Transform val = TemplateManager.Instance.template.gameObject.transform.Find("Mask/Content/ImportSeed");
			((UnityEvent)((Component)val).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(templateSeedInput.ActivateAsAction()));
			Action action2 = delegate
			{
				templateSeedInput.InputField.SendOnSubmit();
			};
			((UnityEvent)((Component)templateSeedInput.gameObject.transform.Find("Validate")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action2));
		}

		private bool OnSeedEnter(string seed)
		{
			try
			{
				List<EntryData> list = Seeder.Instance.Decode<List<EntryData>>(seed);
				if (list == null)
				{
					throw new EntryIsEmpty();
				}
				if (list.Count == 1)
				{
					TemplateManager.Instance.AddEntryData(list[0]);
				}
				else
				{
					TemplateManager.Instance.AddEntriesData(list);
				}
				return true;
			}
			catch (InvalidCastException)
			{
				Notification.Instance.Show("Invalid data from seed");
				return false;
			}
			catch (ArgumentNullException)
			{
				Notification.Instance.Show("Seed is empty");
				return false;
			}
			catch (OverflowException)
			{
				Notification.Instance.Show("Seed is too large");
				return false;
			}
			catch (EntryIsEmpty)
			{
				Notification.Instance.Show("Cannot add a empty entry");
				return false;
			}
			catch (Exception ex4)
			{
				((MelonBase)this).LoggerInstance.Error((object)ex4);
				Notification.Instance.Show("Invalid seed");
				return false;
			}
		}

		private void InitTemplateName()
		{
			templateNameInput = new InputUI("TemplateName", "InputName");
			InputUI inputUI = templateNameInput;
			inputUI.OnSubmit = (Func<string, bool>)Delegate.Combine(inputUI.OnSubmit, new Func<string, bool>(OnEntryNameValidated));
			Action action = delegate
			{
				templateNameInput.Deactivate();
			};
			((UnityEvent)((Component)templateNameInput.gameObject.transform.Find("Close")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action));
			Action action2 = delegate
			{
				templateNameInput.InputField.SendOnSubmit();
			};
			((UnityEvent)((Component)templateNameInput.gameObject.transform.Find("Validate")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action2));
		}

		private void AddNotificationPanel(DeliveryApp app)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Notification.Instance.Instantiate();
			val.transform.SetParent(((Component)((App<DeliveryApp>)(object)app).appContainer).transform, false);
			val.transform.localPosition = new Vector3(0f, 200f, 0f);
		}

		private void AddAppSaveButton(DeliveryApp app)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<DeliveryShop> enumerator = app.deliveryShops.GetEnumerator();
			while (enumerator.MoveNext())
			{
				DeliveryShop deliveryShop = enumerator.Current;
				Transform panel = GetPanel(deliveryShop);
				if (Object.op_Implicit((Object)(object)panel))
				{
					GameObject val = AssetsManager.Instance.Instantiate("SaveButton");
					Button component = val.GetComponent<Button>();
					val.transform.SetParent(panel, false);
					val.transform.localPosition = new Vector3(122f, -13f, 0f);
					Action action = delegate
					{
						OnShopSelected(deliveryShop);
					};
					((UnityEvent)component.onClick).AddListener(UnityAction.op_Implicit(action));
				}
				else
				{
					((MelonBase)this).LoggerInstance.Warning("Cannot get panel for deliveryShop '" + ((Object)deliveryShop).name + "'");
				}
			}
		}

		private void OnShopSelected(DeliveryShop deliveryShop)
		{
			if (HasComponent(deliveryShop))
			{
				_deliveryShop = deliveryShop;
				templateNameInput.Activate();
			}
		}

		private bool OnEntryNameValidated(string name)
		{
			if (string.IsNullOrEmpty(templateNameInput.InputField.text))
			{
				Notification.Instance.Show("Name cannot be empty");
				return false;
			}
			TemplateManager.Instance.AddEntry(templateNameInput.InputField.text, _deliveryShop);
			return true;
		}

		private bool HasComponent(DeliveryShop shop)
		{
			Enumerator<ListingEntry> enumerator = shop.listingEntries.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ListingEntry current = enumerator.Current;
				if (current.QuantityInput.text != "0")
				{
					return true;
				}
			}
			return false;
		}

		private Transform GetPanel(DeliveryShop deliveryShop)
		{
			int childCount = ((Transform)deliveryShop.ContentsContainer).childCount;
			for (int i = 0; i < childCount; i++)
			{
				GameObject gameObject = ((Component)((Transform)deliveryShop.ContentsContainer).GetChild(i)).gameObject;
				if (((Object)gameObject).name == "Panel")
				{
					return gameObject.transform;
				}
			}
			return null;
		}
	}
	internal class IngredientRegister
	{
		private uint _counter;

		private static IngredientRegister _instance;

		private Dictionary<string, uint> _ingredientAttributor = new Dictionary<string, uint>();

		public static IngredientRegister Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new IngredientRegister();
				}
				return _instance;
			}
		}

		public void Synchronize()
		{
			if (_ingredientAttributor.Count != 0)
			{
				return;
			}
			Enumerator<DeliveryShop> enumerator = PlayerSingleton<DeliveryApp>.Instance.deliveryShops.GetEnumerator();
			while (enumerator.MoveNext())
			{
				DeliveryShop current = enumerator.Current;
				Enumerator<ListingEntry> enumerator2 = current.listingEntries.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					ListingEntry current2 = enumerator2.Current;
					if (!_ingredientAttributor.ContainsKey(((ItemDefinition)current2.MatchingListing.Item).ID))
					{
						_ingredientAttributor.Add(((ItemDefinition)current2.MatchingListing.Item).ID, _counter);
						_counter++;
					}
				}
			}
		}

		public uint GetItemID(string ingredientName)
		{
			return _ingredientAttributor[ingredientName];
		}

		public string GetItemName(uint id)
		{
			return _ingredientAttributor.First((KeyValuePair<string, uint> e) => e.Value == id).Key;
		}
	}
	internal class InputUI
	{
		private GameObject _parent;

		private InputField _inputField;

		public Action<string> OnEndEdit = delegate
		{
		};

		public Action<string> OnValueChanged = delegate
		{
		};

		public Func<string, bool> OnSubmit = (string _) => true;

		public bool clearAfterSubmit = true;

		public InputField InputField => _inputField;

		public GameObject gameObject => _parent;

		public InputUI(InputField field)
		{
			InitInput(field);
		}

		public InputUI(string assetName, string inputName)
		{
			GameObject val = AssetsManager.Instance.Instantiate(assetName);
			val.transform.SetParent(((Component)((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).appContainer).transform, false);
			val.SetActive(false);
			_parent = val;
			InitInput(((Component)_parent.transform.Find(inputName)).GetComponent<InputField>());
		}

		private void InitInput(InputField field)
		{
			_inputField = field;
			Action<string> action = delegate(string value)
			{
				OnValueChanged(value);
			};
			Action<string> action2 = delegate(string value)
			{
				OnEndEdit(value);
				if (_inputField.wasCanceled)
				{
					Deactivate();
					InputField.text = value;
				}
			};
			Action<string> action3 = delegate(string value)
			{
				if (OnSubmit(value))
				{
					Deactivate();
				}
			};
			((UnityEvent<string>)(object)_inputField.onEndEdit).AddListener(UnityAction<string>.op_Implicit(action2));
			((UnityEvent<string>)(object)_inputField.onSubmit).AddListener(UnityAction<string>.op_Implicit(action3));
			((UnityEvent<string>)(object)_inputField.onValueChanged).AddListener(UnityAction<string>.op_Implicit(action));
			((UnityEvent<string>)(object)_inputField.onValueChange).AddListener(UnityAction<string>.op_Implicit(OnValueChanged));
		}

		public void Deactivate()
		{
			if ((Object)(object)_parent != (Object)null)
			{
				_parent.SetActive(false);
			}
			Singleton<GameInput>.Instance.PlayerInput.ActivateInput();
			if (clearAfterSubmit)
			{
				_inputField.text = "";
			}
		}

		public Action ActivateAsAction()
		{
			return delegate
			{
				Activate();
			};
		}

		public void Activate()
		{
			if ((Object)(object)_parent != (Object)null)
			{
				_parent.SetActive(true);
			}
			Singleton<GameInput>.Instance.PlayerInput.DeactivateInput();
			((Selectable)_inputField).Select();
		}
	}
	internal static class ModConfig
	{
		public static string ModRootFile => Path.Combine(Application.dataPath, "..", "Mods", "DeliverySaver");

		public static string AssetPath => Path.Combine(ModRootFile, "assets");

		public static string GetFilePath(string fileName)
		{
			return Path.Combine(ModRootFile, fileName);
		}
	}
	internal class Notification
	{
		private static Notification _instance;

		private GameObject _notification;

		public static Notification Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new Notification();
				}
				return _instance;
			}
		}

		private Notification()
		{
		}

		public GameObject Instantiate()
		{
			_notification = AssetsManager.Instance.Instantiate("Notification");
			return _notification;
		}

		public void Show(string message)
		{
			Text component = ((Component)_notification.transform.Find("Message")).GetComponent<Text>();
			component.text = message;
			_notification.GetComponent<Animator>().Play("NotificationAnim");
		}
	}
	internal class Seeder
	{
		private static Seeder _instance;

		private string signature = AssetsManager.Instance.GetAssetFile("Signature").content;

		public static Seeder Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new Seeder();
				}
				return _instance;
			}
		}

		public string Seed(object obj)
		{
			string text = JsonConvert.SerializeObject(obj);
			byte[] bytes = Encoding.UTF8.GetBytes(signature + text);
			return Convert.ToBase64String(bytes, Base64FormattingOptions.None);
		}

		public void SeedToClipboard(object obj)
		{
			GUIUtility.systemCopyBuffer = Seed(obj);
		}

		public T Decode<T>(string encoded) where T : class
		{
			if (encoded == "")
			{
				throw new ArgumentNullException();
			}
			byte[] bytes = Convert.FromBase64String(encoded);
			string @string = Encoding.UTF8.GetString(bytes);
			if (!@string.StartsWith(signature))
			{
				throw new Exception("Invalid seed");
			}
			string text = @string.Substring(signature.Length);
			return JsonConvert.DeserializeObject<T>(text);
		}
	}
	internal enum SaveState
	{
		Save,
		PreventSave
	}
	public class EntryAlreadyExistsException : Exception
	{
	}
	public class EntryIsEmpty : Exception
	{
	}
	internal class GameInfo
	{
		private static GameInfo _instance;

		public string organisationName;

		public int seed;

		public static GameInfo Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new GameInfo();
				}
				return _instance;
			}
		}

		public string GameName => $"{NetworkSingleton<GameManager>.Instance.OrganisationName}_{NetworkSingleton<GameManager>.Instance.seed}";

		public GameInfo()
		{
			organisationName = NetworkSingleton<GameManager>.Instance.OrganisationName;
			seed = NetworkSingleton<GameManager>.Instance.seed;
		}
	}
	internal class SaveCache
	{
		public SaveState state = SaveState.Save;

		public List<EntryData> entries = new List<EntryData>();

		public List<EntryData> ToJson()
		{
			return entries;
		}
	}
	internal class TemplateManager
	{
		private Dictionary<string, SaveCache> _toSaves = new Dictionary<string, SaveCache>();

		private Template _template;

		private static TemplateManager _instance;

		public static TemplateManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new TemplateManager();
				}
				return _instance;
			}
		}

		public Template template => _template;

		public void Init()
		{
			AssetsManager.Instance.LoadAssetBundleFromResources("Template", "ui.template");
			AssetsManager.Instance.LoadAssetBundleFromResources("Entry", "ui.entry");
			AssetsManager.Instance.LoadAssetBundleFromResources("ImmutableEntry", "ui.immutableentry");
			AssetsManager.Instance.LoadAssetBundleFromResources("Component", "ui.component");
		}

		public void CreateTemplateGameObject()
		{
			_template = new Template();
		}

		public bool AddEntryData(EntryData entry)
		{
			EntryData entryData = FindDataFromTitle(entry.title);
			if (entryData != null)
			{
				Comparator.Instance.Compare(entry, entryData);
				return false;
			}
			AddEntryDataBase(entry);
			_toSaves[GameInfo.Instance.GameName].entries.Add(entry);
			return true;
		}

		private void AddEntryDataBase(EntryData entry)
		{
			_template.AddEntryData(entry);
			_template.RebuildLayout();
			_template.Open();
		}

		public void AddEntriesData(List<EntryData> entries)
		{
			List<EntryData> entries2 = _toSaves[GameInfo.Instance.GameName].entries;
			List<EntryData> list = entries.Intersect(entries2).ToList();
			List<EntryData> list2 = entries.Except(list).ToList();
			foreach (EntryData item in list2)
			{
				AddEntryData(item);
			}
			Comparator.Instance.Compare(list, entries2.Intersect(entries).ToList());
		}

		public bool AddEntry(string name, DeliveryShop shop)
		{
			EntryData entryData = FindDataFromTitle(name);
			if (entryData != null)
			{
				Comparator.Instance.Compare(EntryData.FromDeliveryShop(name, entryData.multiplier, shop), entryData);
				return false;
			}
			_template.AddEntry(name, shop);
			_toSaves[GameInfo.Instance.GameName].entries.Add(_template.GetLastEntry().ToEntryData());
			_template.RebuildLayout();
			_template.Open();
			return true;
		}

		public void SetEntry(ImmutableEntry newEntry)
		{
			EntryData entryData = newEntry.ToEntryData();
			SetEntryData(entryData);
		}

		public void SetEntryData(EntryData newEntryData)
		{
			int num = _toSaves[GameInfo.Instance.GameName].entries.FindIndex((EntryData ed) => ed.title == newEntryData.title);
			if (num != -1)
			{
				_toSaves[GameInfo.Instance.GameName].entries[num] = newEntryData;
				_template.SetEntryData(newEntryData);
				_template.RebuildLayout();
				return;
			}
			throw new Exception("EntryData " + newEntryData.title + " has not been found");
		}

		public void UpdateEntryTitle(string oldTitle, ImmutableEntry entry)
		{
			for (int i = 0; i < _toSaves[GameInfo.Instance.GameName].entries.Count; i++)
			{
				if (_toSaves[GameInfo.Instance.GameName].entries[i].title == oldTitle)
				{
					_toSaves[GameInfo.Instance.GameName].entries[i] = entry.ToEntryData();
					break;
				}
			}
		}

		public void UpdateEntry(ImmutableEntry entry)
		{
			for (int i = 0; i < _toSaves[GameInfo.Instance.GameName].entries.Count; i++)
			{
				if (_toSaves[GameInfo.Instance.GameName].entries[i].title == entry.title)
				{
					_toSaves[GameInfo.Instance.GameName].entries[i] = entry.ToEntryData();
					break;
				}
			}
		}

		public EntryData[] GetActualTemplateData()
		{
			return _toSaves[GameInfo.Instance.GameName].entries.ToArray();
		}

		public void Save()
		{
			foreach (KeyValuePair<string, SaveCache> toSafe in _toSaves)
			{
				if (toSafe.Value.state == SaveState.Save)
				{
					string path = Path.Combine(ModConfig.ModRootFile, "template_" + toSafe.Key + "_v2.json");
					string contents = JsonConvert.SerializeObject((object)toSafe.Value.ToJson());
					File.WriteAllText(path, contents);
				}
			}
		}

		public void Load()
		{
			string gameName = GameInfo.Instance.GameName;
			if (_toSaves.ContainsKey(gameName))
			{
				foreach (EntryData entry in _toSaves[gameName].entries)
				{
					AddEntryDataBase(entry);
				}
				return;
			}
			if (!_toSaves.ContainsKey(gameName))
			{
				_toSaves.Add(gameName, new SaveCache
				{
					entries = new List<EntryData>(),
					state = SaveState.Save
				});
			}
			string path = Path.Combine(ModConfig.ModRootFile, "template_" + GameInfo.Instance.GameName + "_v2.json");
			if (File.Exists(path))
			{
				try
				{
					string text = File.ReadAllText(path);
					List<EntryData> list = JsonConvert.DeserializeObject<List<EntryData>>(text);
					foreach (EntryData item in list)
					{
						AddEntryData(item);
					}
					if (_toSaves[GameInfo.Instance.GameName].state == SaveState.PreventSave)
					{
						_toSaves[GameInfo.Instance.GameName].state = SaveState.Save;
					}
				}
				catch (Exception ex)
				{
					_toSaves[GameInfo.Instance.GameName].state = SaveState.PreventSave;
					throw new Exception(ex.Message);
				}
			}
			_template.Close();
		}

		internal void RemoveEntry(ImmutableEntry entry)
		{
			_template.RemoveEntry(entry);
			_toSaves[GameInfo.Instance.GameName].entries.Remove(FindDataFromEntry(entry));
		}

		private EntryData FindDataFromEntry(ImmutableEntry entry)
		{
			return _toSaves[GameInfo.Instance.GameName].entries.Find((EntryData e) => e.title == entry.title);
		}

		private EntryData FindDataFromTitle(string title)
		{
			return _toSaves[GameInfo.Instance.GameName].entries.Find((EntryData e) => e.title == title);
		}

		public bool IsEntryRegister(string title)
		{
			return _toSaves[GameInfo.Instance.GameName].entries.Find((EntryData e) => e.title == title) != null;
		}
	}
	internal class Template
	{
		private Button _openButton;

		private AssetBundle _entry;

		private Transform _templates;

		private VerticalLayoutGroup _vls;

		private bool _isOpen;

		private bool _deliveryAppWasEnabled;

		private Animator _animator;

		private bool _rebuildLayout = false;

		private float _timer = 0f;

		private List<Entry> _entries = new List<Entry>();

		private Transform _container;

		public GameObject gameObject { get; private set; }

		public bool isOpen => _isOpen;

		public Transform templateContent => _templates;

		public Template()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			_container = ((Component)((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).appContainer).transform;
			gameObject = AssetsManager.Instance.Instantiate("Template");
			gameObject.transform.SetParent(_container, false);
			gameObject.transform.localPosition = new Vector3(393f, -32f, 0f);
			_templates = gameObject.transform.Find("Mask/Content/Entries/Scroll/View/Templates");
			_vls = ((Component)_templates).GetComponent<VerticalLayoutGroup>();
			Action action = delegate
			{
				OnExportTemplate();
			};
			((UnityEvent)((Component)gameObject.transform.Find("Mask/Content/ExportSeed")).GetComponent<Button>().onClick).AddListener(UnityAction.op_Implicit(action));
			_animator = ((Component)gameObject.transform.Find("Mask/Content")).GetComponent<Animator>();
			_openButton = ((Component)gameObject.transform.Find("Mask/Content/Open")).GetComponent<Button>();
			Action action2 = delegate
			{
				RebuildEveryLayout();
			};
			Action action3 = delegate
			{
				_isOpen = !_isOpen;
			};
			((UnityEvent)_openButton.onClick).AddListener(UnityAction.op_Implicit(action3));
			((UnityEvent)_openButton.onClick).AddListener(UnityAction.op_Implicit(action2));
			_isOpen = false;
			Action action4 = delegate
			{
				if (_isOpen)
				{
					_animator.SetTrigger("OpenFast");
				}
			};
			((UnityEvent)((App<DeliveryApp>)(object)PlayerSingleton<DeliveryApp>.Instance).appIconButton.onClick).AddListener(UnityAction.op_Implicit(action4));
		}

		private void OnExportTemplate()
		{
			EntryData[] actualTemplateData = TemplateManager.Instance.GetActualTemplateData();
			Seeder.Instance.SeedToClipboard(actualTemplateData);
			Notification.Instance.Show("Template seed copied to clipboard");
		}

		public void RebuildEveryLayout()
		{
			foreach (Entry entry in _entries)
			{
				GUIUtils.MarkRebuildLayout(entry.gameObject.GetComponent<VerticalLayoutGroup>());
			}
		}

		public void OnUpdate()
		{
			if (_rebuildLayout && _timer <= 0f)
			{
				GUIUtils.RebuildLayout(_vls);
				_rebuildLayout = false;
				_timer = 0f;
			}
			if (_timer > 0f)
			{
				_timer -= Time.deltaTime;
			}
		}

		public Entry GetLastEntry()
		{
			return _entries.Last();
		}

		public Entry[] GetAllEntries()
		{
			return _entries.ToArray();
		}

		public void AddEntry(string name, DeliveryShop shop)
		{
			_entries.Add(new Entry(name, shop, ((Component)templateContent).transform));
		}

		public void AddEntryData(EntryData data)
		{
			_entries.Add(new Entry(data, ((Component)templateContent).transform));
		}

		internal void RemoveEntry(ImmutableEntry entry)
		{
			_entries.Remove((Entry)entry);
		}

		public void RebuildLayout()
		{
			_timer = Time.deltaTime;
			_rebuildLayout = true;
		}

		internal void Open()
		{
			if (!isOpen)
			{
				((UnityEvent)_openButton.onClick).Invoke();
			}
		}

		internal void Close()
		{
			if (isOpen)
			{
				((UnityEvent)_openButton.onClick).Invoke();
			}
		}

		public void SetEntry(Entry newEntry)
		{
			int num = _entries.IndexOf(newEntry);
			if (num != -1)
			{
				_entries[num] = newEntry;
				return;
			}
			throw new Exception("Entry " + newEntry.title + " has not been found in template");
		}

		public void SetEntryData(EntryData newEntryData)
		{
			int num = _entries.FindIndex((Entry e) => e.title == newEntryData.title);
			if (num != -1)
			{
				_entries[num].SetDataFromEntryData(newEntryData);
				return;
			}
			throw new Exception("EntryData " + newEntryData.title + " has not been found in template");
		}
	}
}