Skip to content

+EA 23.62 Nightly hotfix 1 - Plugin.BaseCore

December 21, 2024

0 file modified. 117 new files created.

Important Changes

None.

+ArticleStyle

File Created
cs
public enum ArticleStyle
{
	Default,
	None,
	The
}

+AutodumpFlag

File Created
cs
public enum AutodumpFlag
{
	existing,
	sameCategory,
	none,
	distribution
}

+CWPSTRUCT

File Created
cs
using System;

namespace B83.Win32;

public struct CWPSTRUCT
{
	public IntPtr lParam;

	public IntPtr wParam;

	public WM message;

	public IntPtr hwnd;
}

+EnumThreadDelegate

File Created
cs
using System;

namespace B83.Win32;

public delegate bool EnumThreadDelegate(IntPtr Hwnd, IntPtr lParam);

+HookProc

File Created
cs
using System;

namespace B83.Win32;

public delegate IntPtr HookProc(int code, IntPtr wParam, ref MSG lParam);

+HookType

File Created
cs
namespace B83.Win32;

public enum HookType
{
	WH_JOURNALRECORD,
	WH_JOURNALPLAYBACK,
	WH_KEYBOARD,
	WH_GETMESSAGE,
	WH_CALLWNDPROC,
	WH_CBT,
	WH_SYSMSGFILTER,
	WH_MOUSE,
	WH_HARDWARE,
	WH_DEBUG,
	WH_SHELL,
	WH_FOREGROUNDIDLE,
	WH_CALLWNDPROCRET,
	WH_KEYBOARD_LL,
	WH_MOUSE_LL
}

+MSG

File Created
cs
using System;

namespace B83.Win32;

public struct MSG
{
	public IntPtr hwnd;

	public WM message;

	public IntPtr wParam;

	public IntPtr lParam;

	public ushort time;

	public POINT pt;
}

+POINT

File Created
cs
namespace B83.Win32;

public struct POINT
{
	public int x;

	public int y;

	public POINT(int aX, int aY)
	{
		x = aX;
		y = aY;
	}

	public override string ToString()
	{
		return "(" + x + ", " + y + ")";
	}
}

+RECT

File Created
cs
namespace B83.Win32;

public struct RECT
{
	public int Left;

	public int Top;

	public int Right;

	public int Bottom;

	public RECT(int left, int top, int right, int bottom)
	{
		Left = left;
		Top = top;
		Right = right;
		Bottom = bottom;
	}

	public override string ToString()
	{
		return "(" + Left + ", " + Top + ", " + Right + ", " + Bottom + ")";
	}
}

+UnityDragAndDropHook

File Created
cs
using System;
using System.Collections.Generic;
using System.Text;
using AOT;

namespace B83.Win32;

public static class UnityDragAndDropHook
{
	public delegate void DroppedFilesEvent(List<string> aPathNames, POINT aDropPoint);

	private static uint threadId;

	private static IntPtr mainWindow = IntPtr.Zero;

	private static IntPtr m_Hook;

	private static string m_ClassName = "UnityWndClass";

	public static event DroppedFilesEvent OnDroppedFiles;

	[MonoPInvokeCallback(typeof(EnumThreadDelegate))]
	private static bool EnumCallback(IntPtr W, IntPtr _)
	{
		if (Window.IsWindowVisible(W) && (mainWindow == IntPtr.Zero || (m_ClassName != null && Window.GetClassName(W) == m_ClassName)))
		{
			mainWindow = W;
		}
		return true;
	}

	public static void InstallHook()
	{
		threadId = WinAPI.GetCurrentThreadId();
		if (threadId != 0)
		{
			Window.EnumThreadWindows(threadId, EnumCallback, IntPtr.Zero);
		}
		IntPtr moduleHandle = WinAPI.GetModuleHandle(null);
		m_Hook = WinAPI.SetWindowsHookEx(HookType.WH_GETMESSAGE, Callback, moduleHandle, threadId);
		WinAPI.DragAcceptFiles(mainWindow, fAccept: true);
	}

	public static void UninstallHook()
	{
		WinAPI.UnhookWindowsHookEx(m_Hook);
		WinAPI.DragAcceptFiles(mainWindow, fAccept: false);
		m_Hook = IntPtr.Zero;
	}

	[MonoPInvokeCallback(typeof(HookProc))]
	private static IntPtr Callback(int code, IntPtr wParam, ref MSG lParam)
	{
		if (code == 0 && lParam.message == WM.DROPFILES)
		{
			WinAPI.DragQueryPoint(lParam.wParam, out var pos);
			uint num = WinAPI.DragQueryFile(lParam.wParam, uint.MaxValue, null, 0u);
			StringBuilder stringBuilder = new StringBuilder(1024);
			List<string> list = new List<string>();
			for (uint num2 = 0u; num2 < num; num2++)
			{
				int num3 = (int)WinAPI.DragQueryFile(lParam.wParam, num2, stringBuilder, 1024u);
				list.Add(stringBuilder.ToString(0, num3));
				stringBuilder.Length = 0;
			}
			WinAPI.DragFinish(lParam.wParam);
			if (UnityDragAndDropHook.OnDroppedFiles != null)
			{
				UnityDragAndDropHook.OnDroppedFiles(list, pos);
			}
		}
		return WinAPI.CallNextHookEx(m_Hook, code, wParam, ref lParam);
	}
}

+WM

File Created
cs
using System;

namespace B83.Win32;

public enum WM : uint
{
	NULL = 0u,
	CREATE = 1u,
	DESTROY = 2u,
	MOVE = 3u,
	SIZE = 5u,
	ACTIVATE = 6u,
	SETFOCUS = 7u,
	KILLFOCUS = 8u,
	ENABLE = 10u,
	SETREDRAW = 11u,
	SETTEXT = 12u,
	GETTEXT = 13u,
	GETTEXTLENGTH = 14u,
	PAINT = 15u,
	CLOSE = 16u,
	QUERYENDSESSION = 17u,
	QUERYOPEN = 19u,
	ENDSESSION = 22u,
	QUIT = 18u,
	ERASEBKGND = 20u,
	SYSCOLORCHANGE = 21u,
	SHOWWINDOW = 24u,
	WININICHANGE = 26u,
	SETTINGCHANGE = 26u,
	DEVMODECHANGE = 27u,
	ACTIVATEAPP = 28u,
	FONTCHANGE = 29u,
	TIMECHANGE = 30u,
	CANCELMODE = 31u,
	SETCURSOR = 32u,
	MOUSEACTIVATE = 33u,
	CHILDACTIVATE = 34u,
	QUEUESYNC = 35u,
	GETMINMAXINFO = 36u,
	PAINTICON = 38u,
	ICONERASEBKGND = 39u,
	NEXTDLGCTL = 40u,
	SPOOLERSTATUS = 42u,
	DRAWITEM = 43u,
	MEASUREITEM = 44u,
	DELETEITEM = 45u,
	VKEYTOITEM = 46u,
	CHARTOITEM = 47u,
	SETFONT = 48u,
	GETFONT = 49u,
	SETHOTKEY = 50u,
	GETHOTKEY = 51u,
	QUERYDRAGICON = 55u,
	COMPAREITEM = 57u,
	GETOBJECT = 61u,
	COMPACTING = 65u,
	[Obsolete]
	COMMNOTIFY = 68u,
	WINDOWPOSCHANGING = 70u,
	WINDOWPOSCHANGED = 71u,
	[Obsolete]
	POWER = 72u,
	COPYDATA = 74u,
	CANCELJOURNAL = 75u,
	NOTIFY = 78u,
	INPUTLANGCHANGEREQUEST = 80u,
	INPUTLANGCHANGE = 81u,
	TCARD = 82u,
	HELP = 83u,
	USERCHANGED = 84u,
	NOTIFYFORMAT = 85u,
	CONTEXTMENU = 123u,
	STYLECHANGING = 124u,
	STYLECHANGED = 125u,
	DISPLAYCHANGE = 126u,
	GETICON = 127u,
	SETICON = 128u,
	NCCREATE = 129u,
	NCDESTROY = 130u,
	NCCALCSIZE = 131u,
	NCHITTEST = 132u,
	NCPAINT = 133u,
	NCACTIVATE = 134u,
	GETDLGCODE = 135u,
	SYNCPAINT = 136u,
	NCMOUSEMOVE = 160u,
	NCLBUTTONDOWN = 161u,
	NCLBUTTONUP = 162u,
	NCLBUTTONDBLCLK = 163u,
	NCRBUTTONDOWN = 164u,
	NCRBUTTONUP = 165u,
	NCRBUTTONDBLCLK = 166u,
	NCMBUTTONDOWN = 167u,
	NCMBUTTONUP = 168u,
	NCMBUTTONDBLCLK = 169u,
	NCXBUTTONDOWN = 171u,
	NCXBUTTONUP = 172u,
	NCXBUTTONDBLCLK = 173u,
	INPUT_DEVICE_CHANGE = 254u,
	INPUT = 255u,
	KEYFIRST = 256u,
	KEYDOWN = 256u,
	KEYUP = 257u,
	CHAR = 258u,
	DEADCHAR = 259u,
	SYSKEYDOWN = 260u,
	SYSKEYUP = 261u,
	SYSCHAR = 262u,
	SYSDEADCHAR = 263u,
	UNICHAR = 265u,
	KEYLAST = 264u,
	IME_STARTCOMPOSITION = 269u,
	IME_ENDCOMPOSITION = 270u,
	IME_COMPOSITION = 271u,
	IME_KEYLAST = 271u,
	INITDIALOG = 272u,
	COMMAND = 273u,
	SYSCOMMAND = 274u,
	TIMER = 275u,
	HSCROLL = 276u,
	VSCROLL = 277u,
	INITMENU = 278u,
	INITMENUPOPUP = 279u,
	MENUSELECT = 287u,
	MENUCHAR = 288u,
	ENTERIDLE = 289u,
	MENURBUTTONUP = 290u,
	MENUDRAG = 291u,
	MENUGETOBJECT = 292u,
	UNINITMENUPOPUP = 293u,
	MENUCOMMAND = 294u,
	CHANGEUISTATE = 295u,
	UPDATEUISTATE = 296u,
	QUERYUISTATE = 297u,
	CTLCOLORMSGBOX = 306u,
	CTLCOLOREDIT = 307u,
	CTLCOLORLISTBOX = 308u,
	CTLCOLORBTN = 309u,
	CTLCOLORDLG = 310u,
	CTLCOLORSCROLLBAR = 311u,
	CTLCOLORSTATIC = 312u,
	MOUSEFIRST = 512u,
	MOUSEMOVE = 512u,
	LBUTTONDOWN = 513u,
	LBUTTONUP = 514u,
	LBUTTONDBLCLK = 515u,
	RBUTTONDOWN = 516u,
	RBUTTONUP = 517u,
	RBUTTONDBLCLK = 518u,
	MBUTTONDOWN = 519u,
	MBUTTONUP = 520u,
	MBUTTONDBLCLK = 521u,
	MOUSEWHEEL = 522u,
	XBUTTONDOWN = 523u,
	XBUTTONUP = 524u,
	XBUTTONDBLCLK = 525u,
	MOUSEHWHEEL = 526u,
	MOUSELAST = 526u,
	PARENTNOTIFY = 528u,
	ENTERMENULOOP = 529u,
	EXITMENULOOP = 530u,
	NEXTMENU = 531u,
	SIZING = 532u,
	CAPTURECHANGED = 533u,
	MOVING = 534u,
	POWERBROADCAST = 536u,
	DEVICECHANGE = 537u,
	MDICREATE = 544u,
	MDIDESTROY = 545u,
	MDIACTIVATE = 546u,
	MDIRESTORE = 547u,
	MDINEXT = 548u,
	MDIMAXIMIZE = 549u,
	MDITILE = 550u,
	MDICASCADE = 551u,
	MDIICONARRANGE = 552u,
	MDIGETACTIVE = 553u,
	MDISETMENU = 560u,
	ENTERSIZEMOVE = 561u,
	EXITSIZEMOVE = 562u,
	DROPFILES = 563u,
	MDIREFRESHMENU = 564u,
	IME_SETCONTEXT = 641u,
	IME_NOTIFY = 642u,
	IME_CONTROL = 643u,
	IME_COMPOSITIONFULL = 644u,
	IME_SELECT = 645u,
	IME_CHAR = 646u,
	IME_REQUEST = 648u,
	IME_KEYDOWN = 656u,
	IME_KEYUP = 657u,
	MOUSEHOVER = 673u,
	MOUSELEAVE = 675u,
	NCMOUSEHOVER = 672u,
	NCMOUSELEAVE = 674u,
	WTSSESSION_CHANGE = 689u,
	TABLET_FIRST = 704u,
	TABLET_LAST = 735u,
	CUT = 768u,
	COPY = 769u,
	PASTE = 770u,
	CLEAR = 771u,
	UNDO = 772u,
	RENDERFORMAT = 773u,
	RENDERALLFORMATS = 774u,
	DESTROYCLIPBOARD = 775u,
	DRAWCLIPBOARD = 776u,
	PAINTCLIPBOARD = 777u,
	VSCROLLCLIPBOARD = 778u,
	SIZECLIPBOARD = 779u,
	ASKCBFORMATNAME = 780u,
	CHANGECBCHAIN = 781u,
	HSCROLLCLIPBOARD = 782u,
	QUERYNEWPALETTE = 783u,
	PALETTEISCHANGING = 784u,
	PALETTECHANGED = 785u,
	HOTKEY = 786u,
	PRINT = 791u,
	PRINTCLIENT = 792u,
	APPCOMMAND = 793u,
	THEMECHANGED = 794u,
	CLIPBOARDUPDATE = 797u,
	DWMCOMPOSITIONCHANGED = 798u,
	DWMNCRENDERINGCHANGED = 799u,
	DWMCOLORIZATIONCOLORCHANGED = 800u,
	DWMWINDOWMAXIMIZEDCHANGE = 801u,
	GETTITLEBARINFOEX = 831u,
	HANDHELDFIRST = 856u,
	HANDHELDLAST = 863u,
	AFXFIRST = 864u,
	AFXLAST = 895u,
	PENWINFIRST = 896u,
	PENWINLAST = 911u,
	APP = 32768u,
	USER = 1024u,
	CPL_LAUNCH = 5120u,
	CPL_LAUNCHED = 5121u,
	SYSTIMER = 280u
}

+WinAPI

File Created
cs
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace B83.Win32;

public static class WinAPI
{
	[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
	public static extern IntPtr GetModuleHandle(string lpModuleName);

	[DllImport("kernel32.dll")]
	public static extern uint GetCurrentThreadId();

	[DllImport("user32.dll", SetLastError = true)]
	public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

	[DllImport("user32.dll", SetLastError = true)]
	public static extern bool UnhookWindowsHookEx(IntPtr hhk);

	[DllImport("user32.dll")]
	public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, ref MSG lParam);

	[DllImport("shell32.dll")]
	public static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);

	[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
	public static extern uint DragQueryFile(IntPtr hDrop, uint iFile, StringBuilder lpszFile, uint cch);

	[DllImport("shell32.dll")]
	public static extern void DragFinish(IntPtr hDrop);

	[DllImport("shell32.dll")]
	public static extern void DragQueryPoint(IntPtr hDrop, out POINT pos);
}

+Window

File Created
cs
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace B83.Win32;

public static class Window
{
	[DllImport("user32.dll")]
	public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

	[DllImport("user32.dll", SetLastError = true)]
	public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

	[DllImport("user32.dll")]
	public static extern bool IsWindowVisible(IntPtr hWnd);

	[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
	private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

	public static string GetClassName(IntPtr hWnd)
	{
		StringBuilder stringBuilder = new StringBuilder(256);
		int className = GetClassName(hWnd, stringBuilder, 256);
		return stringBuilder.ToString(0, className);
	}

	[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
	private static extern int GetWindowTextLength(IntPtr hWnd);

	[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
	private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

	public static string GetWindowText(IntPtr hWnd)
	{
		int num = GetWindowTextLength(hWnd) + 2;
		StringBuilder stringBuilder = new StringBuilder(num);
		int windowText = GetWindowText(hWnd, stringBuilder, num);
		return stringBuilder.ToString(0, windowText);
	}
}

+BaseCore

File Created
cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class BaseCore : MonoBehaviour
{
	public static bool IsOffline;

	public static BaseCore Instance;

	public static bool resetRuntime;

	public static Func<bool> BlockInput;

	public Version version;

	public Version versionMoongate;

	public Version versionMod;

	public ReleaseMode releaseMode;

	public string langCode;

	public EventSystem eventSystem;

	public List<Action> actionsLateUpdate = new List<Action>();

	public List<Action> actionsNextFrame = new List<Action>();

	[NonSerialized]
	public Canvas canvas;

	[NonSerialized]
	public string forceLangCode;

	[NonSerialized]
	public int frame;

	protected int lastScreenWidth;

	protected int lastScreenHeight;

	public virtual float uiScale => 1f;

	protected virtual void Awake()
	{
		GameObject[] array = GameObject.FindGameObjectsWithTag("Temp");
		for (int i = 0; i < array.Length; i++)
		{
			UnityEngine.Object.DestroyImmediate(array[i]);
		}
	}

	public virtual void ConsumeInput()
	{
	}

	public void WaitForEndOfFrame(Action action)
	{
		StartCoroutine(_WaitForEndOfFrame(action));
	}

	private IEnumerator _WaitForEndOfFrame(Action action)
	{
		yield return new WaitForEndOfFrame();
		action();
	}

	public virtual void StopEventSystem(float duration = 0.2f)
	{
	}

	public virtual void StopEventSystem(Component c, Action action, float duration = 0.15f)
	{
	}

	public virtual void FreezeScreen(float duration)
	{
	}

	public virtual void UnfreezeScreen()
	{
	}

	public virtual void RebuildBGMList()
	{
	}
}

+BaseModManager

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class BaseModManager
{
	[Serializable]
	public class BaseResource
	{
		public string resourcePath;

		public List<string> files;

		public void Parse<T>(ModItemList<T> list) where T : UnityEngine.Object
		{
			foreach (string file in files)
			{
				list.Add(null, resourcePath + "/" + file);
			}
		}
	}

	public static BaseModManager Instance;

	public static string rootMod;

	public static string rootDefaultPacakge;

	public static bool isInitialized;

	public static List<string> listChainLoad = new List<string>();

	public DirectoryInfo dirWorkshop;

	public int priorityIndex;

	[NonSerialized]
	public List<BaseModPackage> packages = new List<BaseModPackage>();

	public virtual void Init(string path, string defaultPackage = "_Elona")
	{
		Debug.Log("Initializing ModManager:" + defaultPackage + "/" + path);
		Instance = this;
		rootMod = (rootDefaultPacakge = path);
		if (!defaultPackage.IsEmpty())
		{
			rootDefaultPacakge = rootMod + defaultPackage + "/";
		}
	}

	public void InitLang()
	{
		Debug.Log("Initializing Langs");
		foreach (LangSetting value in MOD.langs.Values)
		{
			if (value.id != Lang.langCode)
			{
				continue;
			}
			new DirectoryInfo(value.dir);
			FileInfo[] files = new DirectoryInfo(value.dir + "Data").GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				if (fileInfo.Name == "Alias.xlsx")
				{
					Lang.alias = new ExcelData(fileInfo.FullName);
				}
				if (fileInfo.Name == "Name.xlsx")
				{
					Lang.names = new ExcelData(fileInfo.FullName);
				}
				if (fileInfo.Name == "chara_talk.xlsx")
				{
					MOD.listTalk.items.Add(new ExcelData(fileInfo.FullName));
				}
				if (fileInfo.Name == "chara_tone.xlsx")
				{
					MOD.tones.items.Add(new ExcelData(fileInfo.FullName));
				}
			}
		}
	}

	public virtual void ParseExtra(DirectoryInfo dir, BaseModPackage package)
	{
	}
}

+BaseModPackage

File Created
cs
using System.IO;
using System.Xml;
using UnityEngine;
using UnityEngine.UI;

public class BaseModPackage
{
	public static XmlReader xmlReader;

	public static XmlReaderSettings readerSetting;

	public string title;

	public string author;

	public string version;

	public string id;

	public string description;

	public string visibility;

	public string[] tags;

	public bool builtin;

	public bool activated;

	public bool willActivate = true;

	public bool installed;

	public bool banned;

	public bool isInPackages;

	public bool hasPublishedPackage;

	public bool downloadStarted;

	public int loadPriority;

	public object item;

	public DirectoryInfo dirInfo;

	public Text progressText;

	public bool IsValidVersion()
	{
		return !Version.Get(version).IsBelow(BaseCore.Instance.versionMod);
	}

	public bool Init()
	{
		if (!File.Exists(dirInfo.FullName + "/package.xml"))
		{
			return false;
		}
		UpdateMeta();
		return true;
	}

	public void UpdateMeta(bool updateOnly = false)
	{
		string text = dirInfo.FullName + "/package.xml";
		if (!File.Exists(text))
		{
			return;
		}
		XmlReader xmlReader = XmlReader.Create(text, new XmlReaderSettings
		{
			IgnoreComments = true,
			IgnoreWhitespace = true
		});
		while (xmlReader.Read())
		{
			if (xmlReader.NodeType != XmlNodeType.Element)
			{
				continue;
			}
			switch (xmlReader.Name)
			{
			case "title":
				if (xmlReader.Read())
				{
					title = xmlReader.Value;
				}
				break;
			case "author":
				if (xmlReader.Read())
				{
					author = xmlReader.Value;
				}
				break;
			case "id":
				if (xmlReader.Read())
				{
					id = xmlReader.Value;
				}
				break;
			case "description":
				if (xmlReader.Read())
				{
					description = xmlReader.Value;
				}
				break;
			case "version":
				if (xmlReader.Read())
				{
					version = xmlReader.Value;
				}
				break;
			case "builtin":
				if (xmlReader.Read())
				{
					bool.TryParse(xmlReader.Value, out builtin);
				}
				break;
			case "tag":
			case "tags":
				if (xmlReader.Read())
				{
					tags = xmlReader.Value.Split(',');
				}
				break;
			case "loadPriority":
				if (!updateOnly && xmlReader.Read())
				{
					int.TryParse(xmlReader.Value, out loadPriority);
				}
				break;
			case "visibility":
				if (xmlReader.Read())
				{
					visibility = xmlReader.Value;
				}
				break;
			}
		}
		xmlReader.Close();
	}

	public void Activate()
	{
		if (!hasPublishedPackage && installed && dirInfo.Exists && willActivate)
		{
			Debug.Log("Activating(" + loadPriority + ") :" + title + "/" + id);
			activated = true;
			Parse();
		}
	}

	public void Parse()
	{
		DirectoryInfo[] directories = dirInfo.GetDirectories();
		foreach (DirectoryInfo directoryInfo in directories)
		{
			if (directoryInfo.Name == "Actor")
			{
				FileInfo[] files = directoryInfo.GetFiles();
				foreach (FileInfo fileInfo in files)
				{
					if (fileInfo.Name.EndsWith(".xlsx"))
					{
						MOD.actorSources.items.Add(new ExcelData(fileInfo.FullName));
					}
				}
				DirectoryInfo[] directories2 = directoryInfo.GetDirectories();
				foreach (DirectoryInfo directoryInfo2 in directories2)
				{
					Log.App(directoryInfo2.FullName);
					string name = directoryInfo2.Name;
					if (!(name == "PCC"))
					{
						if (!(name == "Sprite"))
						{
							continue;
						}
						files = directoryInfo2.GetFiles();
						foreach (FileInfo fileInfo2 in files)
						{
							if (fileInfo2.Name.EndsWith(".png"))
							{
								MOD.sprites.Add(fileInfo2);
							}
						}
					}
					else
					{
						DirectoryInfo[] directories3 = directoryInfo2.GetDirectories();
						foreach (DirectoryInfo obj in directories3)
						{
							MOD.OnAddPcc(obj);
						}
					}
				}
			}
			else
			{
				BaseModManager.Instance.ParseExtra(directoryInfo, this);
			}
		}
	}
}

+BitArray32

File Created
cs
using System;
using Unity.Burst;

public struct BitArray32 : IEquatable<BitArray32>
{
	public uint Bits;

	public bool this[int index]
	{
		get
		{
			uint num = (uint)(1 << index);
			return (Bits & num) == num;
		}
		set
		{
			uint num = (uint)(1 << index);
			if (value)
			{
				Bits |= num;
			}
			else
			{
				Bits &= ~num;
			}
		}
	}

	public int Length => 32;

	public BitArray32(uint bits)
	{
		Bits = bits;
	}

	public void SetBit(int index)
	{
		RequireIndexInBounds(index);
		uint num = (uint)(1 << index);
		Bits |= num;
	}

	public void UnsetBit(int index)
	{
		RequireIndexInBounds(index);
		uint num = (uint)(1 << index);
		Bits &= ~num;
	}

	public uint GetBits(uint mask)
	{
		return Bits & mask;
	}

	public void SetBits(uint mask)
	{
		Bits |= mask;
	}

	public void UnsetBits(uint mask)
	{
		Bits &= ~mask;
	}

	public override bool Equals(object obj)
	{
		if (obj is BitArray32)
		{
			return Bits == ((BitArray32)obj).Bits;
		}
		return false;
	}

	public bool Equals(BitArray32 arr)
	{
		return Bits == arr.Bits;
	}

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

	public int ToInt()
	{
		return (int)Bits;
	}

	public void SetInt(int i)
	{
		Bits = (uint)i;
	}

	public override string ToString()
	{
		char[] array = new char[44];
		int i;
		for (i = 0; i < 11; i++)
		{
			array[i] = "BitArray32{"[i];
		}
		uint num = 2147483648u;
		while (num != 0)
		{
			array[i] = (((Bits & num) != 0) ? '1' : '0');
			num >>= 1;
			i++;
		}
		array[i] = '}';
		return new string(array);
	}

	[BurstDiscard]
	public void RequireIndexInBounds(int index)
	{
	}
}

+ButtonState

File Created
cs
using System;
using UnityEngine;

public class ButtonState
{
	public enum ClickCriteria
	{
		ByDuration,
		ByMargin,
		ByDurationAndMargin
	}

	public static float delta;

	public string id;

	public float pressedTimer;

	public float timeSinceLastClick;

	public float timeSinceLastButtonDown;

	public float clickDuration = 0.5f;

	public float dragMargin = 12f;

	public int mouse = -1;

	public EInput.KeyMap keymap;

	public bool down;

	public bool up;

	public bool pressing;

	public bool clicked;

	public bool doubleClicked;

	public bool consumed;

	public bool dragging;

	public bool dragging2;

	public bool draggedOverMargin;

	public bool ignoreClick;

	public bool wasConsumed;

	public bool usedMouse;

	public bool usedKey;

	public bool ignoreWheel;

	public ClickCriteria clickCriteria = ClickCriteria.ByDurationAndMargin;

	public Action pressedLongAction;

	public bool pressedLong
	{
		get
		{
			if (pressing)
			{
				return pressedTimer >= clickDuration;
			}
			return false;
		}
	}

	public bool IsInDoubleClickDuration()
	{
		return timeSinceLastClick < 0.2f;
	}

	public void Update()
	{
		timeSinceLastClick += delta;
		if (mouse != -1 && !usedKey)
		{
			down = Input.GetMouseButtonDown(mouse);
			up = Input.GetMouseButtonUp(mouse);
			pressing = Input.GetMouseButton(mouse);
			if (down)
			{
				usedMouse = true;
			}
		}
		if (mouse == 1)
		{
			if (down)
			{
				EInput.dragStartPos2 = EInput.mpos;
			}
			else if (pressing)
			{
				if (Vector3.Distance(EInput.mpos, EInput.dragStartPos2) > dragMargin)
				{
					dragging2 = true;
				}
			}
			else
			{
				dragging2 = false;
			}
		}
		if (keymap != null && !usedMouse && !EInput.isInputFieldActive)
		{
			down = Input.GetKeyDown(keymap.key);
			up = Input.GetKeyUp(keymap.key);
			pressing = Input.GetKey(keymap.key);
			if (down)
			{
				usedKey = true;
			}
		}
		if (consumed)
		{
			if (down || up || pressing)
			{
				Clear();
				return;
			}
			consumed = false;
		}
		if (down)
		{
			wasConsumed = false;
			EInput.dragStartPos = EInput.mpos;
			if (timeSinceLastClick < 0.2f)
			{
				doubleClicked = true;
			}
		}
		else if (pressing)
		{
			pressedTimer += delta;
			if (EInput.mpos != EInput.dragStartPos)
			{
				dragging = true;
			}
			if (Vector3.Distance(EInput.mpos, EInput.dragStartPos) > dragMargin)
			{
				draggedOverMargin = true;
			}
		}
		else if (up)
		{
			if (ignoreWheel)
			{
				EInput.ignoreWheelDuration = 0.2f;
			}
			switch (clickCriteria)
			{
			case ClickCriteria.ByDuration:
				clicked = pressedTimer < clickDuration;
				break;
			case ClickCriteria.ByMargin:
				clicked = !draggedOverMargin;
				break;
			case ClickCriteria.ByDurationAndMargin:
				clicked = !draggedOverMargin && pressedTimer < clickDuration;
				break;
			}
			if (clicked)
			{
				timeSinceLastClick = 0f;
			}
			if (ignoreClick)
			{
				clicked = false;
			}
		}
		else
		{
			Clear();
		}
	}

	public void Consume()
	{
		Clear();
		consumed = (wasConsumed = true);
	}

	public void Clear()
	{
		pressedTimer = 0f;
		down = (up = (pressing = false));
		usedKey = (usedMouse = (clicked = (doubleClicked = (dragging = (draggedOverMargin = (ignoreClick = false))))));
	}
}

+CameraFilterPack_Atmosphere_Rain

File Created
cs
using UnityEngine;

[ExecuteInEditMode]
[AddComponentMenu("Camera Filter Pack/Weather/Rain")]
public class CameraFilterPack_Atmosphere_Rain : MonoBehaviour
{
	public Shader SCShader;

	private float TimeX = 1f;

	private Material SCMaterial;

	[Range(0f, 1f)]
	public float Fade = 1f;

	[Range(0f, 2f)]
	public float Intensity = 0.5f;

	[Range(-0.25f, 0.25f)]
	public float DirectionX = 0.12f;

	[Range(0.4f, 2f)]
	public float Size = 1.5f;

	[Range(0f, 0.5f)]
	public float Speed = 0.275f;

	[Range(0f, 0.5f)]
	public float Distortion = 0.05f;

	[Range(0f, 1f)]
	public float StormFlashOnOff = 1f;

	private Texture2D Texture2;

	private Material material
	{
		get
		{
			if (SCMaterial == null)
			{
				SCMaterial = new Material(SCShader);
				SCMaterial.hideFlags = HideFlags.HideAndDontSave;
			}
			return SCMaterial;
		}
	}

	private void Start()
	{
		Texture2 = Resources.Load("CameraFilterPack_Atmosphere_Rain_FX") as Texture2D;
		SCShader = Shader.Find("CameraFilterPack/Atmosphere_Rain");
		if (!SystemInfo.supportsImageEffects)
		{
			base.enabled = false;
		}
	}

	private void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
	{
		if (SCShader != null)
		{
			TimeX += Time.deltaTime;
			if (TimeX > 100f)
			{
				TimeX = 0f;
			}
			material.SetFloat("_TimeX", TimeX);
			material.SetFloat("_Value", Fade);
			material.SetFloat("_Value2", Intensity);
			material.SetFloat("_Value3", DirectionX);
			material.SetFloat("_Value4", Speed);
			material.SetFloat("_Value5", Size);
			material.SetFloat("_Value6", Distortion);
			material.SetFloat("_Value7", StormFlashOnOff);
			material.SetVector("_ScreenResolution", new Vector4(sourceTexture.width, sourceTexture.height, 0f, 0f));
			material.SetTexture("Texture2", Texture2);
			Graphics.Blit(sourceTexture, destTexture, material);
		}
		else
		{
			Graphics.Blit(sourceTexture, destTexture);
		}
	}

	private void Update()
	{
	}

	private void OnDisable()
	{
		if ((bool)SCMaterial)
		{
			Object.DestroyImmediate(SCMaterial);
		}
	}
}

+ClassCache

File Created
cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

public class ClassCache<T>
{
	public Dictionary<string, Func<T>> dict = new Dictionary<string, Func<T>>();

	public T Create<T2>(Type type)
	{
		if (type == null)
		{
			return default(T);
		}
		Func<T> func = dict.TryGetValue(type.Name);
		if (func != null)
		{
			return func();
		}
		ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
		if (constructor == null)
		{
			return default(T);
		}
		func = Expression.Lambda<Func<T>>(Expression.New(constructor), Array.Empty<ParameterExpression>()).Compile();
		dict.Add(type.Name, func);
		return func();
	}

	public T Create<T2>(string id, string assembly)
	{
		Type type = Type.GetType(id + ", " + assembly);
		if (type == null)
		{
			foreach (string assembly2 in ClassCache.assemblies)
			{
				type = Type.GetType(id + ", " + assembly2);
				if (type != null)
				{
					break;
				}
			}
		}
		return Create<T2>(type);
	}
}
public class ClassCache
{
	public static ClassCache<object> caches = new ClassCache<object>();

	public static HashSet<string> assemblies = new HashSet<string>();

	public static T Create<T>(string id, string assembly = "Assembly-CSharp")
	{
		return (T)caches.Create<T>(id, assembly);
	}
}

+ClassExtension

File Created
cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Pluralize.NET;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public static class ClassExtension
{
	private static Vector3 vector3;

	public static IPluralize pluralizer = new Pluralizer();

	public static string lang(this string s)
	{
		return Lang.Get(s);
	}

	public static string langPlural(this string s, int i)
	{
		string text = Lang.Get(s);
		return Lang.Parse((i <= 1 || !Lang.setting.pluralize) ? text : pluralizer.Pluralize(text), i.ToString() ?? "");
	}

	public static string lang(this string s, string ref1, string ref2 = null, string ref3 = null, string ref4 = null, string ref5 = null)
	{
		return Lang.Parse(s, ref1, ref2, ref3, ref4, ref5);
	}

	public static string langGame(this string s)
	{
		return Lang.Game.Get(s);
	}

	public static string langGame(this string s, string ref1, string ref2 = null, string ref3 = null, string ref4 = null)
	{
		return Lang.Game.Parse(s, ref1, ref2, ref3, ref4);
	}

	public static string Parentheses(this string str)
	{
		return "(" + str + ")";
	}

	public static string Bracket(this string str, int type = 0)
	{
		return type switch
		{
			-1 => str, 
			1 => "「" + str + "」", 
			2 => "『" + str + "』", 
			3 => "《" + str + "》", 
			4 => "(" + str + ")", 
			_ => "_bracketLeft".lang() + str + "_bracketRight".lang(), 
		};
	}

	public static byte[] ToBytes(this BitArray bits)
	{
		byte[] array = new byte[(bits.Length - 1) / 8 + 1];
		bits.CopyTo(array, 0);
		return array;
	}

	public static bool GetBit(this byte pByte, int bitNo)
	{
		return (pByte & (1 << bitNo)) != 0;
	}

	public static byte SetBit(this byte pByte, int bitNo, bool value)
	{
		if (!value)
		{
			return Convert.ToByte(pByte & ~(1 << bitNo));
		}
		return Convert.ToByte(pByte | (1 << bitNo));
	}

	public static int ToInt3(this float a)
	{
		return (int)(a * 1000f);
	}

	public static float FromInt3(this int a)
	{
		return (float)a / 1000f;
	}

	public static int ToInt2(this float a)
	{
		return (int)(a * 100f);
	}

	public static float FromInt2(this int a)
	{
		return (float)a / 100f;
	}

	public static int Minimum(this int i)
	{
		if (i != 0)
		{
			if (i <= 0)
			{
				return -1;
			}
			return 1;
		}
		return 0;
	}

	public static bool IsNull(this object o)
	{
		return o == null;
	}

	public static bool IsOn(this int data, int digit)
	{
		BitArray32 bitArray = default(BitArray32);
		bitArray.SetInt(data);
		return bitArray[digit];
	}

	public static T ToEnum<T>(this int value)
	{
		return (T)Enum.ToObject(typeof(T), value);
	}

	public static T ToEnum<T>(this long value)
	{
		return (T)Enum.ToObject(typeof(T), value);
	}

	public static T ToEnum<T>(this string value, bool ignoreCase = true)
	{
		return (T)Enum.Parse(typeof(T), value, ignoreCase);
	}

	public static Type ToType(this string value)
	{
		return Type.GetType("Elona." + value + ", Assembly-CSharp");
	}

	public static T NextEnum<T>(this T src) where T : struct
	{
		return ((T[])Enum.GetValues(src.GetType())).NextItem(src);
	}

	public static T PrevEnum<T>(this T src) where T : struct
	{
		return ((T[])Enum.GetValues(src.GetType())).PrevItem(src);
	}

	public static bool Within(this int v, int v2, int range)
	{
		if (v - v2 >= range)
		{
			return v - v2 < -range;
		}
		return true;
	}

	public static bool Within(this byte v, byte v2, byte range)
	{
		if (v - v2 >= range)
		{
			return v - v2 < -range;
		}
		return true;
	}

	public static int Clamp(this int v, int min, int max, bool loop = false)
	{
		if (v < min)
		{
			v = ((!loop) ? min : max);
		}
		else if (v > max)
		{
			v = ((!loop) ? max : min);
		}
		return v;
	}

	public static int ClampMin(this int v, int min)
	{
		if (v >= min)
		{
			return v;
		}
		return min;
	}

	public static int ClampMax(this int v, int max)
	{
		if (v <= max)
		{
			return v;
		}
		return max;
	}

	public static T ToField<T>(this string s, object o)
	{
		return (T)o.GetType().GetField(s).GetValue(o);
	}

	public static bool HasField<T>(this object o, string name)
	{
		FieldInfo field = o.GetType().GetField(name);
		if (field != null)
		{
			return typeof(T).IsAssignableFrom(field.FieldType);
		}
		return false;
	}

	public static T GetField<T>(this object o, string name)
	{
		return (T)o.GetType().GetField(name).GetValue(o);
	}

	public static void SetField<T>(this object o, string name, T value)
	{
		o.GetType().GetField(name).SetValue(o, value);
	}

	public static T GetProperty<T>(this object o, string name)
	{
		return (T)o.GetType().GetProperty(name).GetValue(o);
	}

	public static void SetProperty<T>(this object o, string name, T value)
	{
		o.GetType().GetProperty(name).SetValue(o, value);
	}

	public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
	{
		if (list is List<T>)
		{
			((List<T>)list).Sort(comparison);
			return;
		}
		List<T> list2 = new List<T>(list);
		list2.Sort(comparison);
		for (int i = 0; i < list.Count; i++)
		{
			list[i] = list2[i];
		}
	}

	public static TValue TryGet<TValue>(this IList<TValue> array, int index, int defIndex = -1)
	{
		if (array.Count != 0)
		{
			if (index >= array.Count)
			{
				if (defIndex != -1)
				{
					if (array.Count <= defIndex)
					{
						return array[Mathf.Max(0, array.Count - 1)];
					}
					return array[defIndex];
				}
				return array[Mathf.Max(0, array.Count - 1)];
			}
			return array[Math.Max(0, index)];
		}
		return default(TValue);
	}

	public static TValue TryGet<TValue>(this IList<TValue> array, int index, bool returnNull)
	{
		if (index >= array.Count)
		{
			return default(TValue);
		}
		return array[index];
	}

	public static bool IsEmpty(this Array array)
	{
		if (array != null)
		{
			return array.Length == 0;
		}
		return true;
	}

	public static int IndexOf(this IList<Component> list, GameObject go)
	{
		if (!go)
		{
			return -1;
		}
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i].gameObject == go)
			{
				return i;
			}
		}
		return -1;
	}

	public static TValue Move<TValue>(this IList<TValue> list, TValue target, int a)
	{
		int num = list.IndexOf(target);
		int num2 = num + a;
		if (num2 < 0)
		{
			num2 = list.Count - 1;
		}
		if (num2 >= list.Count)
		{
			num2 = 0;
		}
		list.Remove(target);
		list.Insert(num2, target);
		return list[num];
	}

	public static IList<TValue> Copy<TValue>(this IList<TValue> list)
	{
		return list.ToList();
	}

	public static void Each<TValue>(this IList<TValue> list, Action<TValue> action)
	{
		for (int num = list.Count - 1; num >= 0; num--)
		{
			action(list[num]);
		}
	}

	public static IList<TValue> Shuffle<TValue>(this IList<TValue> list)
	{
		int num = list.Count;
		while (num > 1)
		{
			int index = Rand._random.Next(num);
			num--;
			TValue value = list[num];
			list[num] = list[index];
			list[index] = value;
		}
		return list;
	}

	public static TValue TryGetValue<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key, TValue fallback = default(TValue))
	{
		TValue value = default(TValue);
		if (key != null && source.TryGetValue(key, out value))
		{
			return value;
		}
		return fallback;
	}

	public static TValue GetOrCreate<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, Func<TValue> func = null)
	{
		TValue val = dict.TryGetValue(key);
		if (val == null)
		{
			val = ((func != null) ? func() : Activator.CreateInstance<TValue>());
			dict.Add(key, val);
		}
		return val;
	}

	public static TKey[] CopyKeys<TKey, TValue>(this IDictionary<TKey, TValue> dict)
	{
		TKey[] array = new TKey[dict.Keys.Count];
		dict.Keys.CopyTo(array, 0);
		return array;
	}

	public static TValue[] CopyValues<TKey, TValue>(this IDictionary<TKey, TValue> dict)
	{
		TValue[] array = new TValue[dict.Keys.Count];
		dict.Values.CopyTo(array, 0);
		return array;
	}

	public static T RandomItem<T>(this IEnumerable<T> ie)
	{
		int num = ie.Count();
		if (num == 0)
		{
			return default(T);
		}
		return ie.ElementAt(Rand.rnd(num));
	}

	public static TValue RandomItem<TKey, TValue>(this IDictionary<TKey, TValue> source)
	{
		if (source.Count != 0)
		{
			return source.ElementAt(Rand.rnd(source.Count)).Value;
		}
		return default(TValue);
	}

	public static TValue RandomItem<TValue>(this IList<TValue> source)
	{
		if (source.Count != 0)
		{
			return source[Rand.rnd(source.Count)];
		}
		return default(TValue);
	}

	public static TValue RandomItem<TValue>(this IList<TValue> source, TValue exclude)
	{
		return source.RandomItem(source.IndexOf(exclude));
	}

	public static TValue RandomItem<TValue>(this IList<TValue> source, int exclude)
	{
		if (source.Count > 1)
		{
			int num;
			do
			{
				num = Rand.rnd(source.Count);
			}
			while (num == exclude);
			return source[num];
		}
		if (source.Count == 1)
		{
			return source[0];
		}
		return default(TValue);
	}

	public static TValue RandomItem<TValue>(this IList<TValue> source, Func<TValue, bool> funcValid, TValue defaultValue = default(TValue))
	{
		for (int i = 0; i < 100; i++)
		{
			TValue val = source[Rand.rnd(source.Count)];
			if (funcValid(val))
			{
				return val;
			}
		}
		return defaultValue;
	}

	public static TValue RandomItemWeighted<TValue>(this IList<TValue> source, Func<TValue, float> getWeight)
	{
		if (source.Count == 0)
		{
			return default(TValue);
		}
		if (source.Count == 1)
		{
			return source[0];
		}
		float num = 0f;
		foreach (TValue item in source)
		{
			num += getWeight(item);
		}
		float num2 = Rand.Range(0f, num);
		num = 0f;
		foreach (TValue item2 in source)
		{
			num += getWeight(item2);
			if (num2 < num)
			{
				return item2;
			}
		}
		return source.First();
	}

	public static TValue Remainder<TValue>(this IList<TValue> source, int divider)
	{
		if (source.Count != 0)
		{
			return source[divider % source.Count];
		}
		return default(TValue);
	}

	public static TValue FirstItem<TKey, TValue>(this IDictionary<TKey, TValue> source)
	{
		return source[source.First().Key];
	}

	public static TValue LastItem<TValue>(this IList<TValue> source)
	{
		if (source.Count != 0)
		{
			return source[source.Count - 1];
		}
		return default(TValue);
	}

	public static TValue NextItem<TValue>(this IList<TValue> source, ref int index)
	{
		index++;
		if (index >= source.Count)
		{
			index = 0;
		}
		if (source.Count != 0)
		{
			return source[index];
		}
		return default(TValue);
	}

	public static int NextIndex<TValue>(this IList<TValue> source, TValue val)
	{
		if (val == null)
		{
			return 0;
		}
		int num = source.IndexOf(val) + 1;
		if (num >= source.Count)
		{
			num = 0;
		}
		return num;
	}

	public static TValue NextItem<TValue>(this IList<TValue> source, TValue val)
	{
		int num = source.IndexOf(val) + 1;
		if (num >= source.Count)
		{
			num = 0;
		}
		if (source.Count != 0)
		{
			return source[num];
		}
		return default(TValue);
	}

	public static TValue PrevItem<TValue>(this IList<TValue> source, TValue val)
	{
		int num = source.IndexOf(val) - 1;
		if (num < 0)
		{
			num = source.Count - 1;
		}
		if (source.Count != 0)
		{
			return source[num];
		}
		return default(TValue);
	}

	public static TValue Clamp<TValue>(this IList<TValue> source, int i)
	{
		if (i < 0)
		{
			i = 0;
		}
		else if (i >= source.Count)
		{
			i = source.Count - 1;
		}
		return source[i];
	}

	public static List<T> GetList<T>(this IDictionary source)
	{
		List<T> list = new List<T>();
		foreach (object value in source.Values)
		{
			if (value is T)
			{
				list.Add((T)value);
			}
		}
		return list;
	}

	public static void ToDictionary<T>(this IList<UPair<T>> list, ref Dictionary<string, T> dic)
	{
		dic = new Dictionary<string, T>();
		for (int i = 0; i < list.Count; i++)
		{
			dic.Add(list[i].name, list[i].value);
		}
	}

	public static T FindMax<T>(this List<T> list, Func<T, int> func)
	{
		int num = int.MinValue;
		T result = default(T);
		foreach (T item in list)
		{
			int num2 = func(item);
			if (num2 > num)
			{
				num = num2;
				result = item;
			}
		}
		return result;
	}

	public static void Set<T1, T2>(this Dictionary<T1, T2> dic, Dictionary<T1, T2> from)
	{
		dic.Clear();
		foreach (KeyValuePair<T1, T2> item in from)
		{
			dic[item.Key] = item.Value;
		}
	}

	public static int Calc(this string str, int power = 0, int ele = 0, int p2 = 0)
	{
		return Cal.Calcuate(str.Replace("p2", p2.ToString() ?? "").Replace("p", power.ToString() ?? "").Replace("e", ele.ToString() ?? ""));
	}

	public static int ToInt<T>(this string str)
	{
		return str.ToInt(typeof(T));
	}

	public static int ToInt(this string str, Type type)
	{
		FieldInfo field = type.GetField(str, BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
		if (field == null)
		{
			Debug.LogError("Field is null:" + str + "/" + type);
			return -1;
		}
		return (int)field.GetValue(null);
	}

	public static int ToInt(this string str)
	{
		if (int.TryParse(str, out var result))
		{
			return result;
		}
		return 0;
	}

	public static float ToFloat(this string str)
	{
		float result = 0f;
		try
		{
			if (!float.TryParse(str, out result))
			{
				Debug.Log("exception: ToFlat1" + str);
				result = 1f;
			}
		}
		catch
		{
			Debug.Log("exception: ToFlat2" + str);
			result = 1f;
		}
		return result;
	}

	public static string StripLastPun(this string str)
	{
		if (str != null)
		{
			return str.TrimEnd(Lang.words.period);
		}
		return str;
	}

	public static string StripPun(this string str, bool stripComma, bool insertSpaceForComma = false)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (char c in str)
		{
			if (c == Lang.words.comma)
			{
				if (stripComma)
				{
					if (insertSpaceForComma)
					{
						stringBuilder.Append('\u3000');
					}
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			else if (c != Lang.words.period)
			{
				stringBuilder.Append(c);
			}
		}
		return stringBuilder.ToString();
	}

	public static string Repeat(this string str, int count)
	{
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < Mathf.Abs(count); i++)
		{
			stringBuilder.Append(str);
		}
		return stringBuilder.ToString();
	}

	public static string StripBrackets(this string str)
	{
		return str.Replace("\"", "").Replace("「", "").Replace("」", "")
			.Replace("“", "")
			.Replace("\"", "");
	}

	public static string TryAddExtension(this string s, string ext)
	{
		if (!s.Contains("." + ext))
		{
			return s + "." + ext;
		}
		return s;
	}

	public static bool IsEmpty(this string str)
	{
		if (str != null)
		{
			return str == "";
		}
		return true;
	}

	public static string IsEmpty(this string str, string defaultStr)
	{
		if (str != null && !(str == ""))
		{
			return str;
		}
		return defaultStr;
	}

	public static string TrimNewLines(this string text)
	{
		while (text.EndsWith(Environment.NewLine))
		{
			text = text.Substring(0, text.Length - Environment.NewLine.Length);
		}
		return text;
	}

	public static int[] SplitToInts(this string str, char separator)
	{
		string[] array = str.Split(separator);
		int[] array2 = new int[array.Length];
		for (int i = 0; i < array.Length; i++)
		{
			array2[i] = int.Parse(array[i]);
		}
		return array2;
	}

	public static string[] SplitNewline(this string str)
	{
		return str.Split(Environment.NewLine.ToCharArray());
	}

	public static bool Contains(this string[] strs, string id)
	{
		if (strs == null || strs.Length == 0)
		{
			return false;
		}
		for (int i = 0; i < strs.Length; i++)
		{
			if (strs[i] == id)
			{
				return true;
			}
		}
		return false;
	}

	public static string Evalute(this string[] array, float val)
	{
		return array[(int)Mathf.Clamp((float)(array.Length - 1) * val, 0f, array.Length - 1)];
	}

	public static string ToFormat(this int a)
	{
		return $"{a:#,0}";
	}

	public static string ToFormat(this long a)
	{
		return $"{a:#,0}";
	}

	public static string ToText(this int a, bool skipIfZero = true)
	{
		object obj;
		if (!(a == 0 && skipIfZero))
		{
			if (a >= 0)
			{
				return "+" + a;
			}
			obj = a.ToString();
			if (obj == null)
			{
				return "";
			}
		}
		else
		{
			obj = "";
		}
		return (string)obj;
	}

	public static string TagColor(this string s, Color c, string txt)
	{
		return s + "<color=" + c.ToHex() + ">" + txt + "</color>";
	}

	public static string TagColor(this string s, Color c)
	{
		return "<color=" + c.ToHex() + ">" + s + "</color>";
	}

	public static string TagSize(this string s, string txt, int size)
	{
		return s + "<size=" + size + ">" + txt + "</size>";
	}

	public static string TagSize(this string s, int size)
	{
		return "<size=" + size + ">" + s + "</size>";
	}

	public static string GetFullFileNameWithoutExtension(this FileInfo fileInfo)
	{
		return fileInfo.Directory.FullName + "/" + Path.GetFileNameWithoutExtension(fileInfo.Name);
	}

	public static string GetFullFileNameWithoutExtension(this string path)
	{
		return new FileInfo(path).GetFullFileNameWithoutExtension();
	}

	public static string AddArticle(this string s)
	{
		if (!Lang.setting.addArticle || s.Length < 1)
		{
			return s;
		}
		char c = s[0];
		s = ((c == 'a' || c == 'i' || c == 'u' || c == 'e' || c == 'o') ? "an " : "a ") + s;
		return s;
	}

	public static string AddArticle(this string s, int num, ArticleStyle style = ArticleStyle.Default, string replace = null)
	{
		if (!Lang.setting.addArticle || s.Length < 1)
		{
			return s;
		}
		char c = s[0];
		string text = ((num >= 2) ? (num.ToFormat() + " ") : ((c == 'a' || c == 'i' || c == 'u' || c == 'e' || c == 'o') ? "an " : "a "));
		if (num >= 2 && Lang.setting.pluralize)
		{
			s = ((replace.IsEmpty() || !s.Contains(replace) || s.Contains("limestone stone")) ? pluralizer.Pluralize(s) : s.Replace(replace, pluralizer.Pluralize(replace)));
		}
		return style switch
		{
			ArticleStyle.The => "_the".lang().ToTitleCase() + " " + ((num > 1) ? (num + " ") : "") + s, 
			ArticleStyle.None => ((num > 1) ? (num.ToFormat() + " ") : "") + s.ToTitleCase(), 
			_ => text + s, 
		};
	}

	public static string ToTitleCase(this string s, bool wholeText = false)
	{
		if (!Lang.setting.capitalize)
		{
			return s;
		}
		char[] array = s.ToCharArray();
		bool flag = true;
		for (int i = 0; i < array.Length; i++)
		{
			if (flag)
			{
				array[i] = char.ToUpper(array[i]);
				flag = false;
			}
			if (!wholeText)
			{
				break;
			}
			if (array[i] == ' ')
			{
				flag = true;
			}
		}
		return new string(array);
	}

	public static void LoopTail<T>(this List<T> list, bool vertical = false) where T : Selectable
	{
		if (list.Count > 1)
		{
			Navigation navigation = list[0].navigation;
			Navigation navigation2 = list[list.Count - 1].navigation;
			if (vertical)
			{
				navigation.selectOnUp = list[list.Count - 1];
				navigation2.selectOnDown = list[0];
			}
			else
			{
				navigation.selectOnLeft = list[list.Count - 1];
				navigation2.selectOnRight = list[0];
			}
			list[0].navigation = navigation;
			list[list.Count - 1].navigation = navigation2;
		}
	}

	public static void SetNavigation(this Component a, Component b, bool vertical = false)
	{
		if (!a || !b)
		{
			return;
		}
		Selectable component = a.GetComponent<Selectable>();
		Selectable component2 = b.GetComponent<Selectable>();
		if ((bool)component && (bool)component2)
		{
			Navigation navigation = component.navigation;
			Navigation navigation2 = component2.navigation;
			if (vertical)
			{
				navigation.selectOnUp = component2;
				navigation2.selectOnDown = component;
			}
			else
			{
				navigation.selectOnLeft = component2;
				navigation2.selectOnRight = component;
			}
			component.navigation = navigation;
			component2.navigation = navigation2;
		}
	}

	public static void LoopSelectable(this List<Selectable> sels, bool vertical = true, bool horizonal = true, bool asGroup = true)
	{
		for (int i = 0; i < sels.Count; i++)
		{
			Selectable selectable = sels[i];
			Selectable selectable2 = sels[0];
			Navigation navigation = selectable.navigation;
			if (horizonal)
			{
				navigation.selectOnRight = ((i + 1 < sels.Count) ? sels[i + 1] : selectable2);
			}
			if (asGroup)
			{
				for (int j = i + 1; j < sels.Count; j++)
				{
					if (sels[j].transform.position.y < selectable.transform.position.y)
					{
						selectable2 = sels[j];
						break;
					}
				}
			}
			else
			{
				selectable2 = ((i + 1 < sels.Count) ? sels[i + 1] : selectable2);
			}
			if (vertical)
			{
				navigation.selectOnDown = selectable2;
			}
			selectable.navigation = navigation;
		}
		for (int num = sels.Count - 1; num >= 0; num--)
		{
			Selectable selectable3 = sels[num];
			Selectable selectable4 = sels[sels.Count - 1];
			Navigation navigation2 = selectable3.navigation;
			if (horizonal)
			{
				navigation2.selectOnLeft = ((num > 0) ? sels[num - 1] : selectable4);
			}
			if (asGroup)
			{
				int num2 = sels.Count - 1;
				for (int num3 = num - 1; num3 >= 0; num3--)
				{
					if (sels[num3].transform.position.y > selectable3.transform.position.y)
					{
						num2 = num3;
						break;
					}
				}
				int num4 = num2;
				while (num4 >= 0 && !(sels[num4].transform.position.y > sels[num2].transform.position.y))
				{
					selectable4 = sels[num4];
					num4--;
				}
			}
			else
			{
				selectable4 = ((num > 0) ? sels[num - 1] : selectable4);
			}
			if (vertical)
			{
				navigation2.selectOnUp = ((selectable4 == selectable3) ? sels[sels.Count - 1] : selectable4);
			}
			navigation2.mode = Navigation.Mode.Explicit;
			selectable3.navigation = navigation2;
		}
	}

	public static void LoopSelectable(this Transform l, bool vertical = true, bool horizonal = true, bool asGroup = true)
	{
		List<Selectable> list = l.GetComponentsInChildren<Selectable>().ToList();
		for (int num = list.Count - 1; num >= 0; num--)
		{
			if (!list[num].interactable || list[num].navigation.mode == Navigation.Mode.None)
			{
				list.RemoveAt(num);
			}
		}
		list.LoopSelectable(vertical, horizonal, asGroup);
	}

	public static Color ToColor(this string s)
	{
		Color color = Color.white;
		ColorUtility.TryParseHtmlString("#" + s, out color);
		return color;
	}

	public static void SetAlpha(this Image c, float a)
	{
		c.color = new Color(c.color.r, c.color.g, c.color.b, a);
	}

	public static void SetAlpha(this RawImage c, float a)
	{
		c.color = new Color(c.color.r, c.color.g, c.color.b, a);
	}

	public static Color SetAlpha(this Color c, float a)
	{
		c.a = a;
		return c;
	}

	public static Color Multiply(this Color c, float mtp, float add)
	{
		return new Color(c.r * mtp + add, c.g * mtp + add, c.b * mtp + add, c.a);
	}

	public static string Tag(this Color c)
	{
		return "<color=" + $"#{(int)(c.r * 255f):X2}{(int)(c.g * 255f):X2}{(int)(c.b * 255f):X2}" + ">";
	}

	public static string ToHex(this Color c)
	{
		return $"#{(int)(c.r * 255f):X2}{(int)(c.g * 255f):X2}{(int)(c.b * 255f):X2}";
	}

	public static void SetOnClick(this Button b, Action action)
	{
		b.onClick.RemoveAllListeners();
		b.onClick.AddListener(delegate
		{
			action();
		});
	}

	public static void SetListener(this Button.ButtonClickedEvent e, Action action)
	{
		e.RemoveAllListeners();
		e.AddListener(delegate
		{
			action();
		});
	}

	public static void SetAlpha(this Text text, float aloha = 1f)
	{
		text.color = new Color(text.color.r, text.color.g, text.color.b, aloha);
	}

	public static void SetSlider(this Slider slider, float value, Func<float, string> action, bool notify)
	{
		slider.SetSlider(value, action, -1, -1, notify);
	}

	public static void SetSlider(this Slider slider, float value, Func<float, string> action, int min = -1, int max = -1, bool notify = true)
	{
		slider.onValueChanged.RemoveAllListeners();
		slider.onValueChanged.AddListener(delegate(float a)
		{
			slider.GetComponentInChildren<Text>(includeInactive: true).text = action(a);
		});
		if (min != -1)
		{
			slider.minValue = min;
			slider.maxValue = max;
		}
		if (notify)
		{
			slider.value = value;
		}
		else
		{
			slider.SetValueWithoutNotify(value);
		}
		slider.GetComponentInChildren<Text>(includeInactive: true).text = action(value);
	}

	public static T GetOrCreate<T>(this Component t) where T : Component
	{
		return t.gameObject.GetComponent<T>() ?? t.gameObject.AddComponent<T>();
	}

	public static RectTransform Rect(this Component c)
	{
		return c.transform as RectTransform;
	}

	public static void CopyRect(this RectTransform r, RectTransform t)
	{
		r.pivot = t.pivot;
		r.sizeDelta = t.sizeDelta;
		r.anchorMin = t.anchorMin;
		r.anchorMax = t.anchorMax;
		r.anchoredPosition = t.anchoredPosition;
	}

	public static void ToggleActive(this Component c)
	{
		c.SetActive(!c.gameObject.activeSelf);
	}

	public static void SetActive(this Component c, bool enable)
	{
		if (c.gameObject.activeSelf != enable)
		{
			c.gameObject.SetActive(enable);
		}
	}

	public static void SetActive(this Component c, bool enable, Action<bool> onChangeState)
	{
		if (c.gameObject.activeSelf != enable)
		{
			c.gameObject.SetActive(enable);
			onChangeState(enable);
		}
	}

	public static Selectable GetSelectable(this GameObject go)
	{
		return go.GetComponentInChildren<Selectable>();
	}

	public static void SetLayerRecursively(this GameObject obj, int layer)
	{
		obj.layer = layer;
		foreach (Transform item in obj.transform)
		{
			item.gameObject.SetLayerRecursively(layer);
		}
	}

	public static bool IsInteractable(this GameObject obj)
	{
		Selectable selectable = (obj ? obj.GetComponent<Selectable>() : null);
		if ((bool)selectable)
		{
			return selectable.interactable;
		}
		return false;
	}

	public static bool IsChildOf(this GameObject c, GameObject root)
	{
		if (c.transform == root.transform)
		{
			return true;
		}
		if ((bool)c.transform.parent)
		{
			return c.transform.parent.gameObject.IsChildOf(root);
		}
		return false;
	}

	public static bool IsPrefab(this Component c)
	{
		return c.gameObject.scene.name == null;
	}

	public static T CreateMold<T>(this Component c, string name = null) where T : Component
	{
		T result = null;
		for (int i = 0; i < c.transform.childCount; i++)
		{
			T component = c.transform.GetChild(i).GetComponent<T>();
			if ((bool)component && (name.IsEmpty() || name == component.name))
			{
				component.gameObject.SetActive(value: false);
				result = component;
				break;
			}
		}
		c.DestroyChildren();
		return result;
	}

	public static Transform Find(this Component c, string name = null)
	{
		return c.Find<Transform>(name);
	}

	public static T Find<T>(this Component c, string name = null, bool recursive = false) where T : Component
	{
		if (recursive)
		{
			T[] componentsInChildren = c.transform.GetComponentsInChildren<T>();
			foreach (T val in componentsInChildren)
			{
				if (name == null || name == val.name)
				{
					return val;
				}
			}
			return null;
		}
		for (int j = 0; j < c.transform.childCount; j++)
		{
			T component = c.transform.GetChild(j).GetComponent<T>();
			if ((bool)component && (name == null || name == component.name))
			{
				return component;
			}
		}
		return null;
	}

	public static GameObject FindTagInParents(this Component c, string tag, bool includeInactive = true)
	{
		Transform transform = c.transform;
		for (int i = 0; i < transform.childCount; i++)
		{
			Transform child = transform.GetChild(i);
			if ((includeInactive || child.gameObject.activeSelf) && child.tag == tag)
			{
				return child.gameObject;
			}
		}
		if ((bool)transform.parent)
		{
			return transform.parent.FindTagInParents(tag, includeInactive);
		}
		return null;
	}

	public static T GetComponentInChildrenExcludSelf<T>(this Transform c) where T : Component
	{
		for (int i = 0; i < c.childCount; i++)
		{
			T component = c.GetChild(i).GetComponent<T>();
			if ((bool)component)
			{
				return component;
			}
		}
		return null;
	}

	public static List<T> GetComponentsInDirectChildren<T>(this Transform comp, bool includeInactive = true) where T : Component
	{
		List<T> list = new List<T>();
		Transform transform = comp.transform;
		for (int i = 0; i < transform.childCount; i++)
		{
			T component = transform.GetChild(i).GetComponent<T>();
			if ((bool)component && (includeInactive || component.gameObject.activeInHierarchy))
			{
				list.Add(component);
			}
		}
		return list;
	}

	public static List<T> GetComponentsInDirectChildren<T>(this Component comp, bool includeInactive = true) where T : Component
	{
		List<T> list = new List<T>();
		Transform transform = comp.transform;
		for (int i = 0; i < transform.childCount; i++)
		{
			T component = transform.GetChild(i).GetComponent<T>();
			if ((bool)component && (includeInactive || component.gameObject.activeInHierarchy))
			{
				list.Add(component);
			}
		}
		return list;
	}

	public static T GetComponentInDirectChildren<T>(this Component comp) where T : Component
	{
		Transform transform = comp.transform;
		for (int i = 0; i < transform.childCount; i++)
		{
			T component = transform.GetChild(i).GetComponent<T>();
			if ((bool)component)
			{
				return component;
			}
		}
		return null;
	}

	public static void DestroyChildren(this Component component, bool destroyInactive = false, bool ignoreDestroy = true)
	{
		if (!component || !component.transform)
		{
			Debug.LogWarning("DestroyChlidren:" + component);
			return;
		}
		for (int num = component.transform.childCount - 1; num >= 0; num--)
		{
			GameObject gameObject = component.transform.GetChild(num).gameObject;
			if ((!ignoreDestroy || !(gameObject.tag == "IgnoreDestroy")) && (destroyInactive || gameObject.activeSelf))
			{
				UnityEngine.Object.DestroyImmediate(gameObject);
			}
		}
	}

	public static bool IsMouseOver(this RectTransform r, Camera cam)
	{
		return RectTransformUtility.RectangleContainsScreenPoint(r, Input.mousePosition, cam);
	}

	public static void RebuildLayout(this Component c, bool recursive = false)
	{
		if (recursive)
		{
			foreach (Transform item in c.transform)
			{
				if (item is RectTransform)
				{
					item.RebuildLayout(recursive: true);
				}
			}
		}
		LayoutRebuilder.ForceRebuildLayoutImmediate(c.transform as RectTransform);
	}

	public static void RebuildLayoutTo<T>(this Component c) where T : Component
	{
		c.RebuildLayout();
		if ((bool)c.transform.parent && !c.transform.parent.GetComponent<T>())
		{
			c.transform.parent.RebuildLayoutTo<T>();
		}
	}

	public static void RebuildLayoutTo(this Component c, Component target)
	{
		c.RebuildLayout();
		if (!(c == target) && (bool)c.transform.parent)
		{
			c.transform.parent.RebuildLayoutTo(target);
		}
	}

	public static void SetRect(this RectTransform r, float x, float y, float w, float h, float pivotX, float pivotY, float minX, float minY, float maxX, float maxY)
	{
		r.SetPivot(pivotX, pivotY);
		r.SetAnchor(minX, minY, maxX, maxY);
		if (w != -1f)
		{
			r.sizeDelta = new Vector2(w, h);
		}
		r.anchoredPosition = new Vector2((x == -1f) ? r.anchoredPosition.x : x, (y == -1f) ? r.anchoredPosition.y : y);
	}

	public static void SetPivot(this RectTransform r, float x, float y)
	{
		r.pivot = new Vector2(x, y);
	}

	public static void SetAnchor(this RectTransform r, float minX, float minY, float maxX, float maxY)
	{
		r.anchorMin = new Vector2(minX, minY);
		r.anchorMax = new Vector2(maxX, maxY);
	}

	public static void _SetAnchor(this RectTransform _rect, RectPosition anchor)
	{
		switch (anchor)
		{
		case RectPosition.TopCenter:
			_rect.SetAnchor(0.5f, 1f, 0.5f, 1f);
			break;
		case RectPosition.BottomCenter:
			_rect.SetAnchor(0.5f, 0f, 0.5f, 0f);
			break;
		case RectPosition.TopLEFT:
			_rect.SetAnchor(0f, 1f, 0f, 1f);
			break;
		case RectPosition.TopRIGHT:
			_rect.SetAnchor(1f, 1f, 1f, 1f);
			break;
		case RectPosition.BottomLEFT:
			_rect.SetAnchor(0f, 0f, 0f, 0f);
			break;
		case RectPosition.BottomRIGHT:
			_rect.SetAnchor(1f, 0f, 1f, 0f);
			break;
		case RectPosition.Left:
			_rect.SetAnchor(0f, 0.5f, 0f, 0.5f);
			break;
		case RectPosition.Right:
			_rect.SetAnchor(1f, 0.5f, 1f, 0.5f);
			break;
		default:
			_rect.SetAnchor(0.5f, 0.5f, 0.5f, 0.5f);
			break;
		}
	}

	public static void SetAnchor(this RectTransform _rect, RectPosition anchor = RectPosition.Auto)
	{
		Vector3 position = _rect.position;
		_rect._SetAnchor((anchor == RectPosition.Auto) ? _rect.GetAnchor() : anchor);
		_rect.position = position;
	}

	public static RectPosition GetAnchor(this RectTransform _rect)
	{
		Vector3 position = _rect.position;
		int width = Screen.width;
		int height = Screen.height;
		bool flag = position.y > (float)height * 0.5f;
		if (position.x > (float)width * 0.3f && position.x < (float)width * 0.7f)
		{
			if (position.y > (float)height * 0.3f && position.y < (float)height * 0.7f)
			{
				return RectPosition.Center;
			}
			if (!flag)
			{
				return RectPosition.BottomCenter;
			}
			return RectPosition.TopCenter;
		}
		if (position.x < (float)width * 0.5f)
		{
			if (!flag)
			{
				return RectPosition.BottomLEFT;
			}
			return RectPosition.TopLEFT;
		}
		if (!flag)
		{
			return RectPosition.BottomRIGHT;
		}
		return RectPosition.TopRIGHT;
	}

	public static Transform GetLastChild(this Transform trans)
	{
		return trans.GetChild(trans.childCount - 1);
	}

	public static Vector2 ToVector2(this Vector3 self)
	{
		return new Vector2(self.x, self.z);
	}

	public static void SetScale(this SpriteRenderer renderer, float size)
	{
		float x = renderer.bounds.size.x;
		float y = renderer.bounds.size.y;
		float x2 = size / x;
		float y2 = size / y;
		renderer.transform.localScale = new Vector3(x2, y2, 1f);
	}

	private static float GetForwardDiffPoint(Vector2 forward)
	{
		if (object.Equals(forward, Vector2.up))
		{
			return 90f;
		}
		object.Equals(forward, Vector2.right);
		return 0f;
	}

	public static void LookAt2D(this Transform self, Transform target, Vector2 forward)
	{
		self.LookAt2D(target.position, forward);
	}

	public static void LookAt2D(this Transform self, Vector3 target, Vector2 forward)
	{
		float forwardDiffPoint = GetForwardDiffPoint(forward);
		Vector3 vector = target - self.position;
		float num = Mathf.Atan2(vector.y, vector.x) * 57.29578f;
		self.rotation = Quaternion.AngleAxis(num - forwardDiffPoint, Vector3.forward);
	}

	public static float Distance(this Transform t, Vector2 pos)
	{
		return Vector3.Distance(t.position, pos);
	}

	public static Vector3 Plus(this Vector3 v, Vector2 v2)
	{
		v.x += v2.x;
		v.y += v2.y;
		return v;
	}

	public static Vector3 SetZ(this Vector3 v, float a)
	{
		v.z = a;
		return v;
	}

	public static Vector3 SetY(this Vector3 v, float a)
	{
		v.y = a;
		return v;
	}

	public static Vector3 PlusX(this Vector3 v, float a)
	{
		v.x += a;
		return v;
	}

	public static Vector3 PlusY(this Vector3 v, float a)
	{
		v.y += a;
		return v;
	}

	public static Vector3 PlusZ(this Vector3 v, float a)
	{
		v.z += a;
		return v;
	}

	public static void SetPosition(this Transform transform, float x, float y, float z)
	{
		vector3.Set(x, y, z);
		transform.position = vector3;
	}

	public static void SetPositionX(this Transform transform, float x)
	{
		vector3.Set(x, transform.position.y, transform.position.z);
		transform.position = vector3;
	}

	public static void SetPositionY(this Transform transform, float y)
	{
		vector3.Set(transform.position.x, y, transform.position.z);
		transform.position = vector3;
	}

	public static void SetPositionZ(this Transform transform, float z)
	{
		vector3.Set(transform.position.x, transform.position.y, z);
		transform.position = vector3;
	}

	public static void AddPosition(this Transform transform, float x, float y, float z)
	{
		vector3.Set(transform.position.x + x, transform.position.y + y, transform.position.z + z);
		transform.position = vector3;
	}

	public static void AddPositionX(this Transform transform, float x)
	{
		vector3.Set(transform.position.x + x, transform.position.y, transform.position.z);
		transform.position = vector3;
	}

	public static void AddPositionY(this Transform transform, float y)
	{
		vector3.Set(transform.position.x, transform.position.y + y, transform.position.z);
		transform.position = vector3;
	}

	public static void AddPositionZ(this Transform transform, float z)
	{
		vector3.Set(transform.position.x, transform.position.y, transform.position.z + z);
		transform.position = vector3;
	}

	public static void SetLocalPosition(this Transform transform, float x, float y, float z)
	{
		vector3.Set(x, y, z);
		transform.localPosition = vector3;
	}

	public static void SetLocalPositionX(this Transform transform, float x)
	{
		vector3.Set(x, transform.localPosition.y, transform.localPosition.z);
		transform.localPosition = vector3;
	}

	public static void SetLocalPositionY(this Transform transform, float y)
	{
		vector3.Set(transform.localPosition.x, y, transform.localPosition.z);
		transform.localPosition = vector3;
	}

	public static void SetLocalPositionZ(this Transform transform, float z)
	{
		vector3.Set(transform.localPosition.x, transform.localPosition.y, z);
		transform.localPosition = vector3;
	}

	public static void AddLocalPosition(this Transform transform, float x, float y, float z)
	{
		vector3.Set(transform.localPosition.x + x, transform.localPosition.y + y, transform.localPosition.z + z);
		transform.localPosition = vector3;
	}

	public static void AddLocalPositionX(this Transform transform, float x)
	{
		vector3.Set(transform.localPosition.x + x, transform.localPosition.y, transform.localPosition.z);
		transform.localPosition = vector3;
	}

	public static void AddLocalPositionY(this Transform transform, float y)
	{
		vector3.Set(transform.localPosition.x, transform.localPosition.y + y, transform.localPosition.z);
		transform.localPosition = vector3;
	}

	public static void AddLocalPositionZ(this Transform transform, float z)
	{
		vector3.Set(transform.localPosition.x, transform.localPosition.y, transform.localPosition.z + z);
		transform.localPosition = vector3;
	}

	public static void SetLocalScale(this Transform transform, float x, float y, float z)
	{
		vector3.Set(x, y, z);
		transform.localScale = vector3;
	}

	public static void SetLocalScaleX(this Transform transform, float x)
	{
		vector3.Set(x, transform.localScale.y, transform.localScale.z);
		transform.localScale = vector3;
	}

	public static void SetLocalScaleY(this Transform transform, float y)
	{
		vector3.Set(transform.localScale.x, y, transform.localScale.z);
		transform.localScale = vector3;
	}

	public static void SetLocalScaleZ(this Transform transform, float z)
	{
		vector3.Set(transform.localScale.x, transform.localScale.y, z);
		transform.localScale = vector3;
	}

	public static void AddLocalScale(this Transform transform, float x, float y, float z)
	{
		vector3.Set(transform.localScale.x + x, transform.localScale.y + y, transform.localScale.z + z);
		transform.localScale = vector3;
	}

	public static void AddLocalScaleX(this Transform transform, float x)
	{
		vector3.Set(transform.localScale.x + x, transform.localScale.y, transform.localScale.z);
		transform.localScale = vector3;
	}

	public static void AddLocalScaleY(this Transform transform, float y)
	{
		vector3.Set(transform.localScale.x, transform.localScale.y + y, transform.localScale.z);
		transform.localScale = vector3;
	}

	public static void AddLocalScaleZ(this Transform transform, float z)
	{
		vector3.Set(transform.localScale.x, transform.localScale.y, transform.localScale.z + z);
		transform.localScale = vector3;
	}

	public static void SetEulerAngles(this Transform transform, float x, float y, float z)
	{
		vector3.Set(x, y, z);
		transform.eulerAngles = vector3;
	}

	public static void SetEulerAnglesX(this Transform transform, float x)
	{
		vector3.Set(x, transform.localEulerAngles.y, transform.localEulerAngles.z);
		transform.eulerAngles = vector3;
	}

	public static void SetEulerAnglesY(this Transform transform, float y)
	{
		vector3.Set(transform.localEulerAngles.x, y, transform.localEulerAngles.z);
		transform.eulerAngles = vector3;
	}

	public static void SetEulerAnglesZ(this Transform transform, float z)
	{
		vector3.Set(transform.localEulerAngles.x, transform.localEulerAngles.y, z);
		transform.eulerAngles = vector3;
	}

	public static void AddEulerAngles(this Transform transform, float x, float y, float z)
	{
		vector3.Set(transform.eulerAngles.x + x, transform.eulerAngles.y + y, transform.eulerAngles.z + z);
		transform.eulerAngles = vector3;
	}

	public static void AddEulerAnglesX(this Transform transform, float x)
	{
		vector3.Set(transform.eulerAngles.x + x, transform.eulerAngles.y, transform.eulerAngles.z);
		transform.eulerAngles = vector3;
	}

	public static void AddEulerAnglesY(this Transform transform, float y)
	{
		vector3.Set(transform.eulerAngles.x, transform.eulerAngles.y + y, transform.eulerAngles.z);
		transform.eulerAngles = vector3;
	}

	public static void AddEulerAnglesZ(this Transform transform, float z)
	{
		vector3.Set(transform.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z + z);
		transform.eulerAngles = vector3;
	}

	public static void SetLocalEulerAngles(this Transform transform, float x, float y, float z)
	{
		vector3.Set(x, y, z);
		transform.localEulerAngles = vector3;
	}

	public static void SetLocalEulerAnglesX(this Transform transform, float x)
	{
		vector3.Set(x, transform.localEulerAngles.y, transform.localEulerAngles.z);
		transform.localEulerAngles = vector3;
	}

	public static void SetLocalEulerAnglesY(this Transform transform, float y)
	{
		vector3.Set(transform.localEulerAngles.x, y, transform.localEulerAngles.z);
		transform.localEulerAngles = vector3;
	}

	public static void SetLocalEulerAnglesZ(this Transform transform, float z)
	{
		vector3.Set(transform.localEulerAngles.x, transform.localEulerAngles.y, z);
		transform.localEulerAngles = vector3;
	}

	public static void AddLocalEulerAngles(this Transform transform, float x, float y, float z)
	{
		vector3.Set(transform.localEulerAngles.x + x, transform.localEulerAngles.y + y, transform.localEulerAngles.z + z);
		transform.localEulerAngles = vector3;
	}

	public static void AddLocalEulerAnglesX(this Transform transform, float x)
	{
		vector3.Set(transform.localEulerAngles.x + x, transform.localEulerAngles.y, transform.localEulerAngles.z);
		transform.localEulerAngles = vector3;
	}

	public static void AddLocalEulerAnglesY(this Transform transform, float y)
	{
		vector3.Set(transform.localEulerAngles.x, transform.localEulerAngles.y + y, transform.localEulerAngles.z);
		transform.localEulerAngles = vector3;
	}

	public static void AddLocalEulerAnglesZ(this Transform transform, float z)
	{
		vector3.Set(transform.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z + z);
		transform.localEulerAngles = vector3;
	}

	public static void ToggleKeyword(this Material m, string id, bool enable)
	{
		if (enable)
		{
			m.EnableKeyword(id);
		}
		else
		{
			m.DisableKeyword(id);
		}
	}

	public static void ForeachReverse<T>(this IList<T> items, Action<T> action)
	{
		for (int num = items.Count - 1; num >= 0; num--)
		{
			action(items[num]);
		}
	}

	public static void ForeachReverse<T>(this IList<T> items, Func<T, bool> action)
	{
		int num = items.Count - 1;
		while (num >= 0 && !action(items[num]))
		{
			num--;
		}
	}

	public static float ClampAngle(this float angle)
	{
		if (angle < 0f)
		{
			return 360f - (0f - angle) % 360f;
		}
		return angle % 360f;
	}

	public static Vector3 Random(this Vector3 v)
	{
		return new Vector3(Rand.Range(0f - v.x, v.x), Rand.Range(0f - v.y, v.y), Rand.Range(0f - v.z, v.z));
	}

	public static T Instantiate<T>(this T s) where T : ScriptableObject
	{
		string name = s.name;
		T val = UnityEngine.Object.Instantiate(s);
		val.name = name;
		return val;
	}

	public static int GetRuntimeEventCount(this UnityEventBase unityEvent)
	{
		Type typeFromHandle = typeof(UnityEventBase);
		Assembly assembly = Assembly.GetAssembly(typeFromHandle);
		Type type = assembly.GetType("UnityEngine.Events.InvokableCallList");
		Type type2 = assembly.GetType("UnityEngine.Events.BaseInvokableCall");
		Type type3 = typeof(List<>).MakeGenericType(type2);
		FieldInfo field = typeFromHandle.GetField("m_Calls", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = type.GetField("m_RuntimeCalls", BindingFlags.Instance | BindingFlags.NonPublic);
		object value = field.GetValue(unityEvent);
		object value2 = field2.GetValue(value);
		return (int)type3.GetProperty("Count").GetValue(value2, null);
	}
}

+ColorUtil

File Created
cs
using UnityEngine;

public class ColorUtil
{
	public static Color RandomHSV(float minS, float maxS, float minV, float maxV)
	{
		return HSVToRGB(Rand.Range(0f, 1f), Rand.Range(minS, maxS), Rand.Range(minV, maxV));
	}

	public static Color HSVToRGB(float H, float S, float V)
	{
		Color white = Color.white;
		if (S == 0f)
		{
			white.r = V;
			white.g = V;
			white.b = V;
		}
		else if (V == 0f)
		{
			white.r = 0f;
			white.g = 0f;
			white.b = 0f;
		}
		else
		{
			white.r = 0f;
			white.g = 0f;
			white.b = 0f;
			float num = H * 6f;
			int num2 = (int)Mathf.Floor(num);
			float num3 = num - (float)num2;
			float num4 = V * (1f - S);
			float num5 = V * (1f - S * num3);
			float num6 = V * (1f - S * (1f - num3));
			switch (num2)
			{
			case -1:
				white.r = V;
				white.g = num4;
				white.b = num5;
				break;
			case 0:
				white.r = V;
				white.g = num6;
				white.b = num4;
				break;
			case 1:
				white.r = num5;
				white.g = V;
				white.b = num4;
				break;
			case 2:
				white.r = num4;
				white.g = V;
				white.b = num6;
				break;
			case 3:
				white.r = num4;
				white.g = num5;
				white.b = V;
				break;
			case 4:
				white.r = num6;
				white.g = num4;
				white.b = V;
				break;
			case 5:
				white.r = V;
				white.g = num4;
				white.b = num5;
				break;
			case 6:
				white.r = V;
				white.g = num6;
				white.b = num4;
				break;
			}
			white.r = Mathf.Clamp(white.r, 0f, 1f);
			white.g = Mathf.Clamp(white.g, 0f, 1f);
			white.b = Mathf.Clamp(white.b, 0f, 1f);
		}
		return white;
	}
}

+ConsoleProDebug

File Created
cs
using UnityEngine;

public static class ConsoleProDebug
{
	public static void Clear()
	{
	}

	public static void LogToFilter(string inLog, string inFilterName)
	{
		Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"Filter\" \"name\":\"" + inFilterName + "\"}");
	}

	public static void LogAsType(string inLog, string inTypeName)
	{
		Debug.Log(inLog + "\nCPAPI:{\"cmd\":\"LogType\" \"name\":\"" + inTypeName + "\"}");
	}

	public static void Watch(string inName, string inValue)
	{
		Debug.Log(inName + " : " + inValue + "\nCPAPI:{\"cmd\":\"Watch\" \"name\":\"" + inName + "\"}");
	}

	public static void Search(string inText)
	{
		Debug.Log("\nCPAPI:{\"cmd\":\"Search\" \"text\":\"" + inText + "\"}");
	}
}

+ContainerFlag

File Created
cs
using System;

[Flags]
public enum ContainerFlag
{
	none = 0,
	resource = 1,
	food = 2,
	drink = 4,
	weapon = 8,
	armor = 0x10,
	tool = 0x20,
	item = 0x40,
	book = 0x80,
	currency = 0x100,
	furniture = 0x200,
	block = 0x400,
	other = 0x800
}

+ContainerFlag2

File Created
cs
using System;

[Flags]
public enum ContainerFlag2
{
	none = 0,
	meal = 1,
	foodstuff = 2,
	meat = 4,
	vegi = 8,
	fruit = 0x10,
	mushroom = 0x20,
	egg = 0x21,
	fish = 0x40,
	nuts = 0x80,
	foodstuff_raw = 0x100,
	seasoning = 0x200,
	rod = 0x400,
	junk = 0x800,
	garbage = 0x1000,
	bill = 0x2000,
	scroll = 0x4000,
	spellbook = 0x8000,
	card = 0x10000,
	figure = 0x20000,
	bait = 0x40000,
	seed = 0x80000,
	stone = 0x100000,
	textile = 0x200000,
	flora = 0x400000,
	bodyparts = 0x800000,
	fertilizer = 0x1000000,
	milk = 0x2000000,
	wood = 0x4000000,
	ore = 0x8000000,
	ammo = 0x10000000,
	bed = 0x20000000
}

+ContainerSharedType

File Created
cs
public enum ContainerSharedType
{
	Personal,
	Shared
}

+CoreEmu

File Created
cs
public class CoreEmu : BaseCore
{
	public BaseModManager mods = new BaseModManager();

	public new static CoreEmu Instance;

	protected override void Awake()
	{
		base.Awake();
		Instance = this;
		BaseCore.Instance = this;
		CorePath.Init();
	}
}

+CorePath

File Created
cs
using System;
using System.IO;
using UnityEngine;

[Serializable]
public class CorePath
{
	public class UI
	{
		public const string UIMain = "UI/";

		public const string Layer = "UI/Layer/";

		public const string Content = "UI/Content/";

		public const string Window = "UI/Window/";

		public const string WindowBase = "UI/Window/Base/";

		public const string WindowElement = "UI/Window/Base/Element/";

		public const string Widget = "UI/Widget/";

		public const string Element = "UI/Element/";

		public const string Header = "UI/Element/Header/";

		public const string Text = "UI/Element/Text/";

		public const string Note = "UI/Element/Note/";

		public const string Deco = "UI/Element/Deco/";

		public const string Item = "UI/Element/Item/";

		public const string Button = "UI/Element/Button/";

		public const string Other = "UI/Element/Other/";

		public const string List = "UI/Element/List/";

		public const string Pop = "UI/Pop/";

		public const string Util = "UI/Util/";
	}

	public class CorePackage
	{
		public static string TextData => Lang.setting.dir + "Data/";

		public static string TextDialog
		{
			get
			{
				if (Lang.isBuiltin)
				{
					return packageCore + "Lang/_Dialog/";
				}
				return Lang.setting.dir + "Dialog/";
			}
		}

		public static string TextNarration => Lang.setting.dir + "Narration/";

		public static string TextCommon => packageCore + "Lang/_Common/";

		public static string Text => Lang.setting.dir + "Text/";

		public static string TextEN => packageCore + "Lang/EN/Text/";

		public static string Book => Text + "Book/";

		public static string Scroll => Text + "Scroll/";

		public static string Help => Text + "Help/";

		public static string HelpEN => packageCore + "Lang/EN/Text/HELP/";

		public static string News => Text + "News/";

		public static string Background => Text + "Background/";

		public static string Playlist => packageCore + "Sound/Playlist/";

		public static string LangImportMod => Lang.setting.dir + "Game/";

		public static string Ride => packageCore + "Actor/PCC/ride/";
	}

	public const string Scene = "Scene/";

	public const string SceneProfile = "Scene/Profile/";

	public const string FowProfile = "Scene/Profile/Fow/";

	public const string SceneTemplate = "Scene/Template/";

	public const string Lut = "Scene/Profile/Lut/";

	public const string PostEffect = "Scene/Profile/PostEffect/";

	public const string Data_Raw = "Data/Raw/";

	public const string Map = "World/Map/";

	public const string MapGen = "World/Map/Gen/";

	public const string ZoneProfile = "World/Zone/Profile/";

	public const string Media = "Media/";

	public const string Gallery = "Media/Gallery/";

	public const string Anime = "Media/Anime/";

	public const string Sound = "Media/Sound/";

	public const string Effect = "Media/Effect/";

	public const string TextEffect = "Media/Text/";

	public const string Particle = "Media/Effect/Particle/";

	public const string Graphics = "Media/Graphics/";

	public const string Icon = "Media/Graphics/Icon/";

	public const string IconElement = "Media/Graphics/Icon/Element/";

	public const string IconAchievement = "Media/Graphics/Icon/Achievement/";

	public const string IconRecipe = "Media/Graphics/Icon/Recipe/";

	public const string Image = "Media/Graphics/Image/";

	public const string Deco = "Media/Graphics/Deco/";

	public const string Drama = "Media/Drama/";

	public const string DramaActor = "Media/Drama/Actor/";

	public const string BuildMenu = "UI/BuildMenu/";

	public const string Render = "Scene/Render/";

	public const string Actor = "Scene/Render/Actor/";

	public const string RenderData = "Scene/Render/Data/";

	public const string TC = "Scene/Render/Actor/Component/";

	public const string Hoard = "UI/Layer/Hoard/";

	public const string News = "UI/Layer/LayerNewspaper/";

	[NonSerialized]
	public static string packageCore;

	[NonSerialized]
	public static string user;

	[NonSerialized]
	public static string custom;

	[NonSerialized]
	public static string rootMod;

	[NonSerialized]
	public static string rootExe;

	public static string Text_Popup => Lang.setting.dir + "Etc/Popup/";

	public static string Text_DialogHelp => Lang.setting.dir + "Etc/DialogHelp/";

	public static string DramaData => packageCore + "Lang/_Dialog/Drama/";

	public static string DramaDataLocal => Lang.setting.dir + "Dialog/Drama/";

	public static string ConfigFile => RootSave + "/config.txt";

	public static string VersionFile => RootSave + "/version.txt";

	public static string ShareSettingFile => RootSave + "/share_setting.txt";

	public static string coreWidget => packageCore + "Widget/";

	public static string WidgetSave => user + "Widget/";

	public static string LotTemplate => user + "Lot Template/";

	public static string SceneCustomizerSave => user + "Scene/";

	public static string ZoneSave => packageCore + "Map/";

	public static string ZoneSaveUser => user + "Map/";

	public static string MapPieceSave => packageCore + "Map Piece/";

	public static string MapPieceSaveUser => user + "Map Piece/";

	public static string RootData => Application.persistentDataPath + "/";

	public static string RootSave => Application.persistentDataPath + "/Save/";

	public static string RootSaveCloud => Application.persistentDataPath + "/Cloud Save/";

	public static string Temp => RootSave + "_Temp/";

	public static string PathIni => RootSave + "elin.ini";

	public static string PathBackupOld => RootSave + "Backup/";

	public static string PathBackup => RootData + "Backup/";

	public static string PathBackupCloud => RootData + "Cloud Backup/";

	public static void Init()
	{
		Debug.Log("Init CorePath");
		rootMod = Application.dataPath + "/../Package/";
		if (!Directory.Exists(rootMod))
		{
			rootMod = Application.streamingAssetsPath + "/Package/";
		}
		rootExe = Application.dataPath + "/../";
		packageCore = rootMod + "_Elona/";
		user = Application.persistentDataPath + "/User/";
		custom = Application.persistentDataPath + "/Custom/";
		if (!Application.isPlaying)
		{
			return;
		}
		if (!Directory.Exists(PathBackup))
		{
			if (Directory.Exists(PathBackupOld))
			{
				Directory.Move(PathBackupOld, PathBackup);
			}
			else
			{
				IO.CreateDirectory(PathBackup);
			}
		}
		IO.CreateDirectory(PathBackupCloud);
		IO.CreateDirectory(RootSave);
		IO.CreateDirectory(RootSaveCloud);
		string text = (Application.isEditor ? (Application.streamingAssetsPath + "/User/") : (rootExe + "User/"));
		if (!Application.isEditor || !Directory.Exists(user))
		{
			Debug.Log("Copy User Folder:" + text + "  to  " + user);
			IO.CreateDirectory(user);
			IO.CopyAll(text, user, overwrite: false);
			IO.CreateDirectory(SceneCustomizerSave);
		}
		text = (Application.isEditor ? (Application.streamingAssetsPath + "/Custom/") : (rootExe + "Custom/"));
		Debug.Log("Copy Custom Folder:" + text + "  to  " + custom);
		IO.CreateDirectory(custom);
		IO.CopyAll(text, custom, overwrite: false);
	}
}

+CustomAssetManager

File Created
cs
using System.Collections.Generic;
using UnityEngine;

public class CustomAssetManager : ScriptableObject, ISerializationCallbackReceiver
{
	public static CustomAssetManager Instance;

	public string pathEditor = "Assets/Plugins/Essential/DB/Editor/";

	public string exportPath = "Assets/Resources/Data/";

	public string assembly = "Plugins.BaseCore";

	public List<string> pathRawImport;

	public List<ExcelBookImportSetting> books;

	private void Awake()
	{
		Instance = this;
	}

	public void OnBeforeSerialize()
	{
		Instance = this;
	}

	public void OnAfterDeserialize()
	{
		Instance = this;
	}

	public ExcelBookImportSetting GetBook(string id)
	{
		foreach (ExcelBookImportSetting book in books)
		{
			if (book.name == id)
			{
				return book;
			}
		}
		return null;
	}

	public ExcelBookImportSetting GetOrCreateBook(string id)
	{
		ExcelBookImportSetting book = GetBook(id);
		if (book != null)
		{
			return book;
		}
		book = new ExcelBookImportSetting
		{
			name = id
		};
		books.Add(book);
		return book;
	}
}

+DateHelper

File Created
cs
using System;

public class DateHelper
{
	private const int SECOND = 1;

	private const int MINUTE = 60;

	private const int HOUR = 3600;

	private const int DAY = 86400;

	private const int MONTH = 2592000;

	public static string GetLastTime(long time)
	{
		TimeSpan timeSpan = new TimeSpan(DateTime.UtcNow.Ticks - time);
		double num = Math.Abs(timeSpan.TotalSeconds);
		if (num < 60.0)
		{
			if (timeSpan.Seconds != 1)
			{
				return timeSpan.Seconds + " seconds ago";
			}
			return "one second ago";
		}
		if (num < 120.0)
		{
			return "a minute ago";
		}
		if (num < 2700.0)
		{
			return timeSpan.Minutes + " minutes ago";
		}
		if (num < 5400.0)
		{
			return "an hour ago";
		}
		if (num < 86400.0)
		{
			return timeSpan.Hours + " hours ago";
		}
		if (num < 172800.0)
		{
			return "yesterday";
		}
		if (num < 2592000.0)
		{
			return timeSpan.Days + " days ago";
		}
		if (num < 31104000.0)
		{
			int num2 = Convert.ToInt32(Math.Floor((double)timeSpan.Days / 30.0));
			if (num2 > 1)
			{
				return num2 + " months ago";
			}
			return "one month ago";
		}
		int num3 = Convert.ToInt32(Math.Floor((double)timeSpan.Days / 365.0));
		if (num3 > 1)
		{
			return num3 + " years ago";
		}
		return "one year ago";
	}
}

+DynamicAsset

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
public class DynamicAsset<T> where T : MonoBehaviour
{
	public string groupId = "";

	public List<T> list = new List<T>();

	public Dictionary<string, T> map;

	public bool usePool;

	public bool instantiate = true;

	private bool initialized;

	public DynamicAsset()
	{
	}

	public DynamicAsset(string groupId, bool instantiate)
	{
		this.groupId = groupId;
		this.instantiate = instantiate;
	}

	private void Init()
	{
		map = new Dictionary<string, T>();
		foreach (T item in list)
		{
			map.Add(item.name, item);
		}
		initialized = true;
	}

	public T GetNew(string id, Transform parent = null)
	{
		T original = GetOriginal(id);
		if (!instantiate || original == null)
		{
			return original;
		}
		T val = (usePool ? PoolManager.Spawn<T>(groupId + "/" + id, groupId + "/" + id) : UnityEngine.Object.Instantiate(original).GetComponent<T>());
		if ((bool)parent)
		{
			val.transform.SetParent(parent, worldPositionStays: false);
		}
		return val;
	}

	public T GetOriginal(string id)
	{
		if (!initialized)
		{
			Init();
		}
		if (map.TryGetValue(id, out var value))
		{
			return value;
		}
		value = Resources.Load<T>(groupId + "/" + id);
		map[id] = value;
		list.Add(value);
		return value;
	}
}

+EAction

File Created
cs
public enum EAction
{
	None = 0,
	AxisUp = 1,
	AxisDown = 2,
	AxisLeft = 3,
	AxisRight = 4,
	AxisUpLeft = 5,
	AxisUpRight = 6,
	AxisDownLeft = 7,
	AxisDownRight = 8,
	MouseLeft = 10,
	MouseMiddle = 11,
	MouseRight = 12,
	Wait = 20,
	Interact = 21,
	Search = 22,
	Pick = 23,
	Fire = 24,
	Help = 30,
	Log = 31,
	Pause = 32,
	MenuInventory = 33,
	MenuChara = 34,
	MenuJournal = 35,
	MenuAbility = 36,
	Use = 37,
	Confirm = 38,
	Cancel = 39,
	Next = 40,
	Prev = 41,
	Chat = 42,
	Diagonal = 43,
	ShowGrid = 44,
	Report = 45,
	QuickSave = 46,
	QuickLoad = 47,
	AutoCombat = 48,
	EmptyHand = 49,
	SwitchHotbar = 50,
	Examine = 51,
	GetAll = 52,
	CancelUI = 53,
	Dump = 54,
	Mute = 55,
	Meditate = 56
}

+EInput

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class EInput : MonoBehaviour
{
	[Serializable]
	public class KeyMap
	{
		public EAction action;

		public KeyCode key;

		public bool required;

		public int GetGroup()
		{
			if (action == EAction.Examine)
			{
				return 1;
			}
			if (action == EAction.GetAll)
			{
				return 2;
			}
			return 0;
		}
	}

	[Serializable]
	public class KeyMapManager
	{
		public KeyMap cancel = new KeyMap
		{
			action = EAction.CancelUI
		};

		public KeyMap axisUp = new KeyMap
		{
			action = EAction.AxisUp
		};

		public KeyMap axisDown = new KeyMap
		{
			action = EAction.AxisDown
		};

		public KeyMap axisLeft = new KeyMap
		{
			action = EAction.AxisLeft
		};

		public KeyMap axisRight = new KeyMap
		{
			action = EAction.AxisRight
		};

		public KeyMap axisUpLeft = new KeyMap
		{
			action = EAction.AxisUpLeft
		};

		public KeyMap axisUpRight = new KeyMap
		{
			action = EAction.AxisUpRight
		};

		public KeyMap axisDownLeft = new KeyMap
		{
			action = EAction.AxisDownLeft
		};

		public KeyMap axisDownRight = new KeyMap
		{
			action = EAction.AxisDownRight
		};

		public KeyMap journal = new KeyMap
		{
			action = EAction.MenuJournal
		};

		public KeyMap chara = new KeyMap
		{
			action = EAction.MenuChara
		};

		public KeyMap inventory = new KeyMap
		{
			action = EAction.MenuInventory
		};

		public KeyMap ability = new KeyMap
		{
			action = EAction.MenuAbility
		};

		public KeyMap log = new KeyMap
		{
			action = EAction.Log
		};

		public KeyMap fire = new KeyMap
		{
			action = EAction.Fire
		};

		public KeyMap wait = new KeyMap
		{
			action = EAction.Wait
		};

		public KeyMap autoCombat = new KeyMap
		{
			action = EAction.AutoCombat
		};

		public KeyMap emptyHand = new KeyMap
		{
			action = EAction.EmptyHand
		};

		public KeyMap mouseLeft = new KeyMap
		{
			action = EAction.MouseLeft
		};

		public KeyMap mouseRight = new KeyMap
		{
			action = EAction.MouseRight
		};

		public KeyMap mouseMiddle = new KeyMap
		{
			action = EAction.MouseMiddle
		};

		public KeyMap report = new KeyMap
		{
			action = EAction.Report
		};

		public KeyMap quickSave = new KeyMap
		{
			action = EAction.QuickSave
		};

		public KeyMap quickLoad = new KeyMap
		{
			action = EAction.QuickLoad
		};

		public KeyMap switchHotbar = new KeyMap
		{
			action = EAction.SwitchHotbar
		};

		public KeyMap examine = new KeyMap
		{
			action = EAction.Examine
		};

		public KeyMap getAll = new KeyMap
		{
			action = EAction.GetAll
		};

		public KeyMap dump = new KeyMap
		{
			action = EAction.Dump
		};

		public KeyMap mute = new KeyMap
		{
			action = EAction.Mute
		};

		public KeyMap meditate = new KeyMap
		{
			action = EAction.Meditate
		};

		public KeyMap search = new KeyMap
		{
			action = EAction.Search
		};

		public List<KeyMap> List()
		{
			return new List<KeyMap>
			{
				axisUp, axisDown, axisLeft, axisRight, axisUpLeft, axisUpRight, axisDownLeft, axisDownRight, journal, chara,
				inventory, ability, log, fire, wait, mouseLeft, mouseMiddle, mouseRight, report, quickSave,
				quickLoad, autoCombat, emptyHand, switchHotbar, examine, getAll, dump, mute, meditate, search
			};
		}
	}

	public class KeyboardPress
	{
		public float timer;

		public int count;

		public bool consumed;

		public Func<KeyMap> func;

		public EAction Action => func().action;

		public bool IsRepeating => count > 1;

		public bool Update(bool forcePress = false)
		{
			if (Input.GetKey(func().key) || forcePress)
			{
				if (consumed)
				{
					return false;
				}
				if (count == 1)
				{
					timer += delta;
					if (timer < 0.5f)
					{
						return false;
					}
				}
				else
				{
					timer = 0f;
				}
				count++;
				return true;
			}
			consumed = false;
			count = 0;
			return false;
		}

		public void Consume()
		{
			consumed = true;
		}
	}

	public static KeyboardPress keyFire = new KeyboardPress();

	public static KeyboardPress keyWait = new KeyboardPress();

	public static Func<string, string> LangGetter;

	public static EInput Instance;

	public static EventSystem eventSystem;

	public static EAction action;

	public static bool isShiftDown;

	public static bool isCtrlDown;

	public static bool isAltDown;

	public static bool requireConfirmReset;

	public static bool requireAxisReset;

	public static bool hasAxisMoved;

	public static bool hasShiftChanged;

	public static bool haltInput;

	public static bool isInputFieldActive;

	public static bool firstAxisPressed;

	public static bool axisReleased;

	public static int hotkey;

	public static int functionkey;

	public static int skipFrame;

	public static int wheel;

	public static int missClickButton;

	private static float waitInput;

	private static float durationAxis;

	private static float durationFirstAxis;

	private static float durationAxisRelease;

	private static float durationAxisDiagonal;

	private static float waitReleaseKeyTimer;

	private static Vector2 lastAxis;

	private static Vector2 firstAxis;

	private static Vector2 prevAxis;

	public static bool hasMouseMoved;

	public static bool axisXChanged;

	public static bool axisYChanged;

	public static bool waitReleaseAnyKey;

	public static List<ButtonState> buttons = new List<ButtonState>();

	public static float delta;

	public static float antiMissClick;

	public static float missClickDuration;

	public static float dragHack;

	public static float ignoreWheelDuration;

	public static Vector2 axis;

	public static Vector2 forbidAxis;

	public static Vector2 axisDiagonal;

	public static Vector3 mpos;

	public static Vector3 mposWorld;

	public static Vector3 dragStartPos;

	public static Vector3 dragStartPos2;

	public static Vector3 lastMousePos;

	public static Vector3 dragAmount;

	public static ButtonState leftMouse;

	public static ButtonState rightMouse;

	public static ButtonState middleMouse;

	public static ButtonState mouse3;

	public static ButtonState mouse4;

	public static ButtonState buttonScroll;

	public static ButtonState buttonCtrl;

	public static bool rightScroll;

	public static bool disableKeyAxis;

	public static KeyMapManager keys = new KeyMapManager();

	public static Vector3 uiMousePosition;

	public float repeatThresh = 0.3f;

	public float repeatSpeed = 0.05f;

	public static bool isConfirm => action == EAction.Confirm;

	public static bool isCancel
	{
		get
		{
			if (action != EAction.Cancel)
			{
				return action == EAction.CancelUI;
			}
			return true;
		}
	}

	public static bool isPrev => action == EAction.Prev;

	public static bool isNext => action == EAction.Next;

	public static bool IsConsumed => skipFrame > 0;

	public static GameObject selectedGO => eventSystem.currentSelectedGameObject;

	public static void WaitInput(float time)
	{
		waitInput = time;
	}

	private void Awake()
	{
		Instance = this;
		Init();
	}

	public static void Init()
	{
		leftMouse = AddButton(0);
		rightMouse = AddButton(1);
		middleMouse = AddButton(2);
		mouse3 = AddButton(3);
		mouse4 = AddButton(4);
		leftMouse.dragMargin = 32f;
		middleMouse.clickDuration = 0.3f;
		middleMouse.clickCriteria = ButtonState.ClickCriteria.ByDuration;
		middleMouse.ignoreWheel = true;
		middleMouse.id = "middle";
		mouse3.clickDuration = 0.3f;
		mouse3.clickCriteria = ButtonState.ClickCriteria.ByDuration;
		mouse4.clickDuration = 0.3f;
		mouse4.clickCriteria = ButtonState.ClickCriteria.ByDuration;
		buttonCtrl = new ButtonState
		{
			mouse = -1,
			clickCriteria = ButtonState.ClickCriteria.ByDuration
		};
		buttons.Add(buttonCtrl);
		SetKeyMap(keys);
	}

	public static void SetKeyMap(KeyMapManager _keys)
	{
		keys = _keys;
		leftMouse.keymap = keys.mouseLeft;
		rightMouse.keymap = keys.mouseRight;
		middleMouse.keymap = keys.mouseMiddle;
		buttonCtrl.keymap = keys.switchHotbar;
		keyFire.func = () => keys.fire;
		keyWait.func = () => keys.wait;
	}

	public static ButtonState AddButton(int mouse)
	{
		ButtonState buttonState = new ButtonState
		{
			mouse = mouse
		};
		buttons.Add(buttonState);
		return buttonState;
	}

	public static void DisableIME()
	{
		ToggleIME(on: false);
	}

	public static void ToggleIME(bool on)
	{
		Input.imeCompositionMode = (on ? IMECompositionMode.On : IMECompositionMode.Off);
	}

	public static void UpdateOnlyAxis()
	{
		isShiftDown = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
		isCtrlDown = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
		isAltDown = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
		axis = Vector2.zero;
		hasAxisMoved = (hasMouseMoved = false);
		UpdateAxis();
		Consume(3);
	}

	public static void Update()
	{
		missClickDuration -= delta;
		ignoreWheelDuration -= delta;
		dragHack += delta;
		mpos = Input.mousePosition;
		if ((bool)Camera.main)
		{
			mposWorld = Camera.main.ScreenToWorldPoint(mpos);
		}
		mposWorld.z = 0f;
		action = EAction.None;
		axis = Vector2.zero;
		hasAxisMoved = (hasMouseMoved = false);
		wheel = 0;
		if (!Application.isFocused)
		{
			return;
		}
		GameObject gameObject = EventSystem.current?.currentSelectedGameObject;
		if ((bool)gameObject && gameObject.activeInHierarchy)
		{
			isInputFieldActive = gameObject.GetComponent<InputField>();
		}
		else
		{
			isInputFieldActive = false;
		}
		isShiftDown = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
		isCtrlDown = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
		isAltDown = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
		if (waitReleaseAnyKey)
		{
			waitReleaseKeyTimer -= Time.deltaTime;
			if (waitReleaseKeyTimer < 0f)
			{
				waitReleaseAnyKey = false;
			}
			else
			{
				if (!Input.inputString.IsEmpty() || IsAnyKeyDown(includeAxis: true, _skipframe: false))
				{
					return;
				}
				waitReleaseAnyKey = false;
			}
		}
		if (haltInput)
		{
			Consume(consumeAxis: true);
			return;
		}
		if (requireConfirmReset)
		{
			if (Input.GetKey(keys.wait.key) || Input.GetKey(KeyCode.Keypad5))
			{
				Consume(consumeAxis: true);
				return;
			}
			requireConfirmReset = false;
		}
		dragAmount = lastMousePos - mpos;
		if (lastMousePos != mpos)
		{
			lastMousePos = mpos;
			hasMouseMoved = true;
		}
		if (skipFrame > 0)
		{
			skipFrame--;
			return;
		}
		if (waitInput > 0f)
		{
			Consume(consumeAxis: true);
			waitInput -= Time.unscaledDeltaTime;
			return;
		}
		if (Input.GetMouseButtonDown(0))
		{
			missClickButton = 0;
			missClickDuration = antiMissClick;
		}
		if (Input.GetMouseButtonDown(1))
		{
			if (missClickDuration > 0f && missClickButton == 0)
			{
				Consume();
				rightMouse.consumed = false;
				skipFrame = 5;
				return;
			}
			missClickButton = 1;
			missClickDuration = antiMissClick;
		}
		foreach (ButtonState button in buttons)
		{
			button.Update();
		}
		if (ignoreWheelDuration < 0f)
		{
			float num = Input.GetAxis("Mouse ScrollWheel");
			wheel = ((num < 0f) ? (-1) : ((num > 0f) ? 1 : 0));
			if (Input.GetKeyDown(KeyCode.PageUp))
			{
				wheel = 1;
			}
			if (Input.GetKeyDown(KeyCode.PageDown))
			{
				wheel = -1;
			}
		}
		if (isInputFieldActive)
		{
			return;
		}
		UpdateAxis();
		if (requireAxisReset)
		{
			if (axis == Vector2.zero)
			{
				requireAxisReset = false;
			}
			else
			{
				axis = Vector2.zero;
			}
		}
		if (forbidAxis != Vector2.zero && axis == forbidAxis)
		{
			axis = Vector2.zero;
		}
		else
		{
			forbidAxis = Vector2.zero;
		}
		hotkey = GetHotkeyDown();
		if (hotkey == -1 && action == EAction.None)
		{
			action = GetAction();
		}
		functionkey = GetFunctionkeyDown();
	}

	public static bool IsAnyKeyDown(bool includeAxis = true, bool _skipframe = true)
	{
		if (_skipframe && skipFrame > 0)
		{
			return false;
		}
		if (isConfirm || isCancel)
		{
			return true;
		}
		if (includeAxis && axis != Vector2.zero)
		{
			return true;
		}
		foreach (ButtonState button in buttons)
		{
			if (button.clicked)
			{
				return true;
			}
		}
		for (int i = 97; i < 122; i++)
		{
			if (Input.GetKey(i.ToEnum<KeyCode>()))
			{
				return true;
			}
		}
		return false;
	}

	public static void WaitReleaseKey()
	{
		waitReleaseAnyKey = true;
		waitReleaseKeyTimer = 2.5f;
	}

	public static void Consume(int _skipFrame)
	{
		Consume(consumeAxis: false, _skipFrame);
	}

	public static void Consume(bool consumeAxis = false, int _skipFrame = 1)
	{
		wheel = 0;
		action = EAction.None;
		functionkey = -1;
		hotkey = -1;
		if (_skipFrame > skipFrame)
		{
			skipFrame = _skipFrame;
		}
		if (consumeAxis)
		{
			axis = (lastAxis = Vector2.zero);
			requireAxisReset = true;
			durationAxis = 0f;
		}
		foreach (ButtonState button in buttons)
		{
			button.Consume();
		}
	}

	public static void ConsumeWheel()
	{
		wheel = 0;
	}

	public static void SetAxis(int x, int y)
	{
		axis.x = x;
		axis.y = y;
	}

	public static void ModAxisX(int x)
	{
		axis.x += x;
		axisXChanged = true;
	}

	public static void ModAxisY(int y)
	{
		axis.y += y;
		axisYChanged = true;
	}

	private static void UpdateAxis()
	{
		if (waitReleaseAnyKey)
		{
			return;
		}
		axisXChanged = (axisYChanged = false);
		if (Input.GetKey(keys.axisUp.key))
		{
			ModAxisY(1);
		}
		if (Input.GetKey(keys.axisDown.key))
		{
			ModAxisY(-1);
		}
		if (Input.GetKey(keys.axisLeft.key))
		{
			ModAxisX(-1);
		}
		if (Input.GetKey(keys.axisRight.key))
		{
			ModAxisX(1);
		}
		if (axis == Vector2.zero && !disableKeyAxis)
		{
			if (Input.GetKey(keys.axisUp.key) || Input.GetKey(KeyCode.UpArrow))
			{
				ModAxisY(1);
			}
			if (Input.GetKey(keys.axisDown.key) || Input.GetKey(KeyCode.DownArrow))
			{
				ModAxisY(-1);
			}
			if (Input.GetKey(keys.axisLeft.key) || Input.GetKey(KeyCode.LeftArrow))
			{
				ModAxisX(-1);
			}
			if (Input.GetKey(keys.axisRight.key) || Input.GetKey(KeyCode.RightArrow))
			{
				ModAxisX(1);
			}
		}
		if (axis == Vector2.zero)
		{
			if (Input.GetKey(KeyCode.Keypad8))
			{
				ModAxisY(1);
			}
			if (Input.GetKey(KeyCode.Keypad2))
			{
				ModAxisY(-1);
			}
			if (Input.GetKey(KeyCode.Keypad4))
			{
				ModAxisX(-1);
			}
			if (Input.GetKey(KeyCode.Keypad6))
			{
				ModAxisX(1);
			}
		}
		if (Input.GetKey(keys.axisUpLeft.key))
		{
			SetAxis(-1, 1);
		}
		if (Input.GetKey(keys.axisUpRight.key))
		{
			SetAxis(1, 1);
		}
		if (Input.GetKey(keys.axisDownLeft.key))
		{
			SetAxis(-1, -1);
		}
		if (Input.GetKey(keys.axisDownRight.key))
		{
			SetAxis(1, -1);
		}
		if (Input.GetKey(KeyCode.Keypad1))
		{
			SetAxis(-1, -1);
		}
		if (Input.GetKey(KeyCode.Keypad3))
		{
			SetAxis(1, -1);
		}
		if (Input.GetKey(KeyCode.Keypad7))
		{
			SetAxis(-1, 1);
		}
		if (Input.GetKey(KeyCode.Keypad9))
		{
			SetAxis(1, 1);
		}
		if (axis.x == 0f && axisXChanged)
		{
			axis.x = 0f - prevAxis.x;
		}
		else
		{
			prevAxis.x = axis.x;
		}
		if (axis.y == 0f && axisYChanged)
		{
			axis.y = 0f - prevAxis.y;
		}
		else
		{
			prevAxis.y = axis.y;
		}
		if (Input.GetKey(KeyCode.LeftAlt) && (axis.x == 0f || axis.y == 0f))
		{
			axis = Vector2.zero;
		}
		if (axis != Vector2.zero && !firstAxisPressed)
		{
			firstAxisPressed = true;
			firstAxis = axis;
			durationFirstAxis = 0.06f;
		}
		if (firstAxisPressed)
		{
			durationFirstAxis -= delta;
			if (durationFirstAxis > 0f)
			{
				if (!(axis == Vector2.zero))
				{
					axis = Vector2.zero;
					return;
				}
				axis = firstAxis;
			}
			else if (axis == Vector2.zero)
			{
				firstAxisPressed = false;
			}
		}
		if (axis.x != 0f && axis.y != 0f)
		{
			axisDiagonal.x = axis.x;
			axisDiagonal.y = axis.y;
			durationAxisDiagonal += delta;
			if (durationAxisDiagonal > 0f)
			{
				durationAxisDiagonal = 2f;
			}
		}
		else
		{
			durationAxisDiagonal -= delta * 10f;
			if (durationAxisDiagonal < 0f)
			{
				durationAxisDiagonal = 0f;
			}
		}
		if (axis == Vector2.zero)
		{
			durationAxisRelease += delta;
			if (durationAxisRelease < 0.5f + durationAxisDiagonal * 0.1f)
			{
				return;
			}
			lastAxis = Vector2.zero;
		}
		else
		{
			durationAxisRelease = 0f;
		}
		if (durationAxisDiagonal > 1f)
		{
			if (axis != Vector2.zero)
			{
				axis.x = axisDiagonal.x;
				axis.y = axisDiagonal.y;
			}
			lastAxis = Vector2.zero;
			return;
		}
		durationAxis -= delta;
		if (axis != Vector2.zero && axis != lastAxis)
		{
			durationAxis = 0.25f;
			lastAxis = axis;
		}
		else if (durationAxis > 0f)
		{
			axis = lastAxis;
		}
	}

	public static int GetHotkeyDown()
	{
		int result = -1;
		if (Input.GetKeyDown(KeyCode.Alpha1))
		{
			result = 0;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha2))
		{
			result = 1;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha3))
		{
			result = 2;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha4))
		{
			result = 3;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha5))
		{
			result = 4;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha6))
		{
			result = 5;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha7))
		{
			result = 6;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha8))
		{
			result = 7;
		}
		else if (Input.GetKeyDown(KeyCode.Alpha9))
		{
			result = 8;
		}
		return result;
	}

	public static int GetFunctionkeyDown()
	{
		int result = -1;
		if (Input.GetKeyDown(KeyCode.F1))
		{
			result = 0;
		}
		else if (Input.GetKeyDown(KeyCode.F2))
		{
			result = 1;
		}
		else if (Input.GetKeyDown(KeyCode.F3))
		{
			result = 2;
		}
		else if (Input.GetKeyDown(KeyCode.F4))
		{
			result = 3;
		}
		else if (Input.GetKeyDown(KeyCode.F5))
		{
			result = 4;
		}
		else if (Input.GetKeyDown(KeyCode.F6))
		{
			result = 5;
		}
		else if (Input.GetKeyDown(KeyCode.F7))
		{
			result = 6;
		}
		else if (Input.GetKeyDown(KeyCode.F8))
		{
			result = 7;
		}
		return result;
	}

	public static int GetHotkey()
	{
		int result = -1;
		if (Input.GetKey(KeyCode.Alpha1))
		{
			result = 0;
		}
		else if (Input.GetKey(KeyCode.Alpha2))
		{
			result = 1;
		}
		else if (Input.GetKey(KeyCode.Alpha3))
		{
			result = 2;
		}
		else if (Input.GetKey(KeyCode.Alpha4))
		{
			result = 3;
		}
		else if (Input.GetKey(KeyCode.Alpha5))
		{
			result = 4;
		}
		else if (Input.GetKey(KeyCode.Alpha6))
		{
			result = 5;
		}
		else if (Input.GetKey(KeyCode.Alpha7))
		{
			result = 6;
		}
		else if (Input.GetKey(KeyCode.Alpha8))
		{
			result = 7;
		}
		else if (Input.GetKey(KeyCode.Alpha9))
		{
			result = 8;
		}
		return result;
	}

	private static EAction GetAction()
	{
		string inputString = Input.inputString;
		if (Input.GetKeyDown(KeyCode.Escape))
		{
			return EAction.Cancel;
		}
		if (Input.GetKeyDown(keys.wait.key) || Input.GetKey(KeyCode.Keypad5))
		{
			return EAction.Wait;
		}
		if (Input.GetKeyDown(keys.emptyHand.key))
		{
			return EAction.EmptyHand;
		}
		if (Input.GetKeyDown(keys.autoCombat.key))
		{
			return EAction.AutoCombat;
		}
		if (Input.GetKeyDown(keys.examine.key))
		{
			return EAction.Examine;
		}
		if (Input.GetKeyDown(keys.getAll.key))
		{
			return EAction.GetAll;
		}
		if (Input.GetKeyDown(keys.dump.key))
		{
			return EAction.Dump;
		}
		if (Input.GetKeyDown(keys.mute.key))
		{
			return EAction.Mute;
		}
		if (Input.GetKeyDown(keys.meditate.key))
		{
			return EAction.Meditate;
		}
		if (Input.GetKeyDown(keys.search.key))
		{
			return EAction.Search;
		}
		if (keyFire.Update())
		{
			return keyFire.Action;
		}
		if (keyWait.Update())
		{
			return keyWait.Action;
		}
		if (!isShiftDown)
		{
			if (Input.GetKeyDown(keys.chara.key))
			{
				return EAction.MenuChara;
			}
			if (Input.GetKeyDown(keys.journal.key))
			{
				return EAction.MenuJournal;
			}
			if (Input.GetKeyDown(keys.inventory.key))
			{
				return EAction.MenuInventory;
			}
			if (Input.GetKeyDown(keys.ability.key))
			{
				return EAction.MenuAbility;
			}
			if (Input.GetKeyDown(keys.log.key))
			{
				return EAction.Log;
			}
			if (Input.GetKeyDown(keys.report.key))
			{
				return EAction.Report;
			}
			if (Input.GetKeyDown(keys.quickSave.key))
			{
				return EAction.QuickSave;
			}
			if (Input.GetKeyDown(keys.quickLoad.key))
			{
				return EAction.QuickLoad;
			}
		}
		if (!(inputString == "?"))
		{
			if (inputString == "g")
			{
				return EAction.ShowGrid;
			}
			return EAction.None;
		}
		return EAction.Help;
	}

	public static void RestoreDefaultKeys()
	{
	}

	public static void Select(GameObject go)
	{
		eventSystem.SetSelectedGameObject(null);
		eventSystem.SetSelectedGameObject(go);
	}
}

+ERROR

File Created
cs
public class ERROR
{
	public static string msg;
}

+ElinEncoder

File Created
cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class ElinEncoder
{
	private const string key = "123456789012345678901234";

	private const string iv = "12345678";

	public static string AesEncrypt(string srcStr)
	{
		TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider();
		byte[] bytes = Encoding.UTF8.GetBytes(srcStr);
		MemoryStream memoryStream = new MemoryStream();
		CryptoStream cryptoStream = new CryptoStream(memoryStream, tripleDESCryptoServiceProvider.CreateEncryptor(Encoding.UTF8.GetBytes("123456789012345678901234"), Encoding.UTF8.GetBytes("12345678")), CryptoStreamMode.Write);
		cryptoStream.Write(bytes, 0, bytes.Length);
		cryptoStream.Close();
		byte[] inArray = memoryStream.ToArray();
		memoryStream.Close();
		return Convert.ToBase64String(inArray);
	}

	public static string AesDecrypt(string encStr)
	{
		TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider();
		byte[] array = Convert.FromBase64String(encStr);
		MemoryStream memoryStream = new MemoryStream();
		CryptoStream cryptoStream = new CryptoStream(memoryStream, tripleDESCryptoServiceProvider.CreateDecryptor(Encoding.UTF8.GetBytes("123456789012345678901234"), Encoding.UTF8.GetBytes("12345678")), CryptoStreamMode.Write);
		cryptoStream.Write(array, 0, array.Length);
		cryptoStream.Close();
		byte[] bytes = memoryStream.ToArray();
		memoryStream.Close();
		return Encoding.UTF8.GetString(bytes);
	}

	public static string GetCode(int idBacker, int index)
	{
		return AesEncrypt(idBacker.ToString("0000") + index).TrimEnd('=');
	}

	public static string GetID(string code)
	{
		return AesDecrypt(code + "=");
	}

	public static bool IsValid(string code)
	{
		try
		{
			int result;
			return int.TryParse(AesDecrypt(code + "="), out result);
		}
		catch
		{
		}
		return false;
	}
}

+ExcelBookImportSetting

File Created
cs
using System;
using System.Collections.Generic;

[Serializable]
public class ExcelBookImportSetting
{
	public string name;

	public string exportPath;

	public string _prefix;

	public List<ExcelSheetImportSetting> sheets = new List<ExcelSheetImportSetting>();

	public string prefix
	{
		get
		{
			if (!string.IsNullOrEmpty(_prefix))
			{
				return _prefix;
			}
			return "Source";
		}
	}

	public string path => exportPath.IsEmpty(CustomAssetManager.Instance.exportPath) + "Export/";

	public ExcelSheetImportSetting GetSheet(string id)
	{
		foreach (ExcelSheetImportSetting sheet in sheets)
		{
			if (sheet.name == id)
			{
				return sheet;
			}
		}
		return null;
	}

	public ExcelSheetImportSetting GetOrCreateSheet(string id)
	{
		ExcelSheetImportSetting sheet = GetSheet(id);
		if (sheet != null)
		{
			return sheet;
		}
		sheet = new ExcelSheetImportSetting
		{
			name = id
		};
		sheets.Add(sheet);
		return sheet;
	}

	public override string ToString()
	{
		return name;
	}
}

+ExcelData

File Created
cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using UnityEngine;

public class ExcelData
{
	public class Sheet
	{
		public Dictionary<string, Dictionary<string, string>> map;

		public List<Dictionary<string, string>> list;
	}

	public int startIndex = 5;

	public XSSFWorkbook book;

	public IRow rowIndex;

	public Dictionary<string, Sheet> sheets = new Dictionary<string, Sheet>();

	public string path;

	public int maxEmptyRows;

	public DateTime lastModified;

	public ExcelData()
	{
	}

	public ExcelData(string _path, int _index)
	{
		path = _path;
		startIndex = _index;
		BuildMap();
	}

	public ExcelData(string _path)
	{
		path = _path;
	}

	public void LoadBook()
	{
		if (book != null)
		{
			if (lastModified.Equals(File.GetLastWriteTime(path)))
			{
				return;
			}
			Debug.Log("Excel file modified:" + path);
			sheets.Clear();
		}
		lastModified = File.GetLastWriteTime(path);
		TextAsset textAsset = Resources.Load(path) as TextAsset;
		if ((bool)textAsset)
		{
			Stream @is = new MemoryStream(textAsset.bytes);
			book = new XSSFWorkbook(@is);
			return;
		}
		using FileStream is2 = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
		book = new XSSFWorkbook((Stream)is2);
	}

	public bool IsModified()
	{
		return !lastModified.Equals(File.GetLastWriteTime(path));
	}

	public virtual void BuildMap(string sheetName = "_default")
	{
		BuildList(sheetName);
		Sheet sheet = sheets[sheetName];
		if (sheet.map != null)
		{
			return;
		}
		sheet.map = new Dictionary<string, Dictionary<string, string>>();
		foreach (Dictionary<string, string> item in sheet.list)
		{
			sheet.map[item["id"]] = item;
		}
	}

	public List<Dictionary<string, string>> BuildList(string sheetName = "_default")
	{
		LoadBook();
		if (sheetName.IsEmpty())
		{
			sheetName = "_default";
		}
		Sheet sheet = sheets.TryGetValue(sheetName);
		if (sheet == null)
		{
			sheet = new Sheet();
			sheets[sheetName] = sheet;
		}
		if (sheet.list != null)
		{
			return sheet.list;
		}
		sheet.list = new List<Dictionary<string, string>>();
		ISheet sheet2 = (string.IsNullOrEmpty(sheetName) ? book.GetSheetAt(0) : (book.GetSheet(sheetName) ?? book.GetSheetAt(0)));
		rowIndex = sheet2.GetRow(0);
		int num = 0;
		for (int i = startIndex - 1; i <= sheet2.LastRowNum; i++)
		{
			IRow row = sheet2.GetRow(i);
			if (row == null)
			{
				if (i >= 5)
				{
					num++;
					if (num > maxEmptyRows)
					{
						break;
					}
				}
				continue;
			}
			num = 0;
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			for (int j = 0; j < rowIndex.LastCellNum; j++)
			{
				ICell cell = row.GetCell(j);
				string text = rowIndex.GetCell(j).ToString();
				if (text.IsEmpty())
				{
					break;
				}
				try
				{
					dictionary.Add(text, (cell == null) ? "" : cell.ToString());
				}
				catch
				{
				}
			}
			sheet.list.Add(dictionary);
		}
		return sheet.list;
	}

	public void Override(Dictionary<string, SourceData> sources, bool canAddData = true)
	{
		using FileStream @is = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
		book = new XSSFWorkbook((Stream)@is);
		for (int i = 0; i < book.NumberOfSheets; i++)
		{
			ISheet sheetAt = book.GetSheetAt(i);
			ExcelParser.rowDefault = sheetAt.GetRow(2);
			SourceData value = null;
			if (!sources.TryGetValue(sheetAt.SheetName, out value))
			{
				Debug.Log(sheetAt.SheetName + " does not exist in sourceMap.");
				continue;
			}
			Type type = value.GetType();
			IList list = type.GetField("rows").GetValue(value) as IList;
			IDictionary dictionary = type.GetField("map").GetValue(value) as IDictionary;
			Type type2 = list.GetType().GetGenericArguments()[0];
			List<FieldInfo> list2 = new List<FieldInfo>();
			List<ExcelIndex> index = ExcelIndex.GetIndex(sheetAt);
			for (int j = 0; j < index.Count; j++)
			{
				list2.Add(type2.GetField(index[j].name));
			}
			for (int k = startIndex - 1; k <= sheetAt.LastRowNum; k++)
			{
				string stringCellValue = (ExcelParser.row = sheetAt.GetRow(k)).GetCell(0).StringCellValue;
				bool flag = true;
				object obj;
				if (dictionary.Contains(stringCellValue))
				{
					obj = dictionary[stringCellValue];
					flag = false;
				}
				else
				{
					if (!canAddData)
					{
						continue;
					}
					obj = Activator.CreateInstance(type2);
				}
				for (int l = 0; l < index.Count; l++)
				{
					string type3 = index[l].type;
					if (type3 == "str" || type3 == "string")
					{
						list2[l].SetValue(obj, ExcelParser.GetString(l));
					}
				}
				if (flag)
				{
					list.Add(obj);
				}
			}
		}
	}

	public string GetText(string id, string topic = "text")
	{
		BuildMap();
		return sheets["_default"].map.TryGetValue(topic)?[id];
	}
}

+ExcelDataList

File Created
cs
using System.Collections.Generic;
using System.IO;

public class ExcelDataList
{
	public List<ExcelData> items = new List<ExcelData>(0);

	public Dictionary<string, Dictionary<string, string>> all = new Dictionary<string, Dictionary<string, string>>();

	public List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();

	protected bool initialized;

	public virtual int StartIndex => 5;

	public void Reload()
	{
		all.Clear();
		list.Clear();
		initialized = false;
	}

	public virtual void Initialize()
	{
		if (initialized)
		{
			return;
		}
		foreach (ExcelData item in items)
		{
			item.startIndex = StartIndex;
			List<Dictionary<string, string>> obj = item.BuildList();
			string directoryName = new FileInfo(item.path).DirectoryName;
			foreach (Dictionary<string, string> item2 in obj)
			{
				item2["path"] = directoryName;
				all[item2["id"]] = item2;
				list.Add(item2);
			}
		}
		OnInitialize();
		initialized = true;
	}

	public virtual void OnInitialize()
	{
	}

	public Dictionary<string, string> GetRow(string id)
	{
		if (!initialized)
		{
			Initialize();
		}
		return all.TryGetValue(id) ?? list[0];
	}
}

+ExcelDataListExtension

File Created
cs
using System.Collections.Generic;

public static class ExcelDataListExtension
{
	public static int IndexOf(this List<Dictionary<string, string>> list, string id)
	{
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i]["id"] == id)
			{
				return i;
			}
		}
		return -1;
	}

	public static string GetNextID(this List<Dictionary<string, string>> list, string currentId, int a)
	{
		int num = list.IndexOf(currentId) + a;
		if (num >= list.Count)
		{
			num = 0;
		}
		if (num < 0)
		{
			num = list.Count - 1;
		}
		return list[num]["id"];
	}
}

+ExcelIndex

File Created
cs
using System.Collections.Generic;
using NPOI.SS.UserModel;

public class ExcelIndex
{
	public string type;

	public string name;

	public string enumName = "";

	public bool serializable = true;

	public static List<ExcelIndex> GetIndex(ISheet sheet)
	{
		List<ExcelIndex> list = new List<ExcelIndex>();
		IRow row = sheet.GetRow(0);
		IRow row2 = sheet.GetRow(1);
		for (int i = 0; i < row.LastCellNum; i++)
		{
			ICell cell = row2.GetCell(i);
			ExcelIndex item = new ExcelIndex(row.GetCell(i), cell);
			list.Add(item);
		}
		return list;
	}

	public ExcelIndex(ICell titleCell, ICell dataCell)
	{
		name = titleCell.StringCellValue;
		if (dataCell != null)
		{
			type = dataCell.StringCellValue;
		}
		if (type == "Sprite[]")
		{
			serializable = false;
		}
	}

	public string GetTypeName()
	{
		if (type == null)
		{
			return null;
		}
		if (type.StartsWith("#"))
		{
			enumName = type.Replace("#", "");
			return enumName;
		}
		if (type == "str")
		{
			return "string";
		}
		if (type == "element_id")
		{
			return "int";
		}
		if (type == "elements")
		{
			return "int[]";
		}
		return type;
	}
}

+ExcelParser

File Created
cs
using System;
using NPOI.SS.UserModel;

public class ExcelParser
{
	public static IRow row;

	public static IRow rowDefault;

	public static bool IsNull(ICell cell)
	{
		if (cell != null && cell.CellType != CellType.Blank)
		{
			return cell.CellType == CellType.Unknown;
		}
		return true;
	}

	public static int GetInt(int id)
	{
		if (int.TryParse(GetStr(id), out var result))
		{
			return result;
		}
		return 0;
	}

	public static int GetInt(int col, IRow _row)
	{
		row = _row;
		return GetInt(col);
	}

	public static bool GetBool(int id)
	{
		string str = GetStr(id);
		return str switch
		{
			"0" => false, 
			"1" => true, 
			null => false, 
			_ => bool.Parse(str), 
		};
	}

	public static bool GetBool(int col, IRow _row)
	{
		row = _row;
		return GetBool(col);
	}

	public static double GetDouble(int id)
	{
		string str = GetStr(id);
		if (str != null)
		{
			return double.Parse(str);
		}
		return 0.0;
	}

	public static float GetFloat(int id)
	{
		string str = GetStr(id);
		if (str != null)
		{
			return float.Parse(str);
		}
		return 0f;
	}

	public static float[] GetFloatArray(int id)
	{
		string str = GetStr(id);
		if (str != null)
		{
			return Array.ConvertAll(str.Split(','), float.Parse);
		}
		return new float[0];
	}

	public static int[] GetIntArray(int id)
	{
		string str = GetStr(id);
		if (str != null)
		{
			return Array.ConvertAll(str.Split(','), int.Parse);
		}
		return new int[0];
	}

	public static string[] GetStringArray(int id)
	{
		string str = GetStr(id);
		if (str != null)
		{
			return str.Split(',');
		}
		return new string[0];
	}

	public static string GetString(int id)
	{
		return GetStr(id) ?? "";
	}

	public static string GetString(int col, IRow _row)
	{
		row = _row;
		return GetStr(col);
	}

	public static string GetStr(int id, bool useDefault = false)
	{
		IRow row = (useDefault ? rowDefault : ExcelParser.row);
		if (row == null)
		{
			if (!useDefault)
			{
				return GetStr(id, useDefault: true);
			}
			return null;
		}
		ICell cell = row.GetCell(id);
		if (IsNull(cell))
		{
			if (!useDefault)
			{
				return GetStr(id, useDefault: true);
			}
			return null;
		}
		cell.SetCellType(CellType.String);
		if (cell.StringCellValue == "")
		{
			if (!useDefault)
			{
				return GetStr(id, useDefault: true);
			}
			return null;
		}
		return cell.StringCellValue;
	}
}

+ExcelSheetImportSetting

File Created
cs
using System;

[Serializable]
public class ExcelSheetImportSetting
{
	public enum ClassTemplate
	{
		Default,
		ThingV
	}

	public string name;

	public string _baseClass;

	public string _rowClass;

	public string _templateFile;

	public bool intID;

	public SourceData.AutoID autoID;

	public ClassTemplate template;

	public string idTemplate => "ClassTemplate" + ((template == ClassTemplate.Default) ? "" : ("_" + template));

	public string baseClass
	{
		get
		{
			if (!string.IsNullOrEmpty(_baseClass))
			{
				return _baseClass;
			}
			if (!intID)
			{
				return "SourceDataString";
			}
			return "SourceDataInt";
		}
	}

	public string rowClass
	{
		get
		{
			if (!string.IsNullOrEmpty(_rowClass))
			{
				return _rowClass;
			}
			return "BaseRow";
		}
	}

	public override string ToString()
	{
		return name;
	}
}

+FastString

File Created
cs
using System;
using System.Collections.Generic;

public class FastString
{
	private string m_stringGenerated = "";

	private bool m_isStringGenerated;

	private char[] m_buffer;

	private int m_bufferPos;

	private int m_charsCapacity;

	private List<char> m_replacement;

	private object m_valueControl;

	private int m_valueControlInt = int.MinValue;

	public FastString(int initialCapacity = 32)
	{
		m_buffer = new char[m_charsCapacity = initialCapacity];
	}

	public bool IsEmpty()
	{
		if (!m_isStringGenerated)
		{
			return m_bufferPos == 0;
		}
		return m_stringGenerated == null;
	}

	public override string ToString()
	{
		if (!m_isStringGenerated)
		{
			m_stringGenerated = new string(m_buffer, 0, m_bufferPos);
			m_isStringGenerated = true;
		}
		return m_stringGenerated;
	}

	public bool IsModified(int newControlValue)
	{
		bool num = newControlValue != m_valueControlInt;
		if (num)
		{
			m_valueControlInt = newControlValue;
		}
		return num;
	}

	public bool IsModified(object newControlValue)
	{
		bool num = !newControlValue.Equals(m_valueControl);
		if (num)
		{
			m_valueControl = newControlValue;
		}
		return num;
	}

	public void Set(string str)
	{
		Clear();
		Append(str);
		m_stringGenerated = str;
		m_isStringGenerated = true;
	}

	public void Set(object str)
	{
		Set(str.ToString());
	}

	public void Set<T1, T2>(T1 str1, T2 str2)
	{
		Clear();
		Append(str1);
		Append(str2);
	}

	public void Set<T1, T2, T3>(T1 str1, T2 str2, T3 str3)
	{
		Clear();
		Append(str1);
		Append(str2);
		Append(str3);
	}

	public void Set<T1, T2, T3, T4>(T1 str1, T2 str2, T3 str3, T4 str4)
	{
		Clear();
		Append(str1);
		Append(str2);
		Append(str3);
		Append(str4);
	}

	public void Set(params object[] str)
	{
		Clear();
		for (int i = 0; i < str.Length; i++)
		{
			Append(str[i]);
		}
	}

	public FastString Clear()
	{
		m_bufferPos = 0;
		m_isStringGenerated = false;
		return this;
	}

	public FastString Append(string value)
	{
		ReallocateIFN(value.Length);
		int length = value.Length;
		for (int i = 0; i < length; i++)
		{
			m_buffer[m_bufferPos + i] = value[i];
		}
		m_bufferPos += length;
		m_isStringGenerated = false;
		return this;
	}

	public FastString Append(object value)
	{
		Append(value.ToString());
		return this;
	}

	public FastString Append(int value)
	{
		ReallocateIFN(16);
		if (value < 0)
		{
			value = -value;
			m_buffer[m_bufferPos++] = '-';
		}
		int num = 0;
		do
		{
			m_buffer[m_bufferPos++] = (char)(48 + value % 10);
			value /= 10;
			num++;
		}
		while (value != 0);
		for (int num2 = num / 2 - 1; num2 >= 0; num2--)
		{
			char c = m_buffer[m_bufferPos - num2 - 1];
			m_buffer[m_bufferPos - num2 - 1] = m_buffer[m_bufferPos - num + num2];
			m_buffer[m_bufferPos - num + num2] = c;
		}
		m_isStringGenerated = false;
		return this;
	}

	public FastString Append(float valueF)
	{
		double num = valueF;
		m_isStringGenerated = false;
		ReallocateIFN(32);
		if (num == 0.0)
		{
			m_buffer[m_bufferPos++] = '0';
			return this;
		}
		if (num < 0.0)
		{
			num = 0.0 - num;
			m_buffer[m_bufferPos++] = '-';
		}
		int num2 = 0;
		while (num < 1000000.0)
		{
			num *= 10.0;
			num2++;
		}
		long num3 = (long)Math.Round(num);
		int num4 = 0;
		bool flag = true;
		while (num3 != 0L || num2 >= 0)
		{
			if (num3 % 10 != 0L || num2 <= 0)
			{
				flag = false;
			}
			if (!flag)
			{
				m_buffer[m_bufferPos + num4++] = (char)(48 + num3 % 10);
			}
			if (--num2 == 0 && !flag)
			{
				m_buffer[m_bufferPos + num4++] = '.';
			}
			num3 /= 10;
		}
		m_bufferPos += num4;
		for (int num5 = num4 / 2 - 1; num5 >= 0; num5--)
		{
			char c = m_buffer[m_bufferPos - num5 - 1];
			m_buffer[m_bufferPos - num5 - 1] = m_buffer[m_bufferPos - num4 + num5];
			m_buffer[m_bufferPos - num4 + num5] = c;
		}
		return this;
	}

	public FastString Replace(string oldStr, string newStr)
	{
		if (m_bufferPos == 0)
		{
			return this;
		}
		if (m_replacement == null)
		{
			m_replacement = new List<char>();
		}
		for (int i = 0; i < m_bufferPos; i++)
		{
			bool flag = false;
			if (m_buffer[i] == oldStr[0])
			{
				int j;
				for (j = 1; j < oldStr.Length && m_buffer[i + j] == oldStr[j]; j++)
				{
				}
				flag = j >= oldStr.Length;
			}
			if (flag)
			{
				i += oldStr.Length - 1;
				if (newStr != null)
				{
					for (int k = 0; k < newStr.Length; k++)
					{
						m_replacement.Add(newStr[k]);
					}
				}
			}
			else
			{
				m_replacement.Add(m_buffer[i]);
			}
		}
		ReallocateIFN(m_replacement.Count - m_bufferPos);
		for (int l = 0; l < m_replacement.Count; l++)
		{
			m_buffer[l] = m_replacement[l];
		}
		m_bufferPos = m_replacement.Count;
		m_replacement.Clear();
		m_isStringGenerated = false;
		return this;
	}

	private void ReallocateIFN(int nbCharsToAdd)
	{
		if (m_bufferPos + nbCharsToAdd > m_charsCapacity)
		{
			m_charsCapacity = Math.Max(m_charsCapacity + nbCharsToAdd, m_charsCapacity * 2);
			char[] array = new char[m_charsCapacity];
			m_buffer.CopyTo(array, 0);
			m_buffer = array;
		}
	}
}

+FileDragAndDrop

File Created
cs
using System;
using System.Collections.Generic;
using B83.Win32;
using UnityEngine;

public class FileDragAndDrop : MonoBehaviour
{
	public static Action<List<string>> onDrop;

	private void OnEnable()
	{
		UnityDragAndDropHook.InstallHook();
		UnityDragAndDropHook.OnDroppedFiles += OnFiles;
	}

	private void OnDisable()
	{
		UnityDragAndDropHook.UninstallHook();
	}

	private void OnFiles(List<string> aFiles, POINT aPos)
	{
		if (onDrop != null)
		{
			onDrop(aFiles);
		}
	}
}

+Gender

File Created
cs
public class Gender
{
	public const int unknown = 0;

	public const int female = 1;

	public const int male = 2;

	public static string Name(int g)
	{
		return (g switch
		{
			1 => "female", 
			2 => "male", 
			_ => "gay", 
		}).lang();
	}

	public static int GetRandom()
	{
		if (Rand.rnd(30) == 0)
		{
			return 0;
		}
		return Rand.Range(1, 3);
	}
}

+Hide

File Created
cs
using UnityEngine;

public class Hide : PropertyAttribute
{
}

+IChangeLanguage

File Created
cs
public interface IChangeLanguage
{
	void OnChangeLanguage();
}

+IChangeResolution

File Created
cs
public interface IChangeResolution
{
	void OnChangeResolution();
}

+IO

File Created
cs
using System;
using System.IO;
using LZ4;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using UnityEngine;

public class IO
{
	public enum Compression
	{
		LZ4,
		None
	}

	public static string log;

	public static JsonSerializerSettings jsReadGeneral = new JsonSerializerSettings
	{
		NullValueHandling = NullValueHandling.Ignore,
		DefaultValueHandling = DefaultValueHandling.Ignore,
		PreserveReferencesHandling = PreserveReferencesHandling.Objects,
		TypeNameHandling = TypeNameHandling.Auto,
		Error = OnError
	};

	public static JsonSerializerSettings jsWriteGeneral = new JsonSerializerSettings
	{
		NullValueHandling = NullValueHandling.Ignore,
		DefaultValueHandling = DefaultValueHandling.Ignore,
		PreserveReferencesHandling = PreserveReferencesHandling.Objects,
		TypeNameHandling = TypeNameHandling.Auto,
		ContractResolver = ShouldSerializeContractResolver.Instance,
		Error = OnError
	};

	public static JsonSerializerSettings jsWriteConfig = new JsonSerializerSettings
	{
		NullValueHandling = NullValueHandling.Ignore,
		DefaultValueHandling = DefaultValueHandling.Populate,
		PreserveReferencesHandling = PreserveReferencesHandling.Objects,
		TypeNameHandling = TypeNameHandling.Auto,
		ContractResolver = ShouldSerializeContractResolver.Instance,
		Error = OnError
	};

	public static Formatting formatting = Formatting.Indented;

	public static TextureImportSetting.Data importSetting = new TextureImportSetting.Data();

	public static JsonSerializerSettings dpSetting = new JsonSerializerSettings
	{
		NullValueHandling = NullValueHandling.Ignore,
		DefaultValueHandling = DefaultValueHandling.Include,
		PreserveReferencesHandling = PreserveReferencesHandling.Objects,
		TypeNameHandling = TypeNameHandling.Auto,
		Error = OnError
	};

	public static Formatting dpFormat = Formatting.Indented;

	public static string TempPath => Application.persistentDataPath + "/Temp";

	public static void OnError(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
	{
	}

	public static void PrintLog()
	{
		if (!log.IsEmpty())
		{
			Debug.LogWarning(log);
			log = null;
		}
	}

	public static string GetJSON(object obj)
	{
		return JsonConvert.SerializeObject(obj, formatting, jsWriteGeneral);
	}

	public static T LoadJSON<T>(string json)
	{
		return JsonConvert.DeserializeObject<T>(json, jsReadGeneral);
	}

	public static void SaveFile(string path, object obj, bool compress = false, JsonSerializerSettings setting = null)
	{
		string text = JsonConvert.SerializeObject(obj, formatting, setting ?? jsWriteGeneral);
		CreateDirectory(Path.GetDirectoryName(path));
		Debug.Log("#io SaveFile;" + path);
		if (compress)
		{
			Compress(path, text);
		}
		else
		{
			File.WriteAllText(path, text);
		}
	}

	public static void SaveText(string path, string text)
	{
		CreateDirectory(Path.GetDirectoryName(path));
		Debug.Log("#io SaveFile;" + path);
		File.WriteAllText(path, text);
	}

	public static T LoadFile<T>(string path, bool compress = false, JsonSerializerSettings setting = null)
	{
		if (!File.Exists(path))
		{
			Debug.Log("File does not exist:" + path);
			return default(T);
		}
		string value = (IsCompressed(path) ? Decompress(path) : File.ReadAllText(path));
		Debug.Log("#io LoadFile;" + path);
		return JsonConvert.DeserializeObject<T>(value, setting ?? jsReadGeneral);
	}

	public static T LoadStreamJson<T>(MemoryStream stream, JsonSerializerSettings setting = null)
	{
		stream.Position = 0L;
		string value = "";
		using (StreamReader streamReader = new StreamReader(stream))
		{
			value = streamReader.ReadToEnd();
		}
		return JsonConvert.DeserializeObject<T>(value, setting ?? jsReadGeneral);
	}

	public static void WriteLZ4(string _path, byte[] _bytes)
	{
		for (int i = 0; i < 5; i++)
		{
			string path = _path + ((i == 0) ? "" : (".b" + i));
			try
			{
				File.WriteAllBytes(path, _bytes);
				break;
			}
			catch (Exception message)
			{
				Debug.Log(message);
			}
		}
	}

	public static byte[] ReadLZ4(string _path, int size, Compression compression)
	{
		for (int i = 0; i < 5; i++)
		{
			string text = _path + ((i == 0) ? "" : (".b" + i));
			if (!File.Exists(text))
			{
				Debug.Log("Couldn't find:" + text);
				continue;
			}
			byte[] array = File.ReadAllBytes(text);
			if (array.Length == size)
			{
				return array;
			}
			if (compression == Compression.LZ4)
			{
				try
				{
					return ReadLZ4(array);
				}
				catch (Exception message)
				{
					Debug.Log(message);
				}
			}
		}
		return null;
	}

	public static byte[] ReadLZ4(byte[] bytes)
	{
		try
		{
			return LZ4Codec.Unwrap(bytes);
		}
		catch
		{
			Debug.Log("Exception: Failed to unwrap:");
			return bytes;
		}
	}

	public static bool IsCompressed(string path)
	{
		byte[] array;
		using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
		{
			binaryReader.BaseStream.Seek(0L, SeekOrigin.Begin);
			array = binaryReader.ReadBytes(4);
		}
		if (array.Length > 3 && array[0] == 123 && array[1] == 13 && array[2] == 10 && array[3] == 32)
		{
			return false;
		}
		return true;
	}

	public static void Compress(string path, string text)
	{
		File.WriteAllText(path, text);
	}

	public static string Decompress(string path)
	{
		try
		{
			using FileStream innerStream = new FileStream(path, FileMode.Open);
			using LZ4Stream stream = new LZ4Stream(innerStream, LZ4StreamMode.Decompress);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
		catch (Exception message)
		{
			Debug.Log(message);
		}
		Debug.Log("Cannot decompress:" + IsCompressed(path) + "/" + path);
		string text = File.ReadAllText(path);
		Debug.Log(text);
		return text.IsEmpty("");
	}

	public static void CopyDir(string sourceDirectory, string targetDirectory, Func<string, bool> funcExclude = null)
	{
		DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectory);
		DirectoryInfo target = new DirectoryInfo(targetDirectory);
		if (!directoryInfo.Exists)
		{
			Debug.Log("Source dir doesn't exist:" + directoryInfo.FullName);
		}
		else
		{
			_CopyDir(directoryInfo, target, funcExclude);
		}
	}

	public static void _CopyDir(DirectoryInfo source, DirectoryInfo target, Func<string, bool> funcExclude = null)
	{
		if (funcExclude == null || !funcExclude(source.Name))
		{
			Directory.CreateDirectory(target.FullName);
			FileInfo[] files = source.GetFiles();
			foreach (FileInfo fileInfo in files)
			{
				fileInfo.CopyTo(Path.Combine(target.FullName, fileInfo.Name), overwrite: true);
			}
			DirectoryInfo[] directories = source.GetDirectories();
			foreach (DirectoryInfo directoryInfo in directories)
			{
				DirectoryInfo target2 = target.CreateSubdirectory(directoryInfo.Name);
				_CopyDir(directoryInfo, target2, funcExclude);
			}
		}
	}

	public static void Copy(string fromPath, string toPath)
	{
		if (!File.Exists(fromPath))
		{
			Debug.Log("File does not exist:" + fromPath);
			return;
		}
		FileInfo fileInfo = new FileInfo(fromPath);
		DirectoryInfo directoryInfo = new DirectoryInfo(toPath);
		if (!Directory.Exists(directoryInfo.FullName))
		{
			CreateDirectory(directoryInfo.FullName);
		}
		File.Copy(fileInfo.FullName, directoryInfo.FullName + "/" + fileInfo.Name, overwrite: true);
	}

	public static void CopyAs(string fromPath, string toPath)
	{
		if (!File.Exists(fromPath))
		{
			Debug.LogError("File does not exist:" + fromPath);
		}
		else
		{
			File.Copy(fromPath, toPath, overwrite: true);
		}
	}

	public static void CopyAll(string fromPath, string toPath, bool overwrite = true)
	{
		CreateDirectory(toPath);
		string[] directories = Directory.GetDirectories(fromPath, "*", SearchOption.AllDirectories);
		for (int i = 0; i < directories.Length; i++)
		{
			Directory.CreateDirectory(directories[i].Replace(fromPath, toPath));
		}
		directories = Directory.GetFiles(fromPath, "*.*", SearchOption.AllDirectories);
		foreach (string text in directories)
		{
			string text2 = text.Replace(fromPath, toPath);
			if (overwrite || !File.Exists(text2))
			{
				File.Copy(text, text2, overwrite: true);
			}
		}
	}

	public static void DeleteFile(string path)
	{
		if (File.Exists(path))
		{
			File.Delete(path);
		}
	}

	public static void DeleteFiles(string path)
	{
		if (Directory.Exists(path))
		{
			FileInfo[] files = new DirectoryInfo(path).GetFiles();
			for (int i = 0; i < files.Length; i++)
			{
				files[i].Delete();
			}
		}
	}

	public static void CreateDirectory(string path)
	{
		if (!Directory.Exists(path))
		{
			Directory.CreateDirectory(path);
		}
	}

	public static void DeleteDirectory(string path)
	{
		if (Directory.Exists(path))
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(path);
			if (directoryInfo.Exists)
			{
				directoryInfo.Delete(recursive: true);
			}
		}
	}

	public static T Duplicate<T>(T t)
	{
		return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(t, formatting, jsWriteGeneral), jsReadGeneral);
	}

	public static void CreateTempDirectory(string path = null)
	{
		CreateDirectory(path ?? TempPath);
	}

	public static void DeleteTempDirectory(string path = null)
	{
		DeleteDirectory(path ?? TempPath);
	}

	public static T LoadObject<T>(FileInfo file, object option = null) where T : UnityEngine.Object
	{
		return LoadObject<T>(file.FullName, option);
	}

	public static T LoadObject<T>(string _path, object option = null) where T : UnityEngine.Object
	{
		Type typeFromHandle = typeof(T);
		if (typeFromHandle == typeof(Sprite))
		{
			SpriteLoadOption spriteLoadOption = option as SpriteLoadOption;
			Texture2D texture2D = LoadPNG(_path);
			if (!texture2D)
			{
				return null;
			}
			return Sprite.Create(texture2D, new Rect(0f, 0f, texture2D.width, texture2D.height), spriteLoadOption?.pivot ?? new Vector2(0.5f, 0f), 100f) as T;
		}
		if (typeFromHandle == typeof(Texture2D))
		{
			return LoadPNG(_path) as T;
		}
		if (typeof(ExcelData).IsAssignableFrom(typeFromHandle))
		{
			T val = Activator.CreateInstance<T>();
			(val as ExcelData).path = _path;
			return val;
		}
		if (typeFromHandle == typeof(TextData))
		{
			return new TextData
			{
				lines = File.ReadAllLines(_path)
			} as T;
		}
		return null;
	}

	public static void SavePNG(Texture2D tex, string _path)
	{
		byte[] bytes = tex.EncodeToPNG();
		File.WriteAllBytes(_path, bytes);
	}

	public static Texture2D LoadPNG(string _path, FilterMode filter = FilterMode.Point)
	{
		if (!File.Exists(_path))
		{
			return null;
		}
		byte[] array = ReadPngFile(_path);
		int num = 16;
		int num2 = 0;
		for (int i = 0; i < 4; i++)
		{
			if (num + 1 < array.Length)
			{
				num2 = num2 * 256 + array[num++];
			}
		}
		int num3 = 0;
		for (int j = 0; j < 4; j++)
		{
			if (num + 1 < array.Length)
			{
				num3 = num3 * 256 + array[num++];
			}
		}
		TextureImportSetting.Data data = (TextureImportSetting.Instance ? TextureImportSetting.Instance.data : importSetting);
		Texture2D texture2D = new Texture2D(num2, num3, data.format, data.mipmap, data.linear);
		texture2D.LoadImage(array);
		texture2D.wrapMode = data.wrapMode;
		texture2D.filterMode = filter;
		texture2D.anisoLevel = data.anisoLevel;
		texture2D.mipMapBias = data.mipmapBias;
		return texture2D;
	}

	public static byte[] ReadPngFile(string _path)
	{
		FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
		BinaryReader binaryReader = new BinaryReader(fileStream);
		byte[] result = binaryReader.ReadBytes((int)binaryReader.BaseStream.Length);
		binaryReader.Close();
		fileStream.Close();
		return result;
	}

	public static T DeepCopy<T>(T target)
	{
		return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(target, dpFormat, dpSetting), dpSetting);
	}

	public static string[] LoadTextArray(string _path)
	{
		if (!File.Exists(_path))
		{
			_path += ".txt";
			if (!File.Exists(_path))
			{
				Debug.Log(_path);
				return new string[0];
			}
		}
		return File.ReadAllLines(_path);
	}

	public static string LoadText(string _path)
	{
		string[] array = LoadTextArray(_path);
		string text = "";
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			text = text + text2 + Environment.NewLine;
		}
		return text;
	}
}

+IPoolObject

File Created
cs
public interface IPoolObject
{
	void Despawn();
}

+ImageExample

File Created
cs
using System.Collections.Generic;
using System.IO;
using B83.Win32;
using UnityEngine;

public class ImageExample : MonoBehaviour
{
	private class DropInfo
	{
		public string file;

		public Vector2 pos;
	}

	private Texture2D[] textures = new Texture2D[6];

	private DropInfo dropInfo;

	private void OnEnable()
	{
		UnityDragAndDropHook.InstallHook();
		UnityDragAndDropHook.OnDroppedFiles += OnFiles;
	}

	private void OnDisable()
	{
		UnityDragAndDropHook.UninstallHook();
	}

	private void OnFiles(List<string> aFiles, POINT aPos)
	{
		string text = "";
		foreach (string aFile in aFiles)
		{
			switch (new FileInfo(aFile).Extension.ToLower())
			{
			case ".png":
			case ".jpg":
			case ".jpeg":
				text = aFile;
				goto end_IL_0053;
			}
			continue;
			end_IL_0053:
			break;
		}
		if (text != "")
		{
			DropInfo dropInfo = new DropInfo
			{
				file = text,
				pos = new Vector2(aPos.x, aPos.y)
			};
			this.dropInfo = dropInfo;
		}
	}

	private void LoadImage(int aIndex, DropInfo aInfo)
	{
		if (aInfo != null && GUILayoutUtility.GetLastRect().Contains(aInfo.pos))
		{
			byte[] data = File.ReadAllBytes(aInfo.file);
			Texture2D texture2D = new Texture2D(1, 1);
			texture2D.LoadImage(data);
			if (textures[aIndex] != null)
			{
				Object.Destroy(textures[aIndex]);
			}
			textures[aIndex] = texture2D;
		}
	}

	private void OnGUI()
	{
		DropInfo aInfo = null;
		if (Event.current.type == EventType.Repaint && dropInfo != null)
		{
			aInfo = dropInfo;
			dropInfo = null;
		}
		GUILayout.BeginHorizontal();
		for (int i = 0; i < 3; i++)
		{
			if (textures[i] != null)
			{
				GUILayout.Label(textures[i], GUILayout.Width(200f), GUILayout.Height(200f));
			}
			else
			{
				GUILayout.Box("Drag image here", GUILayout.Width(200f), GUILayout.Height(200f));
			}
			LoadImage(i, aInfo);
		}
		GUILayout.EndHorizontal();
		GUILayout.BeginHorizontal();
		for (int j = 3; j < 6; j++)
		{
			if (textures[j] != null)
			{
				GUILayout.Label(textures[j], GUILayout.Width(200f), GUILayout.Height(200f));
			}
			else
			{
				GUILayout.Box("Drag image here", GUILayout.Width(200f), GUILayout.Height(200f));
			}
			LoadImage(j, aInfo);
		}
		GUILayout.EndHorizontal();
	}
}

+IntColor

File Created
cs
using UnityEngine;

public static class IntColor
{
	public static Color32 FromLong(long i)
	{
		return new Color32((byte)(i / 16777216), (byte)(i % 16777216 / 65536), (byte)(i % 65536 / 256), (byte)(i % 256));
	}

	public static long ToLong(ref Color c)
	{
		return (int)c.r * 255 * 16777216 + (int)c.g * 255 * 65536 + (int)c.b * 255 * 256 + (int)(c.a * 255f);
	}

	public static Color32 FromInt(int i)
	{
		byte b = (byte)(i / 4194304 * 2);
		byte b2 = (byte)(i % 4194304 / 32768 * 2);
		byte b3 = (byte)(i % 32768 / 256 * 2);
		byte a = (byte)(i % 256);
		return new Color32((byte)Mathf.Min(b + ((b % 2 != 0) ? 1 : 2), 255), (byte)Mathf.Min(b2 + ((b2 % 2 != 0) ? 1 : 2), 255), (byte)Mathf.Min(b3 + ((b3 % 2 != 0) ? 1 : 2), 255), a);
	}

	public static int ToInt(ref Color c)
	{
		return (int)(c.r * 127f) * 4194304 + (int)(c.g * 127f) * 32768 + (int)(c.b * 127f) * 256 + (int)(c.a * 255f);
	}

	public static int ToInt(Color c)
	{
		return (int)(c.r * 127f) * 4194304 + (int)(c.g * 127f) * 32768 + (int)(c.b * 127f) * 256 + (int)(c.a * 255f);
	}
}

+Lang

File Created
cs
using System;
using System.Collections.Generic;
using System.Text;

public class Lang
{
	public enum LangCode
	{
		None = 0,
		JP = 10,
		EN = 20,
		CN = 30
	}

	public class Words
	{
		public char comma;

		public char period;
	}

	public static NaturalStringComparer comparer = new NaturalStringComparer();

	public static bool runUpdate;

	public static Words words = new Words();

	public static string langCode = "";

	public static string suffix = "";

	public static string space = "";

	public static List<Dictionary<string, object>> listName;

	public static List<Dictionary<string, object>> listAlias;

	public static bool isJP;

	public static bool isBuiltin;

	public static List<char[]> articlesToRemove;

	public static LangGeneral General;

	public static LangGame Game;

	public static LangNote Note;

	public static SourceData List;

	public static LangSetting setting;

	public static ExcelData alias;

	public static ExcelData names;

	public static ExcelData excelDialog;

	public static bool IsBuiltin(string id)
	{
		if (!(id == "JP"))
		{
			return id == "EN";
		}
		return true;
	}

	public static void Init(string lang)
	{
		setting = MOD.langs.TryGetValue(lang) ?? MOD.langs["EN"];
		langCode = lang;
		isJP = lang == "JP";
		isBuiltin = lang == "JP" || lang == "EN";
		suffix = ((!isBuiltin) ? "_L" : (isJP ? "_JP" : ""));
		space = (setting.useSpace ? " " : "");
		char.TryParse("_comma".lang(), out words.comma);
		char.TryParse("_period".lang(), out words.period);
		SourceData.LangSuffix = suffix;
		articlesToRemove = new List<char[]>();
		string[] list = GetList("_articlesToRemove");
		foreach (string text in list)
		{
			articlesToRemove.Add(text.ToCharArray());
		}
	}

	public static string Get(string id)
	{
		if (!(General != null))
		{
			return id;
		}
		return General.Get(id);
	}

	public static bool Has(string id)
	{
		return General.map.ContainsKey(id);
	}

	public static string TryGet(string id)
	{
		if (!General.map.ContainsKey(id))
		{
			return null;
		}
		return Get(id);
	}

	public static string[] GetList(string id)
	{
		return List.GetList(id);
	}

	public static string ParseRaw(string text, string val1, string val2 = null, string val3 = null, string val4 = null, string val5 = null)
	{
		StringBuilder stringBuilder = new StringBuilder(text);
		stringBuilder.Replace("#1", val1 ?? "");
		if (val2 != null)
		{
			stringBuilder.Replace("#(s2)", (val2.Replace(",", "").ToInt() <= 1) ? "" : "_s".lang());
		}
		stringBuilder.Replace("#(s)", (val1.Replace(",", "").ToInt() <= 1) ? "" : "_s".lang());
		if (val2 != null)
		{
			stringBuilder.Replace("#2", val2);
		}
		if (val3 != null)
		{
			stringBuilder.Replace("#3", val3);
		}
		if (val4 != null)
		{
			stringBuilder.Replace("#4", val4);
		}
		if (val5 != null)
		{
			stringBuilder.Replace("#5", val5);
		}
		return stringBuilder.ToString();
	}

	public static string Parse(string idLang, string val1, string val2 = null, string val3 = null, string val4 = null, string val5 = null)
	{
		return ParseRaw(Get(idLang), val1, val2, val3, val4, val5);
	}

	public static string LoadText(string id)
	{
		return null;
	}

	public static string _Number(int a)
	{
		return $"{a:#,0}";
	}

	public static string _currency(int a, string IDCurrency)
	{
		return ("u_currency_" + IDCurrency).lang($"{a:#,0}");
	}

	public static string _currency(int a, bool showUnit = false, int unitSize = 14)
	{
		return $"{a:#,0}" + ((!showUnit) ? "" : ((unitSize == 0) ? "u_money".lang(a.ToString() ?? "") : ("<size=" + unitSize + "> " + "u_money".lang(a.ToString() ?? "") + "</size>")));
	}

	public static string _weight(int a, int b, bool showUnit = true, int unitSize = 0)
	{
		return (0.001f * (float)a).ToString("#0.0") + "/" + (0.001f * (float)b).ToString("#0.0") + ((!showUnit) ? "" : ((unitSize == 0) ? "s" : ("<size=" + unitSize + "> s</size>")));
	}

	public static string _gender(int id)
	{
		return GetList("genders")[id];
	}

	public static string _weight(int a, bool showUnit = true, int unitSize = 0)
	{
		return (0.001f * (float)a).ToString("#0.0") + ((!showUnit) ? "" : ((unitSize == 0) ? "s" : ("<size=" + unitSize + "> s</size>")));
	}

	public static string _rarity(int a)
	{
		return a switch
		{
			4 => "SSR", 
			3 => "SR", 
			2 => "R", 
			1 => "C", 
			0 => "K", 
			_ => "LE", 
		};
	}

	public static string _ChangeNum(int prev, int now)
	{
		return prev + " ⇒ " + now;
	}

	public static string[] GetDialog(string idSheet, string idTopic)
	{
		if (excelDialog == null)
		{
			string path = CorePath.CorePackage.TextDialog + "dialog.xlsx";
			excelDialog = new ExcelData();
			excelDialog.path = path;
		}
		excelDialog.BuildMap(idSheet);
		ExcelData.Sheet sheet = excelDialog.sheets[idSheet];
		string key = "text" + (isBuiltin ? ("_" + langCode) : "");
		Dictionary<string, string> dictionary = sheet.map.TryGetValue(idTopic);
		if (dictionary == null || !dictionary.ContainsKey(key))
		{
			return new string[1] { idTopic };
		}
		string text = dictionary[key];
		if (text.IsEmpty())
		{
			text = dictionary["text_EN"];
		}
		return text.Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
	}
}

+LangGame

File Created
cs
using System;

public class LangGame : SourceLang<LangGame.Row>
{
	[Serializable]
	public class Row : LangRow
	{
		public string filter;

		public string group;

		public string color;

		public string logColor;

		public string sound;

		public string effect;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetString(0),
			filter = SourceData.GetString(1),
			group = SourceData.GetString(2),
			color = SourceData.GetString(3),
			logColor = SourceData.GetString(4),
			sound = SourceData.GetString(5),
			effect = SourceData.GetString(6),
			text_JP = SourceData.GetString(7),
			text = SourceData.GetString(8)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}

	public static bool Has(string id)
	{
		return Lang.Game.map.ContainsKey(id);
	}
}

+LangGeneral

File Created
cs
using System;

public class LangGeneral : SourceLang<LangGeneral.Row>
{
	[Serializable]
	public class Row : LangRow
	{
		public string filter;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetString(0),
			filter = SourceData.GetString(1),
			text_JP = SourceData.GetString(2),
			text = SourceData.GetString(3)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}
}

+LangList

File Created
cs
using System;

public class LangList : SourceDataString<LangList.Row>
{
	[Serializable]
	public class Row : BaseRow
	{
		public string id;

		public string filter;

		public string[] text_JP;

		public string[] text;

		public string[] text_L;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetString(0),
			filter = SourceData.GetString(1),
			text_JP = SourceData.GetStringArray(2),
			text = SourceData.GetStringArray(3)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}

	public override string[] GetList(string id)
	{
		Row row = map.TryGetValue(id);
		if (row == null)
		{
			return null;
		}
		if (!Lang.isBuiltin)
		{
			if (row.text_L == null || row.text_L.Length == 0)
			{
				return row.text;
			}
			return row.text_L;
		}
		if (!Lang.isJP)
		{
			return row.text;
		}
		return row.text_JP;
	}
}

+LangNote

File Created
cs
using System;

public class LangNote : SourceDataString<LangNote.Row>
{
	[Serializable]
	public class Row : BaseRow
	{
		public string id;

		public string text_JP;

		public string text;

		public string text_L;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetString(0),
			text_JP = SourceData.GetString(1),
			text = SourceData.GetString(2)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}
}

+LangRow

File Created
cs
public class LangRow : SourceData.BaseRow
{
	public string id;

	public string text_JP;

	public string text;

	public string text_L;
}

+LangSetting

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using IniParser;
using IniParser.Model;
using UnityEngine;

public class LangSetting
{
	public class FontSetting
	{
		public float lineSpace = 1f;

		public int index;

		public int importSize = 16;

		public string id;
	}

	public string id;

	public string name;

	public string name_en;

	public string dir;

	public bool addArticle;

	public bool pluralize;

	public bool capitalize;

	public bool useSpace;

	public bool hyphenation;

	public bool useTone;

	public bool thirdperson;

	public bool stripPuns;

	public int nameStyle;

	public int bracket;

	public int combatTextStyle;

	public List<FontSetting> listFont = new List<FontSetting>();

	public string pathVersion => dir + "/version.ini";

	public LangSetting(string path)
	{
		try
		{
			IniData iniData = new FileIniDataParser().ReadFile(path, Encoding.UTF8);
			name = iniData.GetKey("name");
			name_en = iniData.GetKey("name_en");
			addArticle = iniData.GetKey("add_article") == "1";
			pluralize = iniData.GetKey("pluralize") == "1";
			capitalize = iniData.GetKey("capitalize") == "1";
			useSpace = iniData.GetKey("use_space") == "1";
			useTone = iniData.GetKey("use_tone") == "1";
			nameStyle = iniData.GetKey("name_style").ToInt();
			combatTextStyle = iniData.GetKey("combat_text_style").ToInt();
			bracket = iniData.GetKey("bracket").ToInt();
			hyphenation = iniData.GetKey("hyphenation") == "1";
			thirdperson = iniData.GetKey("thirdperson") == "1";
			stripPuns = iniData.GetKey("strip_puns") == "1";
			foreach (KeyData item in iniData["LoadFont"])
			{
				string[] array = item.Value.Split(',');
				FontSetting fontSetting = new FontSetting
				{
					index = array[0].ToInt(),
					id = array[1]
				};
				if (array.Length >= 3)
				{
					fontSetting.importSize = array[2].ToInt();
				}
				if (array.Length >= 4)
				{
					fontSetting.lineSpace = array[3].ToFloat();
				}
				listFont.Add(fontSetting);
			}
		}
		catch (Exception message)
		{
			Debug.Log(message);
			Debug.Log("exception: Failed to parse:" + path);
		}
	}

	public int GetVersion()
	{
		try
		{
			return new FileIniDataParser().ReadFile(pathVersion, Encoding.UTF8).Global["version"].ToInt();
		}
		catch (Exception message)
		{
			Debug.Log(message);
			Debug.Log("exception: Failed to parse:" + pathVersion);
			return 0;
		}
	}

	public void SetVersion()
	{
		FileIniDataParser fileIniDataParser = new FileIniDataParser();
		if (!File.Exists(pathVersion))
		{
			StreamWriter streamWriter = File.CreateText(pathVersion);
			streamWriter.WriteLine("version=" + BaseCore.Instance.version.GetInt());
			streamWriter.Close();
		}
		else
		{
			IniData iniData = fileIniDataParser.ReadFile(pathVersion, Encoding.UTF8);
			iniData.Global["version"] = BaseCore.Instance.version.GetInt().ToString() ?? "";
			fileIniDataParser.WriteFile(pathVersion, iniData);
		}
	}
}

+LangTalk

File Created
cs
using System;

public class LangTalk : SourceDataString<LangTalk.Row>
{
	[Serializable]
	public class Row : BaseRow
	{
		public string id;

		public string text_JP;

		public string text;

		public string text_L;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetString(0),
			text_JP = SourceData.GetString(1),
			text = SourceData.GetString(2)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}
}

+LangWord

File Created
cs
using System;

public class LangWord : SourceDataInt<LangWord.Row>
{
	[Serializable]
	public class Row : BaseRow
	{
		public int id;

		public string group;

		public string name_JP;

		public string name;

		public string name_L;

		public override bool UseAlias => false;

		public override string GetAlias => "n";
	}

	public override Row CreateRow()
	{
		return new Row
		{
			id = SourceData.GetInt(0),
			group = SourceData.GetString(1),
			name_JP = SourceData.GetString(2),
			name = SourceData.GetString(3)
		};
	}

	public override void SetRow(Row r)
	{
		map[r.id] = r;
	}

	public override void OnAfterImportData()
	{
		int num = 0;
		foreach (Row row in rows)
		{
			if (row.id != 0)
			{
				num = row.id;
			}
			row.id = num;
			num++;
		}
	}
}

+LightData

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class LightData
{
	public Color color = new Color(1f, 1f, 1f, 25f / 64f);

	[Range(1f, 12f)]
	public int radius = 4;
}

+LoadingScreen

File Created
cs
using UnityEngine;
using UnityEngine.UI;

public class LoadingScreen : MonoBehaviour
{
	public Text moldText;

	public LayoutGroup layout;

	public Text Log(string s)
	{
		Debug.Log(s);
		Text text = Util.Instantiate(moldText, layout);
		text.text = s;
		return text;
	}
}

+Log

File Created
cs
using UnityEngine;

public static class Log
{
	public static string system;

	public static void App(string s)
	{
		if (!Application.isEditor)
		{
			Debug.Log(s);
		}
	}
}

+MOD

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class MOD
{
	public static Dictionary<string, LangSetting> langs = new Dictionary<string, LangSetting>();

	public static TalkDataList listTalk = new TalkDataList();

	public static ToneDataList tones = new ToneDataList();

	public static ExcelDataList actorSources = new ExcelDataList();

	public static ModItemList<Sprite> sprites = new ModItemList<Sprite>();

	public static Action<DirectoryInfo> OnAddPcc;

	public static List<FileInfo> listMaps = new List<FileInfo>();

	public static List<FileInfo> listPartialMaps = new List<FileInfo>();
}

+MatColors

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class MatColors
{
	public Color main;

	public Color alt;
}

+ModItem

File Created
cs
using System.IO;
using UnityEngine;

public class ModItem<T> where T : Object
{
	public ModItemList<T> list;

	public string category;

	public string id;

	public string resourcePath;

	public string parent;

	public string parentParent;

	public FileInfo fileInfo;

	public T cache;

	public ModItem(FileInfo _fileInfo, string path = null, ModItemList<T> _list = null, string desiredID = null)
	{
		list = _list;
		resourcePath = path;
		Set(_fileInfo, path, desiredID);
	}

	public void Set(FileInfo _fileInfo, string path, string desiredID = null)
	{
		if (_fileInfo != null)
		{
			fileInfo = _fileInfo;
			parent = ((fileInfo != null) ? fileInfo.Directory.Name : Path.GetDirectoryName(path));
			parentParent = ((fileInfo != null) ? fileInfo.Directory.Parent.Name : Path.GetDirectoryName(path.Split('/')[0]));
			id = desiredID ?? Path.GetFileNameWithoutExtension((fileInfo != null) ? fileInfo.Name : path);
			if (list != null && list.catLength > 0)
			{
				category = id.Substring(0, list.catLength);
			}
		}
	}

	public T GetObject(object option = null)
	{
		if (fileInfo == null)
		{
			return null;
		}
		if (list == null)
		{
			if (cache == null)
			{
				cache = IO.LoadObject<T>(fileInfo, option);
			}
			return cache;
		}
		if (resourcePath != null)
		{
			return list.cache.Get(resourcePath, ResourceLoadType.Resource, option);
		}
		return list.cache.Get(fileInfo.FullName, ResourceLoadType.Streaming, option);
	}

	public void ClearCache()
	{
		if (list == null)
		{
			if ((bool)cache)
			{
				Object.DestroyImmediate(cache);
			}
		}
		else
		{
			list.cache.Clear();
		}
	}
}

+ModItemList

File Created
cs
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class ModItemList<T> where T : Object
{
	public ResourceCache<T> cache = new ResourceCache<T>();

	public List<ModItem<T>> list = new List<ModItem<T>>();

	public Dictionary<string, ModItem<T>> dict = new Dictionary<string, ModItem<T>>();

	public int catLength;

	public ModItemList(int _catLength = 0)
	{
		catLength = _catLength;
	}

	public string GetRandomID(string category = null)
	{
		if (list.Count == 0)
		{
			return null;
		}
		ModItem<T> modItem;
		do
		{
			modItem = list[Rand.rnd(list.Count)];
		}
		while (category != null && !(modItem.category == category));
		return modItem.id;
	}

	public string GetNextID(string currentId, int a, bool ignoreCategory = true)
	{
		int num = IndexOf(currentId) + a;
		if (num >= list.Count)
		{
			num = 0;
		}
		if (num < 0)
		{
			num = list.Count - 1;
		}
		return list[num].id;
	}

	public int IndexOf(string id)
	{
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i].id == id)
			{
				return i;
			}
		}
		return -1;
	}

	public ModItem<T> GetItem(string id, bool returnNull = false)
	{
		ModItem<T> value = null;
		if (dict.TryGetValue(id, out value))
		{
			return value;
		}
		if (!returnNull)
		{
			return list[0];
		}
		return null;
	}

	public T GetObject(string id, object option = null)
	{
		ModItem<T> item = GetItem(id, returnNull: true);
		if (item != null)
		{
			return item.GetObject();
		}
		return null;
	}

	public void Add(FileInfo fi, string path = null, string prefix = "")
	{
		Add(Path.GetFileNameWithoutExtension(prefix + ((fi != null) ? fi.Name : path)), fi, path);
	}

	public void Add(string id, FileInfo fi, string path = null)
	{
		if (dict.ContainsKey(id))
		{
			dict[id].Set(fi, path);
			return;
		}
		list.Add(new ModItem<T>(fi, path, this, id));
		dict.Add(id, list[list.Count - 1]);
	}
}

+ObjectPool

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour
{
	public interface IItem
	{
		void Update();
	}

	public class Item<T> : IItem where T : new()
	{
		public Stack<T> pools;

		public int max;

		public int addsPerUpdate;

		public Action<T> onCreate;

		public Component mold;

		public void Create(int _max, int _addsPerUpdate = 10)
		{
			max = _max;
			addsPerUpdate = _addsPerUpdate;
			pools = new Stack<T>(_max);
		}

		public T Get(Component parent)
		{
			T obj = ((pools.Count > 0) ? pools.Pop() : Create());
			Component obj2 = obj as Component;
			obj2.transform.SetParent(parent.transform, worldPositionStays: false);
			obj2.SetActive(enable: true);
			return obj;
		}

		public T Get()
		{
			if ((bool)mold)
			{
				Debug.LogError("tried to Get component");
			}
			if (pools.Count > 0)
			{
				return pools.Pop();
			}
			return Create();
		}

		public void Update()
		{
			for (int i = 0; i < addsPerUpdate; i++)
			{
				if (pools.Count >= max)
				{
					break;
				}
				pools.Push(Create());
			}
		}

		public T Create()
		{
			T val;
			if ((bool)mold)
			{
				val = Util.Instantiate(mold, Instance).GetComponent<T>();
				(val as Component).SetActive(enable: false);
			}
			else
			{
				val = new T();
			}
			if (onCreate != null)
			{
				onCreate(val);
			}
			return val;
		}

		public Item<T> SetMold(Component _mold)
		{
			mold = _mold;
			return this;
		}

		public override string ToString()
		{
			return typeof(T).Name + ":" + pools.Count;
		}
	}

	public static ObjectPool Instance;

	public List<IItem> items = new List<IItem>();

	private void Awake()
	{
		Instance = this;
	}

	private void Update()
	{
		foreach (IItem item in items)
		{
			item.Update();
		}
	}

	public static Item<T> Create<T>(int max = 100, int addsPerUpdate = 10, Action<T> _onCreate = null) where T : new()
	{
		Item<T> item = new Item<T>();
		item.Create(max, addsPerUpdate);
		item.onCreate = _onCreate;
		Instance.items.Add(item);
		return item;
	}
}

+PaintPosition

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class PaintPosition
{
	public Vector3 pos;

	public bool flip;
}

+PoolManager

File Created
cs
using System.Collections.Generic;
using UnityEngine;

public class PoolManager : MonoBehaviour
{
	public class PoolGroup
	{
		public string id;

		public Transform original;

		public Transform holder;

		public List<Transform> pooledList = new List<Transform>();

		public PoolGroup(Transform original, PoolManager manager, string _id)
		{
			id = _id;
			this.original = original;
			holder = new GameObject().transform;
			holder.SetParent(manager.transform);
			holder.name = id;
		}

		public Transform Spawn(Transform parent)
		{
			Transform transform = null;
			if (ignorePool)
			{
				transform = Object.Instantiate(original);
			}
			else if (pooledList.Count != 0)
			{
				transform = pooledList[pooledList.Count - 1];
				pooledList.RemoveAt(pooledList.Count - 1);
			}
			else
			{
				transform = Object.Instantiate(original);
				current.spawnedList[transform.GetHashCode()] = this;
			}
			if (Application.isEditor)
			{
				transform.SetAsLastSibling();
			}
			transform.SetParent(parent, worldPositionStays: false);
			return transform;
		}

		public void Despawn(Transform trans)
		{
			trans.SetParent(holder, worldPositionStays: false);
			pooledList.Add(trans);
		}
	}

	public static PoolManager current;

	public static Transform _trans;

	public static bool ignorePool;

	public Dictionary<string, PoolGroup> groups;

	public Dictionary<int, PoolGroup> spawnedList;

	private void Awake()
	{
		current = this;
		_trans = base.transform;
		spawnedList = new Dictionary<int, PoolGroup>();
		groups = new Dictionary<string, PoolGroup>();
		base.gameObject.SetActive(value: false);
	}

	public static T Spawn<T>(T original, Component parent = null) where T : Component
	{
		return current._Spawn(original.name, original.transform, parent?.transform).GetComponent<T>();
	}

	public static T Spawn<T>(string id, string path, Transform parent = null)
	{
		return current._Spawn(id, path, parent).GetComponent<T>();
	}

	public static Transform Spawn(string id, string path, Transform parent)
	{
		return current._Spawn(id, path, parent);
	}

	public static PoolGroup GetGroup(string id)
	{
		return current.groups[id];
	}

	private Transform _Spawn(string id, string path, Transform parent)
	{
		PoolGroup poolGroup = groups.TryGetValue(id);
		if (poolGroup == null)
		{
			poolGroup = CreateGroup(id, path);
		}
		return poolGroup.Spawn(parent);
	}

	private Transform _Spawn(string id, Transform original, Transform parent)
	{
		PoolGroup poolGroup = groups.TryGetValue(id);
		if (poolGroup == null)
		{
			poolGroup = CreateGroup(id, original);
		}
		return poolGroup.Spawn(parent);
	}

	public PoolGroup CreateGroup(string id, Transform original)
	{
		PoolGroup poolGroup = new PoolGroup(original, this, id);
		groups.Add(id, poolGroup);
		return poolGroup;
	}

	public PoolGroup CreateGroup(string id, string path)
	{
		return CreateGroup(id, Resources.Load<Transform>(path));
	}

	public static void Despawn(Component c)
	{
		if (Application.isPlaying)
		{
			if (ignorePool)
			{
				Object.Destroy(c.gameObject);
			}
			else
			{
				current.spawnedList[c.transform.GetHashCode()].Despawn(c.transform);
			}
		}
	}

	public static bool TryDespawn(Component c)
	{
		if (ignorePool)
		{
			return false;
		}
		PoolGroup poolGroup = current.spawnedList.TryGetValue(c.transform.GetHashCode());
		if (poolGroup == null)
		{
			return false;
		}
		poolGroup.Despawn(c.transform);
		return true;
	}

	public static void DespawnOrDestroy(Component c)
	{
		if (ignorePool || !TryDespawn(c))
		{
			Object.Destroy(c.gameObject);
		}
	}
}

+PrefabFix

File Created
cs
using UnityEngine;

public class PrefabFix : MonoBehaviour
{
	public int siblingIndex;

	private void Awake()
	{
		base.transform.SetSiblingIndex(siblingIndex);
	}
}

+AssemblyInfo

File Created
cs
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyVersion("0.0.0.0")]

+Rand

File Created
cs
using System;

public static class Rand
{
	public static int MaxBytes = 1111;

	public static Random _random = new Random();

	public static byte[] bytes;

	public static void InitBytes(int a)
	{
		SetSeed(a);
		bytes = new byte[MaxBytes];
		for (int i = 0; i < MaxBytes; i++)
		{
			bytes[i] = (byte)_random.Next(256);
		}
		SetSeed();
	}

	public static void UseSeed(int seed, Action action)
	{
		SetSeed(seed);
		action();
		SetSeed();
	}

	public static int rndSeed(int a, int seed)
	{
		SetSeed(seed);
		int result = rnd(a);
		SetSeed();
		return result;
	}

	public static void SetSeed(int a = -1)
	{
		_random = ((a == -1) ? new Random() : new Random(a));
	}

	public static int Range(int min, int max)
	{
		return _random.Next(max - min) + min;
	}

	public static float Range(float min, float max)
	{
		return (float)(_random.NextDouble() * (double)(max - min) + (double)min);
	}

	public static int rnd(int max)
	{
		if (max > 0)
		{
			return _random.Next(max);
		}
		return 0;
	}

	public static float rndf(float max)
	{
		return Range(0f, max);
	}

	public static int rndSqrt(int max)
	{
		return _random.Next(_random.Next(max) + 1);
	}

	public static int rndNormal2(int max)
	{
		int num = max / 2;
		return num + rnd(rnd(rnd(num) + 1) + 1) - rnd(rnd(rnd(num) + 1) + 1);
	}

	public static int rndNormal(int max)
	{
		int num = max / 2;
		return num + rnd(rnd(num) + 1) - rnd(rnd(num) + 1);
	}
}

+RectData

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class RectData
{
	public Vector2 position = new Vector2(-1f, -1f);

	public Vector2 size = new Vector2(-1f, -1f);

	public Vector2 pivot;

	public Vector2 anchorMin;

	public Vector2 anchorMax;

	public void Apply(RectTransform rect)
	{
		rect.SetRect(position.x, position.y, size.x, size.y, pivot.x, pivot.y, anchorMax.x, anchorMax.y, anchorMax.x, anchorMax.y);
	}
}

+RectPosition

File Created
cs
public enum RectPosition
{
	Auto,
	TopLEFT,
	TopCenter,
	TopRIGHT,
	Left,
	Center,
	Right,
	BottomLEFT,
	BottomCenter,
	BottomRIGHT
}

+ReleaseMode

File Created
cs
public enum ReleaseMode
{
	Public,
	Internal,
	Debug
}

+ResourceCache

File Created
cs
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class ResourceCache
{
	public static ResourceCache<Object> caches = new ResourceCache<Object>();

	public static T Load<T>(string path) where T : Object
	{
		return caches.Get<T>(path);
	}

	public static T LoadBundle<T>(string path) where T : Object
	{
		return caches.Get<T>(path, ResourceLoadType.AssetBundle);
	}
}
public class ResourceCache<T> where T : Object
{
	public Dictionary<string, T> dict = new Dictionary<string, T>();

	public string path;

	public ResourceCache(string _path = "")
	{
		path = _path;
	}

	public void Clear()
	{
		foreach (T value in dict.Values)
		{
			Object.DestroyImmediate(value);
		}
		dict.Clear();
	}

	public T Get(string id, ResourceLoadType loadType = ResourceLoadType.Resource, object option = null)
	{
		T value = null;
		string key = typeof(T).Name + id;
		if (!dict.TryGetValue(key, out value))
		{
			value = ((loadType == ResourceLoadType.Streaming) ? IO.LoadObject<T>(path + id, option) : Resources.Load<T>(path + id));
			dict.Add(key, value);
		}
		return value;
	}

	public T2 Get<T2>(string id, ResourceLoadType loadType = ResourceLoadType.Resource) where T2 : Object
	{
		T value = null;
		string key = typeof(T2).Name + id;
		if (!dict.TryGetValue(key, out value))
		{
			T2 val = null;
			val = ((loadType != 0) ? AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/Bundle/" + id).LoadAsset<GameObject>(new FileInfo(id).Name).GetComponent<T2>() : Resources.Load<T2>(path + id));
			dict.Add(key, val as T);
			return val;
		}
		return value as T2;
	}
}

+ResourceLoadType

File Created
cs
public enum ResourceLoadType
{
	Resource,
	Streaming,
	AssetBundle
}

+ExtensionFilter

File Created
cs
namespace SFB;

public struct ExtensionFilter
{
	public string Name;

	public string[] Extensions;

	public ExtensionFilter(string filterName, params string[] filterExtensions)
	{
		Name = filterName;
		Extensions = filterExtensions;
	}
}

+IStandaloneFileBrowser

File Created
cs
using System;

namespace SFB;

public interface IStandaloneFileBrowser
{
	string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect);

	string[] OpenFolderPanel(string title, string directory, bool multiselect);

	string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions);

	void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb);

	void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb);

	void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb);
}

+StandaloneFileBrowser

File Created
cs
using System;

namespace SFB;

public class StandaloneFileBrowser
{
	private static IStandaloneFileBrowser _platformWrapper;

	static StandaloneFileBrowser()
	{
		_platformWrapper = new StandaloneFileBrowserWindows();
	}

	public static string[] OpenFilePanel(string title, string directory, string extension, bool multiselect)
	{
		ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
		{
			new ExtensionFilter("", extension)
		});
		return OpenFilePanel(title, directory, extensions, multiselect);
	}

	public static string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect)
	{
		return _platformWrapper.OpenFilePanel(title, directory, extensions, multiselect);
	}

	public static void OpenFilePanelAsync(string title, string directory, string extension, bool multiselect, Action<string[]> cb)
	{
		ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
		{
			new ExtensionFilter("", extension)
		});
		OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
	}

	public static void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb)
	{
		_platformWrapper.OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
	}

	public static string[] OpenFolderPanel(string title, string directory, bool multiselect)
	{
		return _platformWrapper.OpenFolderPanel(title, directory, multiselect);
	}

	public static void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb)
	{
		_platformWrapper.OpenFolderPanelAsync(title, directory, multiselect, cb);
	}

	public static string SaveFilePanel(string title, string directory, string defaultName, string extension)
	{
		ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
		{
			new ExtensionFilter("", extension)
		});
		return SaveFilePanel(title, directory, defaultName, extensions);
	}

	public static string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions)
	{
		return _platformWrapper.SaveFilePanel(title, directory, defaultName, extensions);
	}

	public static void SaveFilePanelAsync(string title, string directory, string defaultName, string extension, Action<string> cb)
	{
		ExtensionFilter[] extensions = (string.IsNullOrEmpty(extension) ? null : new ExtensionFilter[1]
		{
			new ExtensionFilter("", extension)
		});
		SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
	}

	public static void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb)
	{
		_platformWrapper.SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
	}
}

+StandaloneFileBrowserWindows

File Created
cs
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Ookii.Dialogs;

namespace SFB;

public class StandaloneFileBrowserWindows : IStandaloneFileBrowser
{
	[DllImport("user32.dll")]
	private static extern IntPtr GetActiveWindow();

	public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect)
	{
		VistaOpenFileDialog vistaOpenFileDialog = new VistaOpenFileDialog();
		vistaOpenFileDialog.Title = title;
		if (extensions != null)
		{
			vistaOpenFileDialog.Filter = GetFilterFromFileExtensionList(extensions);
			vistaOpenFileDialog.FilterIndex = 1;
		}
		else
		{
			vistaOpenFileDialog.Filter = string.Empty;
		}
		vistaOpenFileDialog.Multiselect = multiselect;
		if (!string.IsNullOrEmpty(directory))
		{
			vistaOpenFileDialog.FileName = GetDirectoryPath(directory);
		}
		string[] result = ((vistaOpenFileDialog.ShowDialog(new WindowWrapper(GetActiveWindow())) == DialogResult.OK) ? vistaOpenFileDialog.FileNames : new string[0]);
		vistaOpenFileDialog.Dispose();
		return result;
	}

	public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb)
	{
		cb(OpenFilePanel(title, directory, extensions, multiselect));
	}

	public string[] OpenFolderPanel(string title, string directory, bool multiselect)
	{
		VistaFolderBrowserDialog vistaFolderBrowserDialog = new VistaFolderBrowserDialog();
		vistaFolderBrowserDialog.Description = title;
		if (!string.IsNullOrEmpty(directory))
		{
			vistaFolderBrowserDialog.SelectedPath = GetDirectoryPath(directory);
		}
		string[] result = ((vistaFolderBrowserDialog.ShowDialog(new WindowWrapper(GetActiveWindow())) != DialogResult.OK) ? new string[0] : new string[1] { vistaFolderBrowserDialog.SelectedPath });
		vistaFolderBrowserDialog.Dispose();
		return result;
	}

	public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb)
	{
		cb(OpenFolderPanel(title, directory, multiselect));
	}

	public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions)
	{
		VistaSaveFileDialog vistaSaveFileDialog = new VistaSaveFileDialog();
		vistaSaveFileDialog.Title = title;
		string text = "";
		if (!string.IsNullOrEmpty(directory))
		{
			text = GetDirectoryPath(directory);
		}
		if (!string.IsNullOrEmpty(defaultName))
		{
			text += defaultName;
		}
		vistaSaveFileDialog.FileName = text;
		if (extensions != null)
		{
			vistaSaveFileDialog.Filter = GetFilterFromFileExtensionList(extensions);
			vistaSaveFileDialog.FilterIndex = 1;
			vistaSaveFileDialog.DefaultExt = extensions[0].Extensions[0];
			vistaSaveFileDialog.AddExtension = true;
		}
		else
		{
			vistaSaveFileDialog.DefaultExt = string.Empty;
			vistaSaveFileDialog.Filter = string.Empty;
			vistaSaveFileDialog.AddExtension = false;
		}
		string result = ((vistaSaveFileDialog.ShowDialog(new WindowWrapper(GetActiveWindow())) == DialogResult.OK) ? vistaSaveFileDialog.FileName : "");
		vistaSaveFileDialog.Dispose();
		return result;
	}

	public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb)
	{
		cb(SaveFilePanel(title, directory, defaultName, extensions));
	}

	private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions)
	{
		string text = "";
		for (int i = 0; i < extensions.Length; i++)
		{
			ExtensionFilter extensionFilter = extensions[i];
			text = text + extensionFilter.Name + "(";
			string[] extensions2 = extensionFilter.Extensions;
			foreach (string text2 in extensions2)
			{
				text = text + "*." + text2 + ",";
			}
			text = text.Remove(text.Length - 1);
			text += ") |";
			extensions2 = extensionFilter.Extensions;
			foreach (string text3 in extensions2)
			{
				text = text + "*." + text3 + "; ";
			}
			text += "|";
		}
		return text.Remove(text.Length - 1);
	}

	private static string GetDirectoryPath(string directory)
	{
		string text = Path.GetFullPath(directory);
		if (!text.EndsWith("\\"))
		{
			text += "\\";
		}
		if (Path.GetPathRoot(text) == text)
		{
			return directory;
		}
		string directoryName = Path.GetDirectoryName(text);
		char directorySeparatorChar = Path.DirectorySeparatorChar;
		return directoryName + directorySeparatorChar;
	}
}

+WindowWrapper

File Created
cs
using System;
using System.Windows.Forms;

namespace SFB;

public class WindowWrapper : IWin32Window
{
	private IntPtr _hwnd;

	public IntPtr Handle => _hwnd;

	public WindowWrapper(IntPtr handle)
	{
		_hwnd = handle;
	}
}

+SerializableColor

File Created
cs
using System;
using Newtonsoft.Json;
using UnityEngine;

[Serializable]
[JsonObject(MemberSerialization.OptIn)]
public class SerializableColor
{
	[JsonProperty]
	public byte[] _color;

	public Color Get()
	{
		return (_color != null) ? new Color32(_color[0], _color[1], _color[2], _color[3]) : default(Color32);
	}

	public SerializableColor()
	{
	}

	public SerializableColor(Color color)
	{
		Set(color);
	}

	public SerializableColor(byte[] bytes)
	{
		_color = bytes;
	}

	public SerializableColor(byte r, byte g, byte b, byte a = byte.MaxValue)
	{
		_color = new byte[4] { r, g, b, a };
	}

	public SerializableColor Set(Color color)
	{
		Color32 color2 = color;
		_color = new byte[4] { color2.r, color2.g, color2.b, color2.a };
		return this;
	}

	public static void ToBytes(Color color, ref byte[] bytes, int index)
	{
		Color32 color2 = color;
		new byte[4] { color2.r, color2.g, color2.b, color2.a }.CopyTo(bytes, index);
	}

	public static Color FromBytes(byte[] _color, int index)
	{
		return new Color32(_color[index], _color[index + 1], _color[index + 2], _color[index + 3]);
	}
}

+ShouldSerializeContractResolver

File Created
cs
using System;
using System.Collections;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class ShouldSerializeContractResolver : DefaultContractResolver
{
	public static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();

	protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
	{
		JsonProperty property = base.CreateProperty(member, memberSerialization);
		if (!typeof(string).IsAssignableFrom(property.PropertyType) && typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
		{
			Predicate<object> newShouldSerialize = (object obj) => !(property.ValueProvider.GetValue(obj) is ICollection collection) || collection.Count != 0;
			Predicate<object> oldShouldSerialize = property.ShouldSerialize;
			property.ShouldSerialize = ((oldShouldSerialize != null) ? ((Predicate<object>)((object o) => oldShouldSerialize(o) && newShouldSerialize(o))) : newShouldSerialize);
		}
		return property;
	}
}

+SingleContent

File Created
cs
using System.Collections.Generic;
using UnityEngine;

public class SingleContent : MonoBehaviour
{
	public List<GameObject> exclude;

	public void Select(GameObject go)
	{
		if (exclude.Contains(go))
		{
			return;
		}
		foreach (Transform componentsInDirectChild in this.GetComponentsInDirectChildren<Transform>())
		{
			if (!exclude.Contains(componentsInDirectChild.gameObject) && !componentsInDirectChild.gameObject.tag.Contains("PivotTooltip") && componentsInDirectChild.gameObject != go)
			{
				componentsInDirectChild.gameObject.SetActive(value: false);
			}
		}
	}
}

+SourceData

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using UnityEngine;

public class SourceData<T, T2> : SourceData where T : SourceData.BaseRow
{
	public class FieldInfo
	{
		public string id;

		public string name;

		public bool isStatic;

		public int width;

		public int column;

		public bool IsIndex => id == "id";

		public string GetValue(T r)
		{
			if (r.HasField<string>(id))
			{
				return r.GetField<string>(id);
			}
			if (r.HasField<int>(id))
			{
				return r.GetField<int>(id).ToString();
			}
			if (r.HasField<string[]>(id))
			{
				string text = "";
				string[] field = r.GetField<string[]>(id);
				if (field != null)
				{
					string[] array = field;
					foreach (string text2 in array)
					{
						text = text + text2 + ",";
					}
				}
				return text.TrimEnd(',');
			}
			return "";
		}
	}

	public class FieldMap
	{
		public FieldInfo field;

		public int column;
	}

	public List<T> rows = new List<T>();

	public Dictionary<T2, T> map = new Dictionary<T2, T>();

	public Dictionary<string, T> alias = new Dictionary<string, T>();

	[NonSerialized]
	public bool initialized;

	[NonSerialized]
	private List<T> _backupRows = new List<T>();

	[NonSerialized]
	public List<string> editorListString = new List<string>();

	public static ISheet currentSheet;

	public bool CanReset => true;

	public virtual string[] ImportFields => new string[1] { "" };

	public override void Init()
	{
		if (initialized)
		{
			Debug.Log("#init Skipping sourceData.Init:" + base.name);
			return;
		}
		initialized = true;
		editorListString.Clear();
		int num = 0;
		foreach (T row in rows)
		{
			SetRow(row);
			if (row.UseAlias)
			{
				alias[row.GetAlias] = row;
			}
			row._index = num;
			num++;
		}
		OnInit();
	}

	public virtual void OnInit()
	{
	}

	public virtual void SetRow(T row)
	{
	}

	public override void Reset()
	{
		if (CanReset)
		{
			initialized = false;
			if (!Application.isPlaying)
			{
				BaseCore.resetRuntime = true;
			}
			if (map != null)
			{
				map.Clear();
			}
			if (map != null)
			{
				alias.Clear();
			}
			if (Application.isPlaying)
			{
				Init();
			}
		}
	}

	public override bool ImportData(ISheet sheet, string bookname, bool overwrite = false)
	{
		if (!overwrite)
		{
			rows = new List<T>();
		}
		isNew = true;
		nameSheet = sheet.SheetName;
		nameBook = bookname;
		SourceData.rowDefault = sheet.GetRow(2);
		int num = 0;
		for (int i = 3; i <= sheet.LastRowNum; i++)
		{
			SourceData.row = sheet.GetRow(i);
			if (SourceData.row == null || SourceData.row.GetCell(0) == null || SourceData.row.GetCell(0).ToString().IsEmpty())
			{
				break;
			}
			T val = CreateRow();
			val.OnImportData(this);
			rows.Add(val);
			num++;
		}
		string text = sheet.SheetName + "/" + sheet.LastRowNum + "/" + num;
		Debug.Log(text);
		ERROR.msg = text;
		OnAfterImportData();
		initialized = false;
		return true;
	}

	public virtual void OnAfterImportData()
	{
	}

	public virtual T CreateRow()
	{
		return null;
	}

	public override void BackupSource()
	{
		_backupRows = rows;
	}

	public override void RollbackSource()
	{
		rows = _backupRows;
	}

	public List<string> GetListString()
	{
		return BuildEditorList().editorListString;
	}

	public SourceData<T, T2> BuildEditorList()
	{
		if (editorListString.Count == 0)
		{
			foreach (T row in rows)
			{
				editorListString.Add(row.GetEditorListName());
			}
		}
		return this;
	}

	public List<FieldInfo> GetFields()
	{
		List<FieldInfo> list = new List<FieldInfo>();
		int x = 0;
		AddField("id", 4096);
		AddField("version", 4096);
		AddField("filter", 4096);
		AddField("name", 4096);
		AddField("text", 4096);
		AddField("detail", 4096);
		AddField("description", 4096);
		string[] importFields = ImportFields;
		foreach (string text in importFields)
		{
			if (!text.IsEmpty())
			{
				AddField(text, 4096);
			}
		}
		return list;
		void AddField(string id, int width)
		{
			bool flag = id == "id" || id == "filter";
			bool flag2 = id == "version";
			if (!(typeof(T).GetField(id) == null) || flag2)
			{
				list.Add(new FieldInfo
				{
					id = id,
					name = id,
					isStatic = flag,
					width = width,
					column = x
				});
				x++;
				if (!(flag || flag2))
				{
					list.Add(new FieldInfo
					{
						id = id,
						name = id + "_EN",
						isStatic = true,
						width = width,
						column = x
					});
					x++;
					list.Add(new FieldInfo
					{
						id = id + "_JP",
						name = id + "_JP",
						isStatic = true,
						width = width,
						column = x
					});
					x++;
				}
			}
		}
	}

	public virtual T GetRow(string id)
	{
		return null;
	}

	public override void ExportTexts(string path, bool update = false)
	{
		Debug.Log("Exporting:" + nameSheet + " path:" + path);
		string text = nameSheet + ".xlsx";
		XSSFWorkbook xSSFWorkbook = new XSSFWorkbook();
		List<FieldInfo> fields = GetFields();
		currentSheet = xSSFWorkbook.CreateSheet(nameSheet);
		int num = 0;
		int y = 0;
		foreach (FieldInfo item in fields)
		{
			GetCell(num, y).SetCellValue(item.name);
			currentSheet.SetColumnWidth(num, item.width);
			ICellStyle cellStyle = xSSFWorkbook.CreateCellStyle();
			cellStyle.FillForegroundColor = 44;
			cellStyle.FillPattern = FillPattern.SolidForeground;
			if (!item.isStatic && item.id != "version")
			{
				GetCell(num, y).CellStyle = cellStyle;
			}
			num++;
		}
		string cellValue = BaseCore.Instance.version.GetText() ?? "";
		y = 2;
		foreach (T row4 in rows)
		{
			foreach (FieldInfo item2 in fields)
			{
				if (item2.isStatic)
				{
					GetCell(item2.column, y).SetCellValue(item2.GetValue(row4));
				}
				else if (item2.id == "version")
				{
					GetCell(item2.column, y).SetCellValue(cellValue);
				}
			}
			y++;
		}
		currentSheet.CreateFreezePane(0, 2);
		currentSheet.SetAutoFilter(new CellRangeAddress(1, 1, 0, fields.Count - 1));
		if (update)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			if (!File.Exists(path + "_temp/" + text))
			{
				return;
			}
			XSSFWorkbook xSSFWorkbook2;
			using (FileStream @is = File.Open(path + "_temp/" + text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
			{
				xSSFWorkbook2 = new XSSFWorkbook((Stream)@is);
			}
			ISheet sheetAt = xSSFWorkbook2.GetSheetAt(0);
			IRow row = sheetAt.GetRow(0);
			int num2 = 0;
			foreach (FieldInfo item3 in fields)
			{
				if (item3.isStatic)
				{
					continue;
				}
				int num3 = -1;
				for (int i = 0; i < row.LastCellNum; i++)
				{
					string stringCellValue = row.GetCell(i).StringCellValue;
					if (stringCellValue.IsEmpty())
					{
						break;
					}
					if (stringCellValue == item3.id)
					{
						num3 = i;
						break;
					}
				}
				if (num3 == -1)
				{
					continue;
				}
				dictionary.Add(item3.id, 0);
				for (y = 2; y <= sheetAt.LastRowNum; y++)
				{
					IRow row2 = sheetAt.GetRow(y);
					if (row2 == null)
					{
						if (y > 5)
						{
							break;
						}
						continue;
					}
					ICell cell = row2.GetCell(0);
					if (cell == null)
					{
						continue;
					}
					string text2 = ((cell.CellType == CellType.Numeric) ? cell.NumericCellValue.ToString() : cell.StringCellValue);
					if (text2.IsEmpty())
					{
						continue;
					}
					for (int j = 0; j <= currentSheet.LastRowNum; j++)
					{
						IRow row3 = currentSheet.GetRow(j);
						if (row3 == null)
						{
							if (j > 5)
							{
								break;
							}
							continue;
						}
						ICell cell2 = row3.GetCell(0);
						if (cell2 == null || cell2.StringCellValue != text2)
						{
							continue;
						}
						string text3 = row2.GetCell(num3)?.StringCellValue ?? "";
						if (text3.IsEmpty())
						{
							continue;
						}
						(row3.GetCell(item3.column) ?? row3.CreateCell(item3.column)).SetCellValue(text3);
						if (item3.id != "version")
						{
							ICell cell3 = row3.GetCell(item3.column + 2);
							ICell cell4 = row2.GetCell(num3 + 2);
							if (cell3 == null)
							{
								continue;
							}
							if (cell4 == null || cell3.StringCellValue != cell4.StringCellValue)
							{
								row3.GetCell(1).SetCellValue(cellValue);
							}
							num2++;
						}
						dictionary[item3.id]++;
					}
				}
			}
			Log.system = Log.system + ((num2 == 0) ? "(No Changes) " : "(Updated) ") + path + "/" + text + Environment.NewLine;
			if (num2 != 0)
			{
				foreach (KeyValuePair<string, int> item4 in dictionary)
				{
					Log.system = Log.system + item4.Key + ":" + item4.Value + "  ";
				}
				Log.system += Environment.NewLine;
			}
			Log.system += Environment.NewLine;
		}
		if (!Directory.Exists(path))
		{
			Directory.CreateDirectory(path);
		}
		using FileStream stream = new FileStream(path + "/" + text, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
		xSSFWorkbook.Write(stream);
	}

	public override void ValidateLang()
	{
		string langImportMod = CorePath.CorePackage.LangImportMod;
		string text = nameSheet + ".xlsx";
		Log.system = Log.system + langImportMod + text + Environment.NewLine;
		Log.system += Environment.NewLine;
	}

	public override void ImportTexts(string _nameSheet = null)
	{
		string langImportMod = CorePath.CorePackage.LangImportMod;
		string text = _nameSheet.IsEmpty(nameSheet) + ".xlsx";
		if (!File.Exists(langImportMod + text))
		{
			return;
		}
		XSSFWorkbook xSSFWorkbook;
		using (FileStream @is = File.Open(langImportMod + text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
		{
			xSSFWorkbook = new XSSFWorkbook((Stream)@is);
		}
		ISheet sheetAt = xSSFWorkbook.GetSheetAt(0);
		List<FieldInfo> fields = GetFields();
		IRow row = sheetAt.GetRow(0);
		List<FieldMap> list = new List<FieldMap>();
		foreach (FieldInfo item in fields)
		{
			if (item.isStatic)
			{
				continue;
			}
			for (int i = 0; i < row.LastCellNum; i++)
			{
				string stringCellValue = row.GetCell(i).StringCellValue;
				if (stringCellValue.IsEmpty())
				{
					break;
				}
				if (stringCellValue == item.id)
				{
					list.Add(new FieldMap
					{
						field = item,
						column = i
					});
					break;
				}
			}
		}
		for (int j = 2; j <= sheetAt.LastRowNum; j++)
		{
			IRow row2 = sheetAt.GetRow(j);
			T val = GetRow(row2.GetCell(0).StringCellValue);
			if (val == null)
			{
				Debug.Log(sheetAt.SheetName + ": id to import no longer exist: " + row2.GetCell(0).StringCellValue);
				break;
			}
			foreach (FieldMap item2 in list)
			{
				FieldInfo field = item2.field;
				System.Reflection.FieldInfo field2 = val.GetType().GetField(field.id + "_L");
				if (field2 == null)
				{
					continue;
				}
				if (typeof(string[]).IsAssignableFrom(field2.FieldType))
				{
					ICell cell = row2.GetCell(item2.column);
					string[] array = ((cell == null) ? new string[0] : cell.StringCellValue.Split(','));
					string[] field3 = val.GetField<string[]>(field.id);
					if (field3 != null)
					{
						field2.SetValue(val, (array.Length >= field3.Length) ? array : field3);
					}
				}
				else
				{
					ICell cell2 = row2.GetCell(item2.column);
					if (cell2 != null)
					{
						field2.SetValue(val, cell2.StringCellValue.IsEmpty(val.GetField<string>(field.id)));
					}
				}
			}
		}
	}

	public static ICell GetCell(int x, int y)
	{
		IRow row = currentSheet.GetRow(y) ?? currentSheet.CreateRow(y);
		return row.GetCell(x) ?? row.CreateCell(x);
	}
}
public class SourceData : ScriptableObject
{
	public enum AutoID
	{
		None,
		Auto
	}

	[Serializable]
	public class BaseRow
	{
		public int _index;

		public virtual bool UseAlias => false;

		public virtual string GetAlias => "";

		public virtual string GetName()
		{
			return GetText();
		}

		public string GetDetail()
		{
			return GetText("detail");
		}

		public virtual string GetEditorListName()
		{
			return this.GetField<int>("id") + "-" + this.GetField<string>("alias") + "(" + this.GetField<string>("name_JP") + ")";
		}

		public string GetText(string id = "name", bool returnNull = false)
		{
			FieldInfo field = GetType().GetField(id + LangSuffix);
			if (!Lang.isBuiltin && (field == null || (field.GetValue(this) as string).IsEmpty()))
			{
				FieldInfo field2 = GetType().GetField(id);
				if (field2 != null && !(field2.GetValue(this) as string).IsEmpty())
				{
					return field2.GetValue(this) as string;
				}
			}
			if (field != null)
			{
				return (field.GetValue(this) as string).IsEmpty(returnNull ? null : "");
			}
			return "";
		}

		public string[] GetTextArray(string id)
		{
			if (!Lang.isBuiltin)
			{
				FieldInfo field = GetType().GetField(id + Lang.suffix);
				if (field != null && field.GetValue(this) is string[] array && array.Length != 0)
				{
					return array;
				}
				return GetType().GetField(id).GetValue(this) as string[];
			}
			return GetType().GetField(id + Lang.suffix).GetValue(this) as string[];
		}

		public virtual void SetID(ref int count)
		{
			this.SetField("id", count);
			count++;
		}

		public virtual void OnImportData(SourceData data)
		{
		}
	}

	public static string LangSuffix;

	public static string dataPath;

	public AutoID autoID;

	public bool isNew = true;

	public string nameSheet;

	public string nameBook;

	public virtual string sheetName => "";

	public virtual string sourcePath => "";

	public static IRow row
	{
		get
		{
			return ExcelParser.row;
		}
		set
		{
			ExcelParser.row = value;
		}
	}

	public static IRow rowDefault
	{
		get
		{
			return ExcelParser.rowDefault;
		}
		set
		{
			ExcelParser.rowDefault = value;
		}
	}

	public void BuildFlags(string rawText, Dictionary<string, bool> map)
	{
		if (!string.IsNullOrEmpty(rawText))
		{
			string[] array = rawText.Split(',');
			foreach (string key in array)
			{
				map.Add(key, value: true);
			}
		}
	}

	public virtual void Reset()
	{
	}

	public virtual void InsertData(IRow row)
	{
	}

	public virtual void Init()
	{
	}

	public virtual string[] GetList(string id)
	{
		return null;
	}

	public virtual bool ImportData(ISheet sheet, string bookname, bool overwrite = false)
	{
		return false;
	}

	public virtual void BackupSource()
	{
	}

	public virtual void RollbackSource()
	{
	}

	public virtual void BackupPref()
	{
	}

	public virtual void RestorePref()
	{
	}

	public virtual void ValidatePref()
	{
	}

	public virtual void ExportTexts(string path, bool update = false)
	{
	}

	public virtual void ImportTexts(string _nameSheet = null)
	{
	}

	public virtual void ValidateLang()
	{
	}

	public static bool IsNull(ICell cell)
	{
		if (cell != null && cell.CellType != CellType.Blank)
		{
			return cell.CellType == CellType.Unknown;
		}
		return true;
	}

	public static int GetInt(int id)
	{
		return ExcelParser.GetInt(id);
	}

	public static bool GetBool(int id)
	{
		return ExcelParser.GetBool(id);
	}

	public static double GetDouble(int id)
	{
		return ExcelParser.GetDouble(id);
	}

	public static float GetFloat(int id)
	{
		return ExcelParser.GetFloat(id);
	}

	public static float[] GetFloatArray(int id)
	{
		return ExcelParser.GetFloatArray(id);
	}

	public static int[] GetIntArray(int id)
	{
		return ExcelParser.GetIntArray(id);
	}

	public static string[] GetStringArray(int id)
	{
		return ExcelParser.GetStringArray(id);
	}

	public static string GetString(int id)
	{
		return ExcelParser.GetString(id);
	}

	public static string GetStr(int id, bool useDefault = false)
	{
		return ExcelParser.GetStr(id, useDefault);
	}
}

+SourceDataInt

File Created
cs
public class SourceDataInt<T> : SourceData<T, int> where T : SourceData.BaseRow
{
	public override T GetRow(string id)
	{
		return map.TryGetValue(id.ToInt());
	}
}

+SourceDataString

File Created
cs
public class SourceDataString<T> : SourceData<T, string> where T : SourceData.BaseRow
{
	public override T GetRow(string id)
	{
		return map.TryGetValue(id);
	}
}

+SourceLang

File Created
cs
using System.Text;

public class SourceLang<T> : SourceData<T, string> where T : LangRow
{
	public override T GetRow(string id)
	{
		return map.TryGetValue(id);
	}

	public string Get(string id)
	{
		T val = map.TryGetValue(id);
		if (val == null)
		{
			return id;
		}
		if (!Lang.isBuiltin)
		{
			if (val.text_L.IsEmpty() && !val.text.IsEmpty())
			{
				return val.text;
			}
			return val.text_L;
		}
		if (!Lang.isJP)
		{
			return val.text;
		}
		return val.text_JP;
	}

	public string TryGetId(string id, string id2)
	{
		if (map.TryGetValue(id) == null)
		{
			return id2;
		}
		return id;
	}

	public string Parse(string idLang, string val1, string val2 = null, string val3 = null, string val4 = null)
	{
		StringBuilder stringBuilder = new StringBuilder(Get(idLang));
		stringBuilder.Replace("#1", val1 ?? "");
		if (val2 != null)
		{
			stringBuilder.Replace("#2", val2);
		}
		if (val3 != null)
		{
			stringBuilder.Replace("#3", val3);
		}
		if (val4 != null)
		{
			stringBuilder.Replace("#4", val4);
		}
		return stringBuilder.ToString();
	}
}

+SpriteAnimation

File Created
cs
using System;
using UnityEngine;

[RequireComponent(typeof(SpriteRenderer))]
public class SpriteAnimation : MonoBehaviour
{
	[Serializable]
	public class Item
	{
		public Sprite sprite;

		public Vector3 pos;

		public float angle;

		public float angleRange;
	}

	public Item[] items;

	public float minInterval;

	public float maxInterval;

	public bool randomAngle;

	public Transform link;

	private SpriteRenderer sr;

	private int index;

	private float _baseAngle;

	private float interval;

	private void Awake()
	{
		sr = GetComponent<SpriteRenderer>();
		sr.sprite = items[0].sprite;
		interval = UnityEngine.Random.Range(minInterval, maxInterval);
		if (randomAngle)
		{
			_baseAngle = UnityEngine.Random.Range(0, 360);
		}
		InvokeRepeating("Refresh", 0f, interval);
	}

	private void Refresh()
	{
		index++;
		if (index >= items.Length)
		{
			index = 0;
		}
		Item item = items[index];
		sr.sprite = item.sprite;
		if ((bool)link)
		{
			link.localPosition = item.pos;
			link.localEulerAngles = new Vector3(0f, 0f, _baseAngle + item.angle + UnityEngine.Random.Range(0f - item.angleRange, item.angleRange));
		}
	}
}

+SpriteData

File Created
cs
using System;
using System.Globalization;
using System.IO;
using System.Text;
using IniParser;
using IniParser.Model;
using UnityEngine;

public class SpriteData
{
	public DateTime date;

	public Texture2D tex;

	public Texture2D texSnow;

	public string path;

	public string texName;

	public Sprite[] sprites;

	public Sprite[] spritesSnow;

	public int frame = 1;

	public int scale = 50;

	public float time = 0.2f;

	public void Init()
	{
		try
		{
			if (File.Exists(path + ".ini"))
			{
				IniData iniData = new FileIniDataParser().ReadFile(path + ".ini", Encoding.UTF8);
				frame = int.Parse(iniData.GetKey("frame") ?? "1");
				scale = int.Parse(iniData.GetKey("scale") ?? "50");
				time = float.Parse(iniData.GetKey("time") ?? "0.2", CultureInfo.InvariantCulture);
			}
		}
		catch (Exception message)
		{
			Debug.Log(message);
			Debug.Log("exception: Failed to parse:" + path + ".ini");
			time = 0.2f;
			scale = 50;
		}
	}

	public Sprite[] GetSprites()
	{
		Validate();
		return sprites;
	}

	public Sprite GetSprite(bool snow = false)
	{
		Validate();
		if (!snow || spritesSnow == null)
		{
			return sprites[0];
		}
		return spritesSnow[0];
	}

	public void Validate()
	{
		DateTime lastWriteTime = File.GetLastWriteTime(path + ".png");
		bool flag = date.Year != 1 && date == lastWriteTime;
		if (!flag)
		{
			Load(flag, ref tex, ref sprites, "");
			if (File.Exists(path + "_snow.png"))
			{
				Load(flag, ref texSnow, ref spritesSnow, "_snow");
			}
			date = lastWriteTime;
		}
	}

	public void Load(bool dateMatched, ref Texture2D tex, ref Sprite[] sprites, string suffix)
	{
		if (dateMatched && (bool)tex)
		{
			return;
		}
		if ((bool)tex)
		{
			Texture2D texture2D = IO.LoadPNG(path + suffix + ".png");
			if (texture2D.width != tex.width || texture2D.height != tex.height)
			{
				Debug.Log(texture2D.width + "/" + texture2D.height + "/" + path);
				tex.Reinitialize(texture2D.width, texture2D.height);
			}
			tex.SetPixels32(texture2D.GetPixels32());
			tex.Apply();
			UnityEngine.Object.Destroy(texture2D);
		}
		else
		{
			tex = IO.LoadPNG(path + suffix + ".png");
			int num = tex.width / frame;
			int height = tex.height;
			sprites = new Sprite[frame];
			for (int i = 0; i < frame; i++)
			{
				sprites[i] = Sprite.Create(tex, new Rect(i * num, 0f, num, height), new Vector2(0.5f, 0.5f), 100f, 0u, SpriteMeshType.FullRect);
			}
		}
	}
}

+SpriteLoadOption

File Created
cs
using UnityEngine;

public class SpriteLoadOption
{
	public Vector2 pivot = new Vector2(0.5f, 0.5f);

	public bool bilinear;
}

+SpriteReplacer

File Created
cs
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class SpriteReplacer
{
	public static Dictionary<string, string> dictModItems = new Dictionary<string, string>();

	public bool hasChacked;

	public SpriteData data;

	public bool HasSprite(string id)
	{
		if (!hasChacked)
		{
			try
			{
				string text = CorePath.packageCore + "Texture/Item/" + id;
				if (dictModItems.ContainsKey(id))
				{
					Debug.Log(id + ":" + dictModItems[id]);
					data = new SpriteData
					{
						path = dictModItems[id]
					};
					data.Init();
				}
				else if (File.Exists(text + ".png"))
				{
					data = new SpriteData
					{
						path = text
					};
					data.Init();
				}
				hasChacked = true;
			}
			catch (Exception ex)
			{
				Debug.Log("Error during fetching spirte:" + ex);
			}
		}
		return data != null;
	}
}

+SpriteReplacerAnimation

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;

public class SpriteReplacerAnimation : MonoBehaviour
{
	public enum Type
	{
		Default,
		Boat
	}

	public static Dictionary<string, SpriteData> dict = new Dictionary<string, SpriteData>();

	public Type type;

	public string id;

	public SpriteData data;

	[NonSerialized]
	public SpriteRenderer sr;

	private int index;

	private void Awake()
	{
		if (!id.IsEmpty())
		{
			SetData(id);
		}
	}

	public void SetData(string id)
	{
		this.id = id;
		string text = id.IsEmpty(base.name + "_anime");
		string path = CorePath.packageCore + "Texture/Item/" + text;
		data = dict.TryGetValue(text);
		if (data == null)
		{
			data = new SpriteData
			{
				path = path
			};
			data.Init();
			dict.Add(text, data);
		}
		sr = GetComponent<SpriteRenderer>();
		sr.sprite = data.GetSprite();
		if (type == Type.Default)
		{
			CancelInvoke();
			InvokeRepeating("Refresh", 0f, data.time);
		}
	}

	private void Refresh()
	{
		index++;
		if (index >= data.frame)
		{
			index = 0;
		}
		sr.sprite = data.GetSprites()[index];
	}
}

+SpriteSheet

File Created
cs
using System.Collections.Generic;
using UnityEngine;

public class SpriteSheet : MonoBehaviour
{
	public static Dictionary<string, Sprite> dict = new Dictionary<string, Sprite>();

	public static HashSet<string> loadedPath = new HashSet<string>();

	public static void Add(Sprite sprite)
	{
		dict[sprite.name] = sprite;
	}

	public static void Add(string path)
	{
		if (!loadedPath.Contains(path))
		{
			Sprite[] array = Resources.LoadAll<Sprite>(path);
			foreach (Sprite sprite in array)
			{
				dict[sprite.name] = sprite;
			}
			loadedPath.Add(path);
		}
	}

	public static Sprite Get(string id)
	{
		return dict.TryGetValue(id);
	}

	public static Sprite Get(string path, string id)
	{
		if (!loadedPath.Contains(path))
		{
			Add(path);
		}
		dict.TryGetValue(id, out var value);
		return value;
	}
}

+TableData

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;

public class TableData : ScriptableObject
{
	[Serializable]
	public class Col
	{
		public List<string> rows = new List<string>();
	}

	public List<Col> cols;

	public List<string> index;

	public Dictionary<string, List<string>> map = new Dictionary<string, List<string>>();

	public void Init()
	{
		for (int i = 0; i < index.Count; i++)
		{
			map.Add(index[i], cols[i].rows);
		}
	}
}

+TalkDataList

File Created
cs
using System;
using System.Collections.Generic;
using UnityEngine;

public class TalkDataList : ExcelDataList
{
	public List<string> IDs;

	public override int StartIndex => 2;

	public override void OnInitialize()
	{
		IDs = new List<string>();
		foreach (string key in list[0].Keys)
		{
			if (key != "id" && key != "path")
			{
				IDs.Add(key);
			}
		}
	}

	public string GetTalk(string id, string idTopic, bool useDefault = false, bool human = true)
	{
		if (!initialized)
		{
			Initialize();
		}
		bool flag = false;
		Dictionary<string, string> dictionary = all.TryGetValue(idTopic);
		if (dictionary == null)
		{
			Debug.LogError("idTopic not found:" + idTopic);
			return "";
		}
		string text = dictionary.TryGetValue(id);
		if (text.IsEmpty())
		{
			if (!useDefault)
			{
				Debug.LogError("id not found:" + id);
				return "";
			}
			text = dictionary.TryGetValue("default");
			flag = true;
		}
		text = text.Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None).RandomItem();
		if (!human)
		{
			if (flag && !text.IsEmpty() && !text.StartsWith("(") && !text.StartsWith("*"))
			{
				text = "(" + text + ")";
			}
			text = text.Replace("。)", ")");
		}
		return text;
	}

	public string GetRandomID(string tag)
	{
		return IDs.RandomItem();
	}
}

+TextConv

File Created
cs
using System.Collections.Generic;
using System.Text;
using NPOI.SS.UserModel;
using UnityEngine;

public class TextConv : ExcelData
{
	public class Item
	{
		public static string[] DefaultSuffix = "、,。,!,?,…,ー".Split(',');

		public string[] strs;

		public string[] suffix;

		public string[] keys;

		public int probab;

		public int gender;

		public bool additive;

		public Item(IRow row, string c0, string c1, string c2, int c4)
		{
			ICell cell = row.GetCell(3);
			keys = c0.Split(',');
			strs = c1.Split(',');
			if (cell == null)
			{
				suffix = DefaultSuffix;
			}
			else
			{
				string text = cell.ToString();
				if (text == "*")
				{
					suffix = null;
				}
				else
				{
					suffix = text.Split(',');
				}
			}
			probab = c4;
			additive = ExcelParser.GetBool(5, row);
			gender = ((c2 == "F") ? 1 : ((c2 == "M") ? 2 : 0));
		}
	}

	public string[] I_M;

	public string[] I_F;

	public string[] you_M;

	public string[] you_F;

	public string[] tags;

	public int p_I_M;

	public int p_I_F;

	public int p_you_M;

	public int p_you_F;

	public List<Item> items = new List<Item>();

	public StringBuilder Apply(ref string text, int gender)
	{
		BuildMap(null);
		StringBuilder stringBuilder = new StringBuilder();
		string text2 = null;
		Item item = null;
		int num = 0;
		if (gender == 0)
		{
			gender = ((Rand.rnd(3) != 0) ? 1 : 2);
		}
		while (num < text.Length)
		{
			bool flag = false;
			foreach (Item item2 in items)
			{
				if ((item2.probab != 0 && Rand.Range(0, 100) >= item2.probab) || (item2.gender != 0 && gender != item2.gender))
				{
					continue;
				}
				string[] keys = item2.keys;
				foreach (string text3 in keys)
				{
					flag = true;
					for (int j = 0; j < text3.Length; j++)
					{
						if (num + j >= text.Length || text[num + j] != text3[j])
						{
							flag = false;
							break;
						}
					}
					if (flag && item2.suffix != null)
					{
						flag = false;
						if (num + text3.Length >= text.Length)
						{
							continue;
						}
						string[] suffix = item2.suffix;
						foreach (string text4 in suffix)
						{
							if (text[num + text3.Length] == text4[0])
							{
								flag = true;
								break;
							}
						}
					}
					if (flag)
					{
						item = item2;
						text2 = text3;
						break;
					}
				}
				if (flag)
				{
					break;
				}
			}
			if (flag && text2.Length > 0)
			{
				stringBuilder.Append((item.additive ? text2 : "") + item.strs[Rand.Range(0, item.strs.Length)]);
				num += text2.Length;
			}
			else
			{
				stringBuilder.Append(text[num]);
				num++;
			}
		}
		stringBuilder.Replace("…ー", "ー…");
		return stringBuilder;
	}

	public override void BuildMap(string sheetName = null)
	{
		LoadBook();
		ISheet sheetAt = book.GetSheetAt(0);
		if (sheetAt.LastRowNum <= 3)
		{
			return;
		}
		for (int i = 3; i <= sheetAt.LastRowNum; i++)
		{
			IRow row = sheetAt.GetRow(i);
			if (row.Cells.Count == 0)
			{
				Debug.LogWarning(path + "/" + book?.ToString() + "/" + sheetName + "/" + sheetAt.LastRowNum + "/" + i);
				continue;
			}
			string text = row.GetCell(0).ToString();
			if (text.IsEmpty())
			{
				Debug.LogWarning(path + "/" + book?.ToString() + "/" + sheetName + "/" + sheetAt.LastRowNum + "/" + i);
				continue;
			}
			string text2 = row.GetCell(1).ToString();
			string text3 = row.GetCell(2)?.ToString() ?? "";
			int @int = ExcelParser.GetInt(4, row);
			if (text[0] == '$')
			{
				switch (text + "_" + text3)
				{
				case "$I_":
					I_M = (I_F = text2.Split(','));
					p_I_M = (p_I_F = @int);
					break;
				case "$you_":
					you_M = (you_F = text2.Split(','));
					p_you_M = (p_you_F = @int);
					break;
				case "$I_M":
					I_M = text2.Split(',');
					p_I_M = @int;
					break;
				case "$you_M":
					you_M = text2.Split(',');
					p_you_M = @int;
					break;
				case "$I_F":
					I_F = text2.Split(',');
					p_I_F = @int;
					break;
				case "$you_F":
					you_F = text2.Split(',');
					p_you_F = @int;
					break;
				case "$tag":
					tags = text2.Split(',');
					break;
				}
			}
			items.Add(new Item(row, text, text2, text3, @int));
		}
	}
}

+TextData

File Created
cs
using UnityEngine;

public class TextData : Object
{
	public string[] lines;
}

+TextureImportSetting

File Created
cs
using System;
using UnityEngine;

public class TextureImportSetting : MonoBehaviour
{
	[Serializable]
	public class Data
	{
		public TextureFormat format = TextureFormat.ARGB32;

		public TextureWrapMode wrapMode;

		public FilterMode filterMode;

		public bool linear;

		public bool mipmap;

		public bool alphaIsTransparency = true;

		public bool fixTranparency;

		public int anisoLevel;

		public int mipmapBias;
	}

	public static TextureImportSetting Instance;

	public Data data;

	private void Awake()
	{
		Instance = this;
	}
}

+ToneDataList

File Created
cs
using System;
using System.Collections.Generic;
using System.Text;

public class ToneDataList : ExcelDataList
{
	public override void OnInitialize()
	{
	}

	public StringBuilder ApplyTone(string id, ref string text, int gender)
	{
		if (!initialized)
		{
			Initialize();
		}
		Dictionary<string, string> dictionary = all[id];
		StringBuilder stringBuilder = new StringBuilder();
		bool flag = false;
		string text2 = "";
		for (int i = 0; i < text.Length; i++)
		{
			if (flag)
			{
				if (text[i] == '}')
				{
					flag = false;
					if (dictionary.ContainsKey(text2))
					{
						string text3 = dictionary[text2].Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None).TryGet((gender != 2) ? 1 : 0, 0);
						stringBuilder.Append(text3.Split(',').RandomItem());
					}
					else
					{
						stringBuilder.Append(text2);
					}
				}
				else
				{
					text2 += text[i];
				}
			}
			else if (text[i] == '{')
			{
				text2 = "";
				flag = true;
			}
			else
			{
				stringBuilder.Append(text[i]);
			}
		}
		stringBuilder.Replace("…~", "~…");
		stringBuilder.Replace("…ー", "ー…");
		return stringBuilder;
	}

	public string GetToneID(string id, int gender)
	{
		if (!initialized)
		{
			Initialize();
		}
		if (!Lang.isJP)
		{
			return id + "|I|YOU";
		}
		Dictionary<string, string> dictionary = all[id];
		string text = dictionary["I"].Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None).TryGet((gender != 2) ? 1 : 0, 0);
		string text2 = dictionary["YOU"].Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None).TryGet((gender != 2) ? 1 : 0, 0);
		string[] array = text.Split(',');
		string[] array2 = text2.Split(',');
		return id + "|" + array[rnd(rnd(array.Length) + 1)] + "|" + array2[rnd(rnd(array2.Length) + 1)];
		static int rnd(int a)
		{
			return Rand.rnd(a);
		}
	}
}

+UD_Int_String

File Created
cs
using System;

[Serializable]
public class UD_Int_String : UDictionary<int, string>
{
}

+UD_String_Color

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class UD_String_Color : UDictionary<string, Color>
{
}

+UD_String_Curve

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class UD_String_Curve : UDictionary<string, AnimationCurve>
{
}

+UD_String_Gradient

File Created
cs
using System;
using UnityEngine;

[Serializable]
public class UD_String_Gradient : UDictionary<string, Gradient>
{
}

+UD_String_LightData

File Created
cs
using System;

[Serializable]
public class UD_String_LightData : UDictionary<string, LightData>
{
}

+UD_String_MatData

File Created
cs
using System;

[Serializable]
public class UD_String_MatData : UDictionary<string, MatColors>
{
}

+UD_String_PaintPosition

File Created
cs
using System;

[Serializable]
public class UD_String_PaintPosition : UDictionary<string, PaintPosition>
{
}

+UD_String_String

File Created
cs
using System;

[Serializable]
public class UD_String_String : UDictionary<string, string>
{
}

+UDictionary

File Created
cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using UnityEngine;

[Serializable]
[ComVisible(false)]
[DebuggerDisplay("Count = {Count}")]
public class UDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, ICollection, ISerializable, IDeserializationCallback, ISerializationCallbackReceiver
{
	[SerializeField]
	private List<TKey> keys = new List<TKey>();

	[SerializeField]
	private List<TValue> values = new List<TValue>();

	[NonSerialized]
	private Dictionary<TKey, TValue> dictionary;

	public bool IsFixedSize => false;

	public ICollection<TKey> Keys => dictionary.Keys;

	ICollection IDictionary.Keys => dictionary.Keys;

	public ICollection<TValue> Values => dictionary.Values;

	ICollection IDictionary.Values => dictionary.Values;

	public TValue this[TKey key]
	{
		get
		{
			return dictionary[key];
		}
		set
		{
			dictionary[key] = value;
		}
	}

	object IDictionary.this[object key]
	{
		get
		{
			if (!(key is TKey))
			{
				return null;
			}
			return dictionary[(TKey)key];
		}
		set
		{
			if (key is TKey && (value is TValue || value == null))
			{
				dictionary[(TKey)key] = (TValue)value;
			}
		}
	}

	public int Count => dictionary.Count;

	public bool IsReadOnly => false;

	public bool IsSynchronized => false;

	public object SyncRoot => null;

	public UDictionary()
	{
		dictionary = new Dictionary<TKey, TValue>();
	}

	public UDictionary(IEqualityComparer<TKey> comparer)
	{
		dictionary = new Dictionary<TKey, TValue>(comparer);
	}

	public UDictionary(IDictionary<TKey, TValue> dictionary)
	{
		this.dictionary = new Dictionary<TKey, TValue>(dictionary);
	}

	public UDictionary(int capacity)
	{
		dictionary = new Dictionary<TKey, TValue>(capacity);
	}

	public UDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
	{
		this.dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
	}

	public UDictionary(int capacity, IEqualityComparer<TKey> comparer)
	{
		dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
	}

	public void OnAfterDeserialize()
	{
		dictionary.Clear();
		for (int i = 0; i < keys.Count; i++)
		{
			if (keys[i] != null && (!(keys[i] is UnityEngine.Object) || (bool)(UnityEngine.Object)(object)keys[i]))
			{
				dictionary.Add(keys[i], values[i]);
			}
		}
	}

	public void OnBeforeSerialize()
	{
		keys.Clear();
		values.Clear();
		foreach (KeyValuePair<TKey, TValue> item in dictionary)
		{
			if (item.Key != null && (!(item.Key is UnityEngine.Object) || (bool)(UnityEngine.Object)(object)item.Key))
			{
				keys.Add(item.Key);
				values.Add(item.Value);
			}
		}
	}

	public void GetObjectData(SerializationInfo info, StreamingContext context)
	{
		dictionary.GetObjectData(info, context);
	}

	public void OnDeserialization(object sender)
	{
		dictionary.OnDeserialization(sender);
	}

	public void Add(TKey key, TValue value)
	{
		dictionary.Add(key, value);
	}

	void IDictionary.Add(object key, object value)
	{
		if (key is TKey && (value is TValue || value == null))
		{
			dictionary.Add((TKey)key, (TValue)value);
		}
	}

	public bool ContainsKey(TKey key)
	{
		return dictionary.ContainsKey(key);
	}

	bool IDictionary.Contains(object key)
	{
		if (!(key is TKey))
		{
			return false;
		}
		return dictionary.ContainsKey((TKey)key);
	}

	public bool Remove(TKey key)
	{
		return dictionary.Remove(key);
	}

	void IDictionary.Remove(object key)
	{
		if (key is TKey)
		{
			dictionary.Remove((TKey)key);
		}
	}

	public bool TryGetValue(TKey key, out TValue value)
	{
		return dictionary.TryGetValue(key, out value);
	}

	IDictionaryEnumerator IDictionary.GetEnumerator()
	{
		return ((IDictionary)dictionary).GetEnumerator();
	}

	public void Add(KeyValuePair<TKey, TValue> item)
	{
		dictionary.Add(item.Key, item.Value);
	}

	public void Clear()
	{
		dictionary.Clear();
	}

	public bool Contains(KeyValuePair<TKey, TValue> item)
	{
		if (dictionary.ContainsKey(item.Key))
		{
			return dictionary[item.Key].Equals(item.Value);
		}
		return false;
	}

	void ICollection.CopyTo(Array array, int index)
	{
	}

	void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
	{
	}

	public bool Remove(KeyValuePair<TKey, TValue> item)
	{
		return dictionary.Remove(item.Key);
	}

	public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
	{
		return dictionary.GetEnumerator();
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return dictionary.GetEnumerator();
	}
}

+UPair

File Created
cs
using System;

[Serializable]
public class UPair<T>
{
	public string name;

	public T value;
}

+UnityEventBool

File Created
cs
using System;
using UnityEngine.Events;

[Serializable]
public class UnityEventBool : UnityEvent<bool>
{
}

+Util

File Created
cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine;

public class Util
{
	public static Color[] alphaMap;

	public static Canvas canvas;

	static Util()
	{
		alphaMap = new Color[256];
		for (int i = 0; i < 256; i++)
		{
			alphaMap[i] = new Color(1f, 1f, 1f, 1f * (float)i / 255f);
		}
	}

	public static int Distance(int pX1, int pY1, int pX2, int pY2)
	{
		return (int)Math.Sqrt((pX1 - pX2) * (pX1 - pX2) + (pY1 - pY2) * (pY1 - pY2));
	}

	public static T CopyComponent<T>(T original, GameObject destination) where T : Component
	{
		Type type = original.GetType();
		T val = destination.GetComponent(type) as T;
		if (!val)
		{
			val = destination.AddComponent(type) as T;
		}
		FieldInfo[] fields = type.GetFields();
		foreach (FieldInfo fieldInfo in fields)
		{
			if (!fieldInfo.IsStatic)
			{
				fieldInfo.SetValue(val, fieldInfo.GetValue(original));
			}
		}
		PropertyInfo[] properties = type.GetProperties();
		foreach (PropertyInfo propertyInfo in properties)
		{
			if (propertyInfo.CanWrite && propertyInfo.CanWrite && !(propertyInfo.Name == "name") && !(propertyInfo.Name == "usedByComposite") && !(propertyInfo.Name == "density"))
			{
				propertyInfo.SetValue(val, propertyInfo.GetValue(original, null), null);
			}
		}
		return val;
	}

	public static T Instantiate<T>(T t, Component parent = null) where T : Component
	{
		T val = UnityEngine.Object.Instantiate(t);
		val.transform.SetParent(parent ? parent.transform : null, worldPositionStays: false);
		if (!val.gameObject.activeSelf)
		{
			val.gameObject.SetActive(value: true);
		}
		return val;
	}

	public static Transform Instantiate(string path, Component parent = null)
	{
		return Instantiate<Transform>(path, parent);
	}

	public static T Instantiate<T>(string path, Component parent = null) where T : Component
	{
		T val = Resources.Load<T>(path);
		if (val == null)
		{
			return null;
		}
		return Instantiate(val, parent);
	}

	public static void DestroyChildren(Transform trans)
	{
		for (int num = trans.childCount - 1; num >= 0; num--)
		{
			UnityEngine.Object.Destroy(trans.GetChild(num).gameObject);
		}
	}

	public static void RebuildLayoutInParents(Component c, Component root)
	{
		Transform transform = c.transform;
		transform.RebuildLayout();
		Transform parent = transform.parent;
		if ((bool)parent && !(parent == root.transform))
		{
			RebuildLayoutInParents(parent, root);
		}
	}

	public static void SetRectToFitScreen(RectTransform rect)
	{
		rect.anchorMin = Vector2.zero;
		rect.anchorMax = Vector2.one;
		rect.localPosition = Vector3.zero;
		rect.anchoredPosition = Vector2.zero;
		rect.sizeDelta = Vector2.zero;
	}

	public static void ClampToScreen(RectTransform rect, int margin = 0)
	{
		RectTransform rectTransform = BaseCore.Instance.canvas.Rect();
		Vector3 localPosition = rect.localPosition;
		Vector3 vector = rectTransform.rect.min - rect.rect.min;
		Vector3 vector2 = rectTransform.rect.max - rect.rect.max;
		localPosition.x = Mathf.Clamp(localPosition.x, vector.x + (float)margin, vector2.x - (float)margin);
		localPosition.y = Mathf.Clamp(localPosition.y, vector.y + (float)margin, vector2.y - (float)margin);
		rect.localPosition = localPosition;
	}

	public static float GetAngle(Vector3 self, Vector3 target)
	{
		Vector3 vector = target - self;
		return Mathf.Atan2(vector.y * -1f, vector.x) * 57.29578f + 90f;
	}

	public static float GetAngle(float x, float y)
	{
		return Mathf.Atan2(0f - y, x) * 57.29578f + 90f;
	}

	public static VectorDir GetVectorDir(Vector3 normal)
	{
		if (Math.Abs(normal.y - 1f) < 0.1f)
		{
			return VectorDir.down;
		}
		if (Math.Abs(normal.x - 1f) < 0.1f)
		{
			return VectorDir.left;
		}
		if (Math.Abs(normal.x - -1f) < 0.1f)
		{
			return VectorDir.right;
		}
		if (Math.Abs(normal.z - 1f) < 0.1f)
		{
			return VectorDir.back;
		}
		if (Math.Abs(normal.z - -1f) < 0.1f)
		{
			return VectorDir.forward;
		}
		return VectorDir.up;
	}

	public static Vector2 ConvertAxis(Vector2 v)
	{
		float x = v.x;
		float y = v.y;
		if (y == 1f)
		{
			if (x == 0f)
			{
				return new Vector2(-1f, 1f);
			}
			if (x == 1f)
			{
				return new Vector2(0f, 1f);
			}
			if (x == -1f)
			{
				return new Vector2(-1f, 0f);
			}
		}
		if (y == 0f)
		{
			if (x == 0f)
			{
				return Vector2.zero;
			}
			if (x == 1f)
			{
				return new Vector2(1f, 1f);
			}
			if (x == -1f)
			{
				return new Vector2(-1f, -1f);
			}
		}
		if (y == -1f)
		{
			if (x == 0f)
			{
				return new Vector2(1f, -1f);
			}
			if (x == 1f)
			{
				return new Vector2(1f, 0f);
			}
			if (x == -1f)
			{
				return new Vector2(0f, -1f);
			}
		}
		return Vector3.zero;
	}

	public static Vector2 WorldToUIPos(Vector3 worldPoint, RectTransform container)
	{
		Vector2 localPoint = Vector2.zero;
		Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(Camera.main, worldPoint);
		RectTransformUtility.ScreenPointToLocalPointInRectangle(container, screenPoint, canvas.worldCamera, out localPoint);
		return localPoint;
	}

	public static T RandomEnum<T>()
	{
		Array values = Enum.GetValues(typeof(T));
		return (T)values.GetValue(new System.Random().Next(values.Length));
	}

	public static List<T> EnumToList<T>() where T : Enum
	{
		return Enum.GetValues(typeof(T)).Cast<T>().ToList();
	}

	public static void ShowExplorer(string itemPath, bool selectFirstFile = false)
	{
		if (selectFirstFile)
		{
			FileInfo[] files = new DirectoryInfo(itemPath).GetFiles();
			if (files.Length != 0)
			{
				itemPath = itemPath + "/" + files[0].Name;
			}
		}
		itemPath = itemPath.Replace("/", "\\");
		Process.Start("explorer.exe", "/select," + itemPath);
	}

	public static void Run(string itemPath)
	{
		Process.Start(itemPath);
	}

	public static T[,] ResizeArray<T>(T[,] original, int x, int y, Func<int, int, T> func)
	{
		T[,] array = new T[x, y];
		int num = Math.Min(x, original.GetLength(0));
		int num2 = Math.Min(y, original.GetLength(1));
		for (int i = 0; i < x; i++)
		{
			for (int j = 0; j < y; j++)
			{
				if (i >= num || j >= num2)
				{
					array[i, j] = func(i, j);
				}
				else
				{
					array[i, j] = original[i, j];
				}
			}
		}
		return array;
	}
}

+VectorDir

File Created
cs
public enum VectorDir
{
	none,
	up,
	down,
	forward,
	back,
	left,
	right
}

+Version

File Created
cs
using System;

[Serializable]
public struct Version
{
	public int major;

	public int minor;

	public int batch;

	public int fix;

	public bool demo;

	public string GetText()
	{
		return ((minor >= 23) ? "EA" : "Beta") + " " + minor + "." + batch + ((fix == 0) ? "" : (" fix " + fix)) + (demo ? "demo".lang() : "");
	}

	public int GetInt()
	{
		return major * 1000000 + minor * 1000 + batch;
	}

	public int GetInt(int _major, int _minor, int _batch)
	{
		return _major * 1000000 + _minor * 1000 + _batch;
	}

	public bool IsBelow(int _major, int _minor, int _batch)
	{
		return GetInt() < GetInt(_major, _minor, _batch);
	}

	public bool IsBelow(Version v)
	{
		return IsBelow(v.GetInt());
	}

	public bool IsBelow(int _int)
	{
		return GetInt() < _int;
	}

	public static Version Get(string str)
	{
		if (str.IsEmpty())
		{
			return default(Version);
		}
		string[] array = str.Split('.');
		if (array.Length < 3)
		{
			return default(Version);
		}
		Version result = default(Version);
		result.major = array[0].ToInt();
		result.minor = array[1].ToInt();
		result.batch = array[2].ToInt();
		return result;
	}

	public static Version Get(int i)
	{
		Version result = default(Version);
		result.major = i / 1000000;
		result.minor = i / 1000 % 1000;
		result.batch = i % 1000;
		return result;
	}

	public bool IsSaveCompatible(Version v)
	{
		if (IsBelow(v))
		{
			return false;
		}
		if (major == v.major)
		{
			return minor >= 21;
		}
		return false;
	}

	public override bool Equals(object obj)
	{
		Version version = (Version)obj;
		if (version.major == major && version.minor == minor)
		{
			return version.batch == batch;
		}
		return false;
	}

	public override int GetHashCode()
	{
		return GetInt();
	}
}