Decompiled source of LCTC Thunderstore v1.3.1

BepInEx/plugins/LCTC_Terminal.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using LCTC;
using Microsoft.CodeAnalysis;
using Patchers;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LCTC_Terminal")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LCTC_Terminal")]
[assembly: AssemblyTitle("LCTC_Terminal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
internal static class Dictionaries
{
	public static readonly Dictionary<string, string> Regex = new Dictionary<string, string>();

	public static readonly Dictionary<string, string> TextPostProcess = new Dictionary<string, string>
	{
		{ "Welcome to the exomoons catalogue.", "歡迎使用星球目錄。" },
		{ "\\[There was no action supplied with the word.\\]", "[該字詞並無附帶任何動作]" },
		{ "\\[There was no object supplied with the action, or your word was typed incorrectly or does not exist.\\]", "[該動作未傳入任何參數,或是你輸入的字詞有誤,或是該字詞不存在]" },
		{ "To route the autopilot to a moon, use the word ROUTE.", "要將自動駕駛導航至星球,請輸入「ROUTE」。" },
		{ "To learn about any moon, use the word INFO.", "要查看任意星球資訊,請輸入「INFO」。" },
		{ "Buying at", "公司收購價格:" },
		{ "Other commands:\n\n", "其他指令:\n\n" },
		{ "To toggle on AND off the main monitor's map cam\n\n", "開啟/關閉主監視器的地圖攝影機\n\n" },
		{ ">SWITCH [Player name\\]", ">SWITCH [玩家名稱]" },
		{ "To switch view to a player on the main monitor\n\n", "將主監視器畫面切換至指定玩家\n\n" },
		{ ">PING [Radar booster name\\]", ">PING [雷達增幅器名稱]" },
		{ "To make a radar booster play a noise.\n\n", "讓雷達增幅器發出聲音\n\n" },
		{ ">TRANSMIT [message\\]", ">TRANSMIT [訊息]" },
		{ "To transmit a message with the signal translator\n\n", "透過訊號轉換器傳送訊息\n\n" },
		{ "To scan for the number of items left on the current planet.", "掃描目前星球上剩餘物品數量。\n\n>FLASH [雷達增幅器名稱]\n啟用雷達增幅器閃光。\n\n>EJECT\n緊急彈射。" },
		{ "Routing autopilot to (.+?)\nYour new balance is [playerCredits\\].\n\nPlease enjoy your flight.\n\n", "正在將自動駕駛設定至 $1\n你的新餘額為 [playerCredits]\n\n祝你旅途愉快。\n\n" },
		{ "Routing autopilot to (.+?)\nYour new balance is [playerCredits\\].\n\nGood luck.\n\n", "正在將自動駕駛設定至 $1\n你的新餘額為 [playerCredits]\n\n祝你好運。\n\n" },
		{ "The cost to route to (.+?) is (.+?). It is \ncurrently (.+?) on this moon.\n\nPlease CONFIRM or DENY.\n\n\n", "前往 $1 的費用為 $2。\n目前該星球狀態為 $3。\n\n請輸入「CONFIRM」或「DENY」。\n\n" },
		{ "You could not afford these items!", "你無法負擔這些物品!" },
		{ "Your balance is (\\$[0-9]+). Total cost of these items is (\\$[0-9]+).", "你的餘額為 $1,這些物品的總價格為 $2。" },
		{ "\\[No items stored. While moving an object with B, press X to store it.\\]", "[目前沒有儲存物品。使用 B 搬運物品時,按下 X 可將其存入倉庫]" },
		{ "There are ([0-9]+) objects outside the ship, totalling at an approximate value of (\\$[0-9]+).", "船外共有 $1 件物品,總價值約為 $2" },
		{ "There are ([0-9]+) objects in the ship, totalling at (\\$[0-9]+).", "船內共有 $1 件物品,總價值為 $2" },
		{ "Exception occured on terminal while setting node planet info; current node displayPlanetInfo:(.+?)", "終端設定星球資訊時發生錯誤,目前節點 displayPlanetInfo:$1" },
		{ "Unable to route the ship currently. It must be in orbit around a moon to route the autopilot.", "目前無法設定航線。必須先進入星球軌道才能使用自動駕駛。" },
		{ "Use the main lever at the front desk to enter orbit.", "請使用前方控制台的主操縱桿進入軌道。" },
		{ "To learn about any moon, use INFO.", "要查看星球資訊,請輸入 INFO。" },
		{ "The ship cannot be leaving or landing!", "飛船目前無法起飛或降落!" },
		{ "\\[No items in stock!\\]", "[目前沒有庫存!]" },
		{ "\\[ALL DATA HAS BEEN CORRUPTED OR OVERWRITTEN\\]", "[所有資料已損毀或被覆寫]" },
		{ "([0-9]+) purchased items on route.", "已有 $1 件購買物品正在運送中。\n" },
		{ "The delivery vehicle cannot hold more than 12 items\nat a time. Please pick up your items when they land!", "運輸載具一次最多只能運送 12 件物品。\n請在物品送達後儘快領取!" },
		{ "[No items available\\]", "[沒有可用物品]" },
		{ "This item is not in stock!", "此物品目前缺貨!" },
		{ "No data collected on wildlife. Scans are required.", "尚未收集任何野生生物資料,請先進行掃描。" },
		{ "No data has been collected on this creature.", "尚未收集此生物的資料。" },
		{ "A scan is required.", "需要進行掃描。" },
		{ "([0-9]+)% OFF!", "$1% 折扣!" },
		{ "\\(Locked\\)", "(鎖定)" },
		{ "\\(NEW\\)", "(新)" },
		{ "Price:", "價格:" },
		{ "mild weather", "溫和天氣" },
		{ "DustClouds", "塵雲" },
		{ "Rainy", "雨天" },
		{ "Stormy", "暴風" },
		{ "Foggy", "濃霧" },
		{ "Flooded", "淹水" },
		{ "Eclipsed", "日蝕" },
		{ "dustclouds", "塵雲" },
		{ "rainy", "雨天" },
		{ "stormy", "暴風" },
		{ "foggy", "濃霧" },
		{ "flooded", "淹水" },
		{ "eclipsed", "日蝕" },
		{ "Please CONFIRM or DENY.", "請輸入「CONFIRM」或「DENY」。" }
	};

	public static readonly Dictionary<string, string> Chat = new Dictionary<string, string>
	{
		{ "(.*) joined the ship\\.", "$1 已加入飛船。" },
		{ "(.*) started the ship\\.", "$1 已啟動飛船。" },
		{ "(.*) was left behind\\.", "$1 被留在外面。" },
		{ "(.*) disconnected\\.", "$1 已離線。" },
		{ "(.*) was kicked\\.", "$1 已被踢出。" }
	};

	public static readonly Dictionary<string, string> Notes = new Dictionary<string, string>
	{
		{ "Most profitable.", "最賺錢員工。" },
		{ "Sustained the most injuries.", "受傷最多的員工。" },
		{ "The laziest employee.", "最偷懶的員工。" },
		{ "The most paranoid employee.", "最神經質的員工。" }
	};

	public static readonly Dictionary<string, string> Loading = new Dictionary<string, string>
	{
		{ "Random seed", "隨機種子" },
		{ "LOADING WORLD...", "載入世界中..." }
	};

	public static readonly Dictionary<string, string> ShipTeleporter = new Dictionary<string, string> { { "[Cooldown: (.+?) sec\\.\\]", "[冷卻時間:$1 秒]" } };

	public static readonly Dictionary<string, string> PlanetInfo = new Dictionary<string, string>
	{
		{ "A competitive ecosystem supports aggressive lifeforms.", "競爭激烈的生態系孕育出具攻擊性的生命體。" },
		{ "Arid. Thick haze, worsened by industrial artifacts.", "乾燥。濃厚霧霾,受到工業殘留影響而加劇。" },
		{ "Dangerous entities have been rumored to take residence in the vast network of tunnels.", "據傳廣大的地下隧道網絡中棲息著危險生物。" },
		{ "Dominated by a few species.", "由少數物種主導。" },
		{ "Ecosystem supports territorial behaviour.", "生態系支持強烈的領域性行為。" },
		{ "Expansive. Constant rain.", "廣闊。持續降雨。" },
		{ "Frozen, rocky. Its planet orbits a white dwarf star.", "冰冷且多岩。其所屬行星圍繞白矮星運行。" },
		{ "Humid. Rough terrain. Teeming with plant-life.", "潮濕。地形崎嶇。植物生長茂密。" },
		{ "Jagged and weathered terrain.", "崎嶇且風化嚴重的地形。" },
		{ "No land masses. Continual storms.", "無陸地。持續風暴。" },
		{ "Unlikely for complex life to exist", "不太可能存在複雜生命體" },
		{ "Where the Company resides.", "公司所在地。" },
		{ "Abandoned", "已廢棄" },
		{ "Diverse", "多樣" },
		{ "Eclipsed", "日蝕" },
		{ "Flooded", "淹水" },
		{ "Foggy", "濃霧" },
		{ "None", "無" },
		{ "Rainy", "雨天" },
		{ "Safe", "安全" },
		{ "Stormy", "暴風" },
		{ "Unknown", "未知" },
		{ "CELESTIAL BODY", "天體" },
		{ "Orbiting", "軌道運行" },
		{ "POPULATION", "人口" },
		{ "CONDITIONS", "環境" },
		{ "FAUNA", "生態" },
		{ "Weather", "天氣" }
	};

	public static readonly Dictionary<string, string> ItemNames = new Dictionary<string, string>
	{
		{ "Walkie-talkie", "$& (對講機)" },
		{ "Flashlight", "$& (手電筒)" },
		{ "Shovel", "$& (鏟子)" },
		{ "Lockpicker", "$& (開鎖器)" },
		{ "Pro-flashlight", "$& (高級手電筒)" },
		{ "Stun grenade", "$& (震撼彈)" },
		{ "Boombox", "$& (音響)" },
		{ "TZP-Inhalant", "$& (TZP 吸入劑)" },
		{ "Zap gun", "$& (電擊槍)" },
		{ "Jetpack", "$& (噴射背包)" },
		{ "Extension ladder", "$& (伸縮梯)" },
		{ "Radar-booster", "$& (雷達增幅器)" },
		{ "Spray paint", "$& (噴漆)" },
		{ "Weed killer", "$& (除草劑)" },
		{ "Belt bag", "$& (腰包)" },
		{ "Cruiser", "$& (巡航車)" }
	};
}
namespace LCTC_Terminal
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LCTC_Terminal";

		public const string PLUGIN_NAME = "LCTC_Terminal";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace NewTerminalDetected
{
	[HarmonyPatch]
	internal static class UIPatches
	{
		[HarmonyPatch]
		internal static class UniversalUIPatches
		{
			[HarmonyPostfix]
			[HarmonyPatch(typeof(PreInitSceneScript), "Start")]
			private static void OnPreInitMenuShown()
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				if (Plugin.Flags.HasFlag(Flags.NewTerminalDetected))
				{
					TextMeshProUGUI component = Object.Instantiate<GameObject>(GameObject.Find("Canvas/GameObject/LANOrOnline/OnlineButton/Text (TMP) (1)").gameObject).GetComponent<TextMeshProUGUI>();
					((TMP_Text)component).transform.parent = GameObject.Find("Canvas/GameObject").transform;
					((TMP_Text)component).transform.localPosition = new Vector3(200f, -170f, 0f);
					((TMP_Text)component).transform.localScale = Vector3.one;
					((TMP_Text)component).text = "偵測到已安裝 NewTerminal,可能與 LCTC 終端機翻譯衝突。";
					((TMP_Text)component).autoSizeTextContainer = true;
					((Graphic)component).color = new Color(0.9434f, 0.0434f, 0.0434f, 1f);
					((TMP_Text)component).alignment = (TextAlignmentOptions)514;
					((TMP_Text)component).fontSize = 18f;
					((Graphic)component).raycastTarget = false;
				}
			}
		}
	}
}
namespace Patchers
{
	internal static class ExternalTextTranslator
	{
		private sealed class RegexRule
		{
			public Regex Pattern { get; }

			public string Replacement { get; }

			public RegexRule(Regex pattern, string replacement)
			{
				Pattern = pattern;
				Replacement = replacement;
			}
		}

		[CompilerGenerated]
		private sealed class <GetBuiltInRegexRules>d__26 : IEnumerable<KeyValuePair<string, string>>, IEnumerable, IEnumerator<KeyValuePair<string, string>>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private KeyValuePair<string, string> <>2__current;

			private int <>l__initialThreadId;

			private Dictionary<string, string>.Enumerator <>s__1;

			private KeyValuePair<string, string> <item>5__2;

			private Dictionary<string, string>.Enumerator <>s__3;

			private KeyValuePair<string, string> <item>5__4;

			private Dictionary<string, string>.Enumerator <>s__5;

			private KeyValuePair<string, string> <item>5__6;

			private Dictionary<string, string>.Enumerator <>s__7;

			private KeyValuePair<string, string> <item>5__8;

			private Dictionary<string, string>.Enumerator <>s__9;

			private KeyValuePair<string, string> <item>5__10;

			private Dictionary<string, string>.Enumerator <>s__11;

			private KeyValuePair<string, string> <item>5__12;

			private Dictionary<string, string>.Enumerator <>s__13;

			private KeyValuePair<string, string> <item>5__14;

			private Dictionary<string, string>.Enumerator <>s__15;

			private KeyValuePair<string, string> <item>5__16;

			KeyValuePair<string, string> IEnumerator<KeyValuePair<string, string>>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

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

			[DebuggerHidden]
			public <GetBuiltInRegexRules>d__26(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				switch (<>1__state)
				{
				case -3:
				case 1:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 2:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				case -5:
				case 3:
					try
					{
					}
					finally
					{
						<>m__Finally3();
					}
					break;
				case -6:
				case 4:
					try
					{
					}
					finally
					{
						<>m__Finally4();
					}
					break;
				case -7:
				case 5:
					try
					{
					}
					finally
					{
						<>m__Finally5();
					}
					break;
				case -8:
				case 6:
					try
					{
					}
					finally
					{
						<>m__Finally6();
					}
					break;
				case -9:
				case 7:
					try
					{
					}
					finally
					{
						<>m__Finally7();
					}
					break;
				case -10:
				case 8:
					try
					{
					}
					finally
					{
						<>m__Finally8();
					}
					break;
				}
				<>s__1 = default(Dictionary<string, string>.Enumerator);
				<item>5__2 = default(KeyValuePair<string, string>);
				<>s__3 = default(Dictionary<string, string>.Enumerator);
				<item>5__4 = default(KeyValuePair<string, string>);
				<>s__5 = default(Dictionary<string, string>.Enumerator);
				<item>5__6 = default(KeyValuePair<string, string>);
				<>s__7 = default(Dictionary<string, string>.Enumerator);
				<item>5__8 = default(KeyValuePair<string, string>);
				<>s__9 = default(Dictionary<string, string>.Enumerator);
				<item>5__10 = default(KeyValuePair<string, string>);
				<>s__11 = default(Dictionary<string, string>.Enumerator);
				<item>5__12 = default(KeyValuePair<string, string>);
				<>s__13 = default(Dictionary<string, string>.Enumerator);
				<item>5__14 = default(KeyValuePair<string, string>);
				<>s__15 = default(Dictionary<string, string>.Enumerator);
				<item>5__16 = default(KeyValuePair<string, string>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = Dictionaries.Regex.GetEnumerator();
						<>1__state = -3;
						goto IL_0194;
					case 1:
						<>1__state = -3;
						<item>5__2 = default(KeyValuePair<string, string>);
						goto IL_0194;
					case 2:
						<>1__state = -4;
						<item>5__4 = default(KeyValuePair<string, string>);
						goto IL_0210;
					case 3:
						<>1__state = -5;
						<item>5__6 = default(KeyValuePair<string, string>);
						goto IL_028c;
					case 4:
						<>1__state = -6;
						<item>5__8 = default(KeyValuePair<string, string>);
						goto IL_0308;
					case 5:
						<>1__state = -7;
						<item>5__10 = default(KeyValuePair<string, string>);
						goto IL_0384;
					case 6:
						<>1__state = -8;
						<item>5__12 = default(KeyValuePair<string, string>);
						goto IL_0400;
					case 7:
						<>1__state = -9;
						<item>5__14 = default(KeyValuePair<string, string>);
						goto IL_047c;
					case 8:
						<>1__state = -10;
						<item>5__16 = default(KeyValuePair<string, string>);
						goto IL_04f8;
					case 9:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("loud horn", "$& (大聲喇叭)");
						<>1__state = 10;
						return true;
					case 10:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Signal Translator", "$& (訊號翻譯器)");
						<>1__state = 11;
						return true;
					case 11:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("signal translator", "$& (訊號翻譯器)");
						<>1__state = 12;
						return true;
					case 12:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Teleporter", "$& (傳送器)");
						<>1__state = 13;
						return true;
					case 13:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("teleporter", "$& (傳送器)");
						<>1__state = 14;
						return true;
					case 14:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Inverse Teleporter", "$& (反向傳送器)");
						<>1__state = 15;
						return true;
					case 15:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("inverse teleporter", "$& (反向傳送器)");
						<>1__state = 16;
						return true;
					case 16:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Monday", "祝你星期一愉快");
						<>1__state = 17;
						return true;
					case 17:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Tuesday", "祝你星期二愉快");
						<>1__state = 18;
						return true;
					case 18:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Wednesday", "祝你星期三愉快");
						<>1__state = 19;
						return true;
					case 19:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Thursday", "祝你星期四愉快");
						<>1__state = 20;
						return true;
					case 20:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Friday", "祝你星期五愉快");
						<>1__state = 21;
						return true;
					case 21:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Saturday", "祝你星期六愉快");
						<>1__state = 22;
						return true;
					case 22:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("Happy Sunday", "祝你星期日愉快");
						<>1__state = 23;
						return true;
					case 23:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bMonday\\b", "星期一");
						<>1__state = 24;
						return true;
					case 24:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bTuesday\\b", "星期二");
						<>1__state = 25;
						return true;
					case 25:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bWednesday\\b", "星期三");
						<>1__state = 26;
						return true;
					case 26:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bThursday\\b", "星期四");
						<>1__state = 27;
						return true;
					case 27:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bFriday\\b", "星期五");
						<>1__state = 28;
						return true;
					case 28:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bSaturday\\b", "星期六");
						<>1__state = 29;
						return true;
					case 29:
						<>1__state = -1;
						<>2__current = new KeyValuePair<string, string>("\\bSunday\\b", "星期日");
						<>1__state = 30;
						return true;
					case 30:
						{
							<>1__state = -1;
							return false;
						}
						IL_0194:
						if (<>s__1.MoveNext())
						{
							<item>5__2 = <>s__1.Current;
							<>2__current = <item>5__2;
							<>1__state = 1;
							return true;
						}
						<>m__Finally1();
						<>s__1 = default(Dictionary<string, string>.Enumerator);
						<>s__3 = Dictionaries.TextPostProcess.GetEnumerator();
						<>1__state = -4;
						goto IL_0210;
						IL_047c:
						if (<>s__13.MoveNext())
						{
							<item>5__14 = <>s__13.Current;
							<>2__current = <item>5__14;
							<>1__state = 7;
							return true;
						}
						<>m__Finally7();
						<>s__13 = default(Dictionary<string, string>.Enumerator);
						<>s__15 = Dictionaries.ItemNames.GetEnumerator();
						<>1__state = -10;
						goto IL_04f8;
						IL_0210:
						if (<>s__3.MoveNext())
						{
							<item>5__4 = <>s__3.Current;
							<>2__current = <item>5__4;
							<>1__state = 2;
							return true;
						}
						<>m__Finally2();
						<>s__3 = default(Dictionary<string, string>.Enumerator);
						<>s__5 = Dictionaries.Chat.GetEnumerator();
						<>1__state = -5;
						goto IL_028c;
						IL_028c:
						if (<>s__5.MoveNext())
						{
							<item>5__6 = <>s__5.Current;
							<>2__current = <item>5__6;
							<>1__state = 3;
							return true;
						}
						<>m__Finally3();
						<>s__5 = default(Dictionary<string, string>.Enumerator);
						<>s__7 = Dictionaries.Notes.GetEnumerator();
						<>1__state = -6;
						goto IL_0308;
						IL_04f8:
						if (<>s__15.MoveNext())
						{
							<item>5__16 = <>s__15.Current;
							<>2__current = <item>5__16;
							<>1__state = 8;
							return true;
						}
						<>m__Finally8();
						<>s__15 = default(Dictionary<string, string>.Enumerator);
						<>2__current = new KeyValuePair<string, string>("Loud horn", "$& (大聲喇叭)");
						<>1__state = 9;
						return true;
						IL_0308:
						if (<>s__7.MoveNext())
						{
							<item>5__8 = <>s__7.Current;
							<>2__current = <item>5__8;
							<>1__state = 4;
							return true;
						}
						<>m__Finally4();
						<>s__7 = default(Dictionary<string, string>.Enumerator);
						<>s__9 = Dictionaries.Loading.GetEnumerator();
						<>1__state = -7;
						goto IL_0384;
						IL_0400:
						if (<>s__11.MoveNext())
						{
							<item>5__12 = <>s__11.Current;
							<>2__current = <item>5__12;
							<>1__state = 6;
							return true;
						}
						<>m__Finally6();
						<>s__11 = default(Dictionary<string, string>.Enumerator);
						<>s__13 = Dictionaries.PlanetInfo.GetEnumerator();
						<>1__state = -9;
						goto IL_047c;
						IL_0384:
						if (<>s__9.MoveNext())
						{
							<item>5__10 = <>s__9.Current;
							<>2__current = <item>5__10;
							<>1__state = 5;
							return true;
						}
						<>m__Finally5();
						<>s__9 = default(Dictionary<string, string>.Enumerator);
						<>s__11 = Dictionaries.ShipTeleporter.GetEnumerator();
						<>1__state = -8;
						goto IL_0400;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				((IDisposable)<>s__3).Dispose();
			}

			private void <>m__Finally3()
			{
				<>1__state = -1;
				((IDisposable)<>s__5).Dispose();
			}

			private void <>m__Finally4()
			{
				<>1__state = -1;
				((IDisposable)<>s__7).Dispose();
			}

			private void <>m__Finally5()
			{
				<>1__state = -1;
				((IDisposable)<>s__9).Dispose();
			}

			private void <>m__Finally6()
			{
				<>1__state = -1;
				((IDisposable)<>s__11).Dispose();
			}

			private void <>m__Finally7()
			{
				<>1__state = -1;
				((IDisposable)<>s__13).Dispose();
			}

			private void <>m__Finally8()
			{
				<>1__state = -1;
				((IDisposable)<>s__15).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetBuiltInRegexRules>d__26(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<KeyValuePair<string, string>>)this).GetEnumerator();
			}
		}

		private static readonly object SyncRoot = new object();

		private static readonly Regex PlaceholderTokenRegex = new Regex("\\[[^\\]\\r\\n]+\\]", RegexOptions.Compiled);

		private static readonly Dictionary<string, string> NodeExactRules = new Dictionary<string, string>(StringComparer.Ordinal);

		private static readonly List<RegexRule> RegexRules = new List<RegexRule>();

		private static FileSystemWatcher _watcher;

		private static string _filePath;

		private static DateTime _lastWriteUtc = DateTime.MinValue;

		private static bool _initialized;

		private static volatile bool _dirty = true;

		public static void Initialize()
		{
			lock (SyncRoot)
			{
				if (!_initialized)
				{
					_filePath = Path.Combine(Paths.ConfigPath, PatchSettings.ExternalTranslationFileName ?? "LCTC.Terminal.Translations.txt");
					EnsureDefaultFile();
					AppendMissingBuiltInRegexRulesToExternalFile();
					SetupWatcher();
					ReloadRules(force: true);
					_initialized = true;
				}
			}
		}

		public static string Translate(string input, string nodeName = null)
		{
			if (string.IsNullOrEmpty(input))
			{
				return input;
			}
			Initialize();
			ReloadRules(force: false);
			string text = input;
			if (!string.IsNullOrEmpty(nodeName) && NodeExactRules.TryGetValue(nodeName, out var value))
			{
				text = AlignPlaceholderTokens(value, input);
			}
			for (int i = 0; i < RegexRules.Count; i++)
			{
				text = RegexRules[i].Pattern.Replace(text, RegexRules[i].Replacement);
			}
			return text;
		}

		public static string TranslateNodeTemplate(string templateText, string nodeName)
		{
			if (string.IsNullOrEmpty(templateText) || string.IsNullOrEmpty(nodeName))
			{
				return templateText;
			}
			if (IsDynamicHubNode(nodeName))
			{
				return templateText;
			}
			if (ContainsDynamicListToken(templateText))
			{
				return templateText;
			}
			Initialize();
			ReloadRules(force: false);
			if (NodeExactRules.TryGetValue(nodeName, out var value))
			{
				return AlignPlaceholderTokens(value, templateText);
			}
			return templateText;
		}

		public static string TranslatePostProcess(string processedText)
		{
			if (string.IsNullOrEmpty(processedText))
			{
				return processedText;
			}
			Initialize();
			ReloadRules(force: false);
			string text = processedText;
			for (int i = 0; i < RegexRules.Count; i++)
			{
				text = RegexRules[i].Pattern.Replace(text, RegexRules[i].Replacement);
			}
			return RemoveOverlappingItemTranslations(text);
		}

		private static string RemoveOverlappingItemTranslations(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			text = Regex.Replace(text, "\\b(Inverse\\s+Teleporter)\\b(\\s*\\([^)]+\\))\\s*\\([^)]+\\)", "$1$2", RegexOptions.CultureInvariant);
			text = Regex.Replace(text, "\\b(inverse\\s+teleporter)\\b(\\s*\\([^)]+\\))\\s*\\([^)]+\\)", "$1$2", RegexOptions.CultureInvariant);
			text = Regex.Replace(text, "(\\s*\\([^)]+\\))\\s*\\1+", "$1", RegexOptions.CultureInvariant);
			return text;
		}

		public static bool HasNodeRule(string nodeName)
		{
			if (string.IsNullOrEmpty(nodeName))
			{
				return false;
			}
			Initialize();
			ReloadRules(force: false);
			lock (SyncRoot)
			{
				return NodeExactRules.ContainsKey(nodeName);
			}
		}

		public static bool TryGetNodeRule(string nodeName, out string translatedNodeText)
		{
			translatedNodeText = null;
			if (string.IsNullOrEmpty(nodeName))
			{
				return false;
			}
			Initialize();
			ReloadRules(force: false);
			lock (SyncRoot)
			{
				return NodeExactRules.TryGetValue(nodeName, out translatedNodeText);
			}
		}

		public static int AppendMissingNodeRules(IEnumerable<TerminalNode> nodes)
		{
			if (nodes == null)
			{
				return 0;
			}
			Initialize();
			ReloadRules(force: false);
			List<string> list = new List<string>();
			lock (SyncRoot)
			{
				foreach (TerminalNode node in nodes)
				{
					if (!((Object)(object)node == (Object)null) && !string.IsNullOrEmpty(((Object)node).name) && !NodeExactRules.ContainsKey(((Object)node).name))
					{
						string value = node.displayText ?? string.Empty;
						string item = "NODE\t" + Escape(((Object)node).name) + "\t" + Escape(value);
						list.Add(item);
						NodeExactRules[((Object)node).name] = value;
					}
				}
			}
			if (list.Count == 0)
			{
				return 0;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("# ===== Auto-added missing NODE rules =====");
			stringBuilder.AppendLine("# Added at: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			foreach (string item2 in list)
			{
				stringBuilder.AppendLine(item2);
			}
			File.AppendAllText(_filePath, stringBuilder.ToString(), Encoding.UTF8);
			_lastWriteUtc = File.GetLastWriteTimeUtc(_filePath);
			_dirty = true;
			return list.Count;
		}

		private static void ReloadRules(bool force)
		{
			lock (SyncRoot)
			{
				if (string.IsNullOrEmpty(_filePath) || !File.Exists(_filePath))
				{
					return;
				}
				DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(_filePath);
				if (!force && !_dirty && PatchSettings.ReloadExternalTranslationOnChange && lastWriteTimeUtc == _lastWriteUtc)
				{
					return;
				}
				NodeExactRules.Clear();
				RegexRules.Clear();
				string[] array = File.ReadAllLines(_filePath, Encoding.UTF8);
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					string text = array2[i]?.TrimEnd() ?? string.Empty;
					if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#"))
					{
						continue;
					}
					string[] array3 = text.Split('\t');
					if (array3.Length < 3)
					{
						continue;
					}
					string a = array3[0].Trim();
					StringBuilder stringBuilder = new StringBuilder(array3[2]);
					for (int j = 3; j < array3.Length; j++)
					{
						stringBuilder.Append('\t').Append(array3[j]);
					}
					if (string.Equals(a, "NODE", StringComparison.OrdinalIgnoreCase))
					{
						string text2 = Unescape(array3[1]);
						string value = Unescape(stringBuilder.ToString());
						if (!string.IsNullOrEmpty(text2))
						{
							NodeExactRules[text2] = value;
						}
					}
					else
					{
						if (!string.Equals(a, "REGEX", StringComparison.OrdinalIgnoreCase))
						{
							continue;
						}
						string text3 = Unescape(array3[1]);
						string replacement = Unescape(stringBuilder.ToString());
						if (!string.IsNullOrEmpty(text3))
						{
							try
							{
								Regex pattern = new Regex(text3, RegexOptions.CultureInvariant);
								RegexRules.Add(new RegexRule(pattern, replacement));
							}
							catch
							{
							}
						}
					}
				}
				HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
				for (int k = 0; k < RegexRules.Count; k++)
				{
					hashSet.Add(RegexRules[k].Pattern.ToString());
				}
				foreach (KeyValuePair<string, string> builtInRegexRule in GetBuiltInRegexRules())
				{
					if (!string.IsNullOrEmpty(builtInRegexRule.Key) && !hashSet.Contains(builtInRegexRule.Key))
					{
						try
						{
							Regex pattern2 = new Regex(builtInRegexRule.Key, RegexOptions.CultureInvariant);
							RegexRules.Add(new RegexRule(pattern2, builtInRegexRule.Value ?? string.Empty));
							hashSet.Add(builtInRegexRule.Key);
						}
						catch
						{
						}
					}
				}
				_lastWriteUtc = lastWriteTimeUtc;
				_dirty = false;
			}
		}

		private static void EnsureDefaultFile()
		{
			if (!string.IsNullOrEmpty(_filePath))
			{
				string directoryName = Path.GetDirectoryName(_filePath);
				if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				if (!File.Exists(_filePath))
				{
					File.WriteAllText(_filePath, BuildDefaultContent(), Encoding.UTF8);
				}
			}
		}

		private static void AppendMissingBuiltInRegexRulesToExternalFile()
		{
			if (string.IsNullOrEmpty(_filePath) || !File.Exists(_filePath))
			{
				return;
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			string[] array = File.ReadAllLines(_filePath, Encoding.UTF8);
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string text = array2[i]?.TrimEnd() ?? string.Empty;
				if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#"))
				{
					continue;
				}
				string[] array3 = text.Split('\t');
				if (array3.Length < 3)
				{
					continue;
				}
				string a = array3[0].Trim();
				if (string.Equals(a, "REGEX", StringComparison.OrdinalIgnoreCase))
				{
					string text2 = Unescape(array3[1]);
					if (!string.IsNullOrEmpty(text2))
					{
						hashSet.Add(text2);
					}
				}
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, string> builtInRegexRule in GetBuiltInRegexRules())
			{
				if (!string.IsNullOrEmpty(builtInRegexRule.Key) && !hashSet.Contains(builtInRegexRule.Key))
				{
					list.Add("REGEX\t" + Escape(builtInRegexRule.Key) + "\t" + Escape(builtInRegexRule.Value));
					hashSet.Add(builtInRegexRule.Key);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("# ===== Auto-added missing REGEX rules =====");
			stringBuilder.AppendLine("# Added at: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			foreach (string item in list)
			{
				stringBuilder.AppendLine(item);
			}
			File.AppendAllText(_filePath, stringBuilder.ToString(), Encoding.UTF8);
		}

		private static void SetupWatcher()
		{
			if (_watcher == null && !string.IsNullOrEmpty(_filePath))
			{
				string directoryName = Path.GetDirectoryName(_filePath);
				string fileName = Path.GetFileName(_filePath);
				if (!string.IsNullOrEmpty(directoryName) && !string.IsNullOrEmpty(fileName))
				{
					_watcher = new FileSystemWatcher(directoryName, fileName)
					{
						NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite)
					};
					_watcher.Changed += OnTranslationFileChanged;
					_watcher.Created += OnTranslationFileChanged;
					_watcher.Renamed += OnTranslationFileChanged;
					_watcher.EnableRaisingEvents = true;
				}
			}
		}

		private static void OnTranslationFileChanged(object sender, FileSystemEventArgs e)
		{
			_dirty = true;
		}

		private static string BuildDefaultContent()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# LCTC translation rules");
			stringBuilder.AppendLine("# Format:");
			stringBuilder.AppendLine("# NODE<TAB>nodeName<TAB>translatedFullText");
			stringBuilder.AppendLine("# REGEX<TAB>regexPattern<TAB>replacementText");
			stringBuilder.AppendLine("# Escape supports: \\\\, \\t, \\r, \\n");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("# NODE rules are auto-appended from runtime terminal nodes");
			stringBuilder.AppendLine("# when AutoAppendMissingNodeRules=true.");
			stringBuilder.AppendLine("# Example:");
			stringBuilder.AppendLine("# NODE\t0_Bestiary\t...");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("# ===== Default REGEX rules =====");
			foreach (KeyValuePair<string, string> builtInRegexRule in GetBuiltInRegexRules())
			{
				stringBuilder.Append("REGEX\t");
				stringBuilder.Append(Escape(builtInRegexRule.Key));
				stringBuilder.Append('\t');
				stringBuilder.Append(Escape(builtInRegexRule.Value));
				stringBuilder.AppendLine();
			}
			return stringBuilder.ToString();
		}

		private static bool ContainsDynamicListToken(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			return text.Contains("[currentScannedEnemiesList]");
		}

		private static bool IsDynamicHubNode(string nodeName)
		{
			return string.Equals(nodeName, "0_Bestiary", StringComparison.Ordinal);
		}

		[IteratorStateMachine(typeof(<GetBuiltInRegexRules>d__26))]
		private static IEnumerable<KeyValuePair<string, string>> GetBuiltInRegexRules()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetBuiltInRegexRules>d__26(-2);
		}

		private static string AlignPlaceholderTokens(string translatedText, string originalText)
		{
			if (string.IsNullOrEmpty(translatedText) || string.IsNullOrEmpty(originalText))
			{
				return translatedText;
			}
			MatchCollection matchCollection = PlaceholderTokenRegex.Matches(translatedText);
			if (matchCollection.Count == 0)
			{
				return translatedText;
			}
			MatchCollection originalTokens = PlaceholderTokenRegex.Matches(originalText);
			if (originalTokens.Count == 0)
			{
				return translatedText;
			}
			int limit = Math.Min(matchCollection.Count, originalTokens.Count);
			int tokenIndex = 0;
			return PlaceholderTokenRegex.Replace(translatedText, delegate(Match match)
			{
				if (tokenIndex < limit)
				{
					string value = originalTokens[tokenIndex].Value;
					tokenIndex++;
					return value;
				}
				return match.Value;
			});
		}

		private static string Escape(string value)
		{
			if (value == null)
			{
				return string.Empty;
			}
			return value.Replace("\\", "\\\\").Replace("\t", "\\t").Replace("\r", "\\r")
				.Replace("\n", "\\n");
		}

		private static string Unescape(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(value.Length);
			for (int i = 0; i < value.Length; i++)
			{
				char c = value[i];
				if (c == '\\' && i + 1 < value.Length)
				{
					i++;
					char c2 = value[i];
					switch (c2)
					{
					case 'n':
						stringBuilder.Append('\n');
						break;
					case 'r':
						stringBuilder.Append('\r');
						break;
					case 't':
						stringBuilder.Append('\t');
						break;
					case '\\':
						stringBuilder.Append('\\');
						break;
					default:
						stringBuilder.Append(c2);
						break;
					}
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch(typeof(Terminal), "Awake")]
	internal static class PatchTerminalAwake
	{
		public static readonly Dictionary<string, string> SpecialNodes = new Dictionary<string, string>(StringComparer.Ordinal);

		[HarmonyPrefix]
		private static void Prefix(ref Terminal __instance)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.terminalNodes == (Object)null || __instance.terminalNodes.specialNodes == null || SpecialNodes.Count > 0)
			{
				return;
			}
			foreach (TerminalNode specialNode in __instance.terminalNodes.specialNodes)
			{
				if (!((Object)(object)specialNode == (Object)null))
				{
					string name = ((Object)specialNode).name;
					if (!string.IsNullOrEmpty(name) && !SpecialNodes.ContainsKey(name))
					{
						SpecialNodes[name] = specialNode.displayText ?? string.Empty;
					}
				}
			}
		}
	}
	internal static class PatchSettings
	{
		public static bool IsPatchEnabled { get; set; } = true;


		public static bool DumpTerminalNodesOnStart { get; set; } = true;


		public static bool DebugMode { get; set; } = false;


		public static bool DebugModeFromConfig { get; set; } = false;


		public static bool UseExternalTranslationFile { get; set; } = true;


		public static string ExternalTranslationFileName { get; set; } = "LCTC.Terminal.Translations.txt";


		public static bool ReloadExternalTranslationOnChange { get; set; } = true;


		public static bool AutoAppendMissingNodeRules { get; set; } = true;


		public static void ResolveDebugMode()
		{
			string path = Path.Combine(Paths.BepInExRootPath, "LCTC_DEBUG.flag");
			bool flag = File.Exists(path);
			DebugMode = DebugModeFromConfig || flag;
		}
	}
	internal static class DebugTranslationReporter
	{
		private static readonly object SyncRoot = new object();

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

		private static string DebugDir => Path.Combine(Paths.BepInExRootPath, "LCTC_Debug");

		private static string NewNodesPath => Path.Combine(DebugDir, "new_nodes.log");

		public static void ReportNode(string nodeName, string nodeText)
		{
			if (!PatchSettings.DebugMode || string.IsNullOrEmpty(nodeName) || (PatchSettings.UseExternalTranslationFile && ExternalTextTranslator.HasNodeRule(nodeName)))
			{
				return;
			}
			string text = Sanitize(nodeText);
			string item = nodeName + "|" + text;
			lock (SyncRoot)
			{
				if (SeenNewNodes.Add(item))
				{
					EnsureDir();
					File.AppendAllText(NewNodesPath, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {nodeName}\t{text}{Environment.NewLine}", Encoding.UTF8);
				}
			}
		}

		private static string Sanitize(string text)
		{
			string text2 = text ?? string.Empty;
			text2 = text2.Replace('\r', ' ').Replace('\n', ' ').Trim();
			if (text2.Length > 300)
			{
				text2 = text2.Substring(0, 300) + "...";
			}
			return text2;
		}

		private static void EnsureDir()
		{
			if (!Directory.Exists(DebugDir))
			{
				Directory.CreateDirectory(DebugDir);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "Start")]
	internal static class TerminalNodeDumpPatch
	{
		private static bool _dumped;

		[HarmonyPostfix]
		private static void Postfix()
		{
			PatchSettings.ResolveDebugMode();
			if (!PatchSettings.DumpTerminalNodesOnStart || _dumped)
			{
				return;
			}
			_dumped = true;
			List<TerminalNode> list = (from node in Resources.FindObjectsOfTypeAll<TerminalNode>()
				where (Object)(object)node != (Object)null
				orderby ((Object)node).name
				select node).ToList();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"Total TerminalNodes: {list.Count}");
			foreach (TerminalNode item in list)
			{
				string text = item.displayText ?? string.Empty;
				text = text.Replace('\r', ' ').Replace('\n', ' ');
				if (text.Length > 160)
				{
					text = text.Substring(0, 160) + "...";
				}
				stringBuilder.AppendLine(((Object)item).name + "\t" + text);
			}
			string text2 = Path.Combine(Paths.BepInExRootPath, "TerminalNodes_dump.txt");
			File.WriteAllText(text2, stringBuilder.ToString(), Encoding.UTF8);
			Debug.Log((object)("[LCTC] Terminal nodes dumped: " + text2));
			if (PatchSettings.UseExternalTranslationFile && PatchSettings.AutoAppendMissingNodeRules)
			{
				int num = ExternalTextTranslator.AppendMissingNodeRules(list);
				if (num > 0)
				{
					Debug.Log((object)$"[LCTC] Appended {num} missing NODE rules to external translation file.");
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
	internal class PatchLoadNewNode
	{
		[HarmonyPrefix]
		private static bool Prefix(ref TerminalNode node)
		{
			if (!PatchSettings.IsPatchEnabled || (Object)(object)node == (Object)null)
			{
				return true;
			}
			string name = ((Object)node).name;
			DebugTranslationReporter.ReportNode(name, node.displayText);
			if (PatchSettings.UseExternalTranslationFile)
			{
				if (!IsSensitiveDynamicNode(name, node.displayText) && ExternalTextTranslator.TryGetNodeRule(name, out var translatedNodeText))
				{
					if (PatchTerminalAwake.SpecialNodes.TryGetValue(name, out var value))
					{
						node.displayText = MergeBySourceLines(node.displayText ?? string.Empty, value, translatedNodeText);
					}
					else
					{
						node.displayText = translatedNodeText;
					}
				}
				else
				{
					node.displayText = ExternalTextTranslator.TranslateNodeTemplate(node.displayText, name);
				}
			}
			return true;
		}

		private static string MergeBySourceLines(string currentText, string sourceTemplateText, string translatedTemplateText)
		{
			string[] array = (sourceTemplateText ?? string.Empty).Replace("\r\n", "\n").Split('\n');
			string[] array2 = (translatedTemplateText ?? string.Empty).Replace("\r\n", "\n").Split('\n');
			int num = Math.Min(array.Length, array2.Length);
			string text = currentText ?? string.Empty;
			for (int i = 0; i < num; i++)
			{
				if (!string.IsNullOrEmpty(array[i]) && !string.IsNullOrEmpty(array2[i]))
				{
					text = text.Replace(array[i], array2[i]);
				}
			}
			return text;
		}

		private static bool IsSensitiveDynamicNode(string nodeName, string templateText)
		{
			if (string.Equals(nodeName, "0_Bestiary", StringComparison.Ordinal))
			{
				return true;
			}
			if (string.IsNullOrEmpty(templateText))
			{
				return false;
			}
			return templateText.Contains("[currentScannedEnemiesList]");
		}
	}
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal class TerminalParsePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref Terminal __instance, ref TerminalNode __result)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.screenText == (Object)null) && __instance.textAdded > 0 && __instance.screenText.text.Length >= __instance.textAdded)
			{
				string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
				if ((Object)(object)__result != (Object)null && text.ToLower() == "translate")
				{
					__result.displayText = "[translate]";
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
	internal class TerminalPatch
	{
		private static readonly Dictionary<string, string> BestiaryNameMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Snareflea", "陷阱蜈蚣" },
			{ "Bracken", "花人布拉肯" },
			{ "Thumper", "重擊者" },
			{ "EyelessDog", "無眼犬" },
			{ "HoardingBug", "囤積蟲" },
			{ "Hygrodere", "史萊姆" },
			{ "ForestKeeper", "森林守護者" },
			{ "CoilHead", "彈簧頭" },
			{ "LassoMan", "套索人" },
			{ "EarthLeviathan", "大地利維坦" },
			{ "Jester", "小丑" },
			{ "Puffer", "孢子蜥蜴" },
			{ "BunkerSpider", "碉堡蜘蛛" },
			{ "Manticoil", "四翼鳥" },
			{ "CircuitBee", "電路蜜蜂" },
			{ "Locust", "遊蕩蝗蟲" },
			{ "BaboonHawk", "狒狒鷹" },
			{ "Nutcracker", "胡桃鉗" },
			{ "RadMech", "古代鳥(機器人)" },
			{ "Butler", "管家" },
			{ "MaskHornets", "假面大黃蜂" },
			{ "TulipSnake", "鬱金香蛇" },
			{ "VainShroud", "紅蔓蕨" },
			{ "BushWolf", "綁架狐" },
			{ "ClaySurgeon", "理髮師" },
			{ "Maneater", "食人者" },
			{ "Sapsucker", "巨啄木鳥" },
			{ "Gunkfish", "污泥魟魚" },
			{ "Feiopar", "伏影豹" },
			{ "CadaverBloom", "屍花" }
		};

		[HarmonyPrefix]
		private static bool Prefix(Terminal __instance, ref string __result, ref string modifiedDisplayText, TerminalNode node)
		{
			List<string> list = new List<string>(7) { "快樂的星期日", "快樂的星期一", "快樂的星期二", "快樂的星期三", "快樂的星期四", "快樂的星期五", "快樂的星期六" };
			int dayOfWeek = (int)DateTime.Now.DayOfWeek;
			if (dayOfWeek >= 0 && dayOfWeek < list.Count)
			{
				modifiedDisplayText = (modifiedDisplayText ?? string.Empty).Replace("[currentDayRussian]", list[dayOfWeek]);
			}
			string a = (((Object)(object)node == (Object)null) ? string.Empty : ((Object)node).name);
			if (string.Equals(a, "0_Bestiary", StringComparison.Ordinal))
			{
				string text = modifiedDisplayText ?? string.Empty;
				text = text.Replace("[currentScannedEnemiesList]", BuildBestiaryList(__instance));
				__result = (PatchSettings.UseExternalTranslationFile ? ExternalTextTranslator.TranslatePostProcess(text) : text);
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		private static void Postfix(ref string __result, TerminalNode node)
		{
			if (PatchSettings.IsPatchEnabled && PatchSettings.UseExternalTranslationFile)
			{
				__result = ExternalTextTranslator.TranslatePostProcess(__result);
			}
		}

		[HarmonyFinalizer]
		private static Exception Finalizer(Exception __exception, ref string __result, string modifiedDisplayText, TerminalNode node)
		{
			if (__exception == null)
			{
				return null;
			}
			if (__exception is ArgumentOutOfRangeException)
			{
				string text = modifiedDisplayText ?? __result ?? string.Empty;
				text = text.Replace("[currentScannedEnemiesList]", string.Empty).Replace("[currentUnlockedLogsList]", string.Empty).Replace("[buyableItemsList]", string.Empty)
					.Replace("[buyableVehiclesList]", string.Empty)
					.Replace("[storedUnlockablesList]", string.Empty)
					.Replace("[unlockablesSelectionList]", string.Empty);
				__result = text;
				string text2 = (((Object)(object)node == (Object)null) ? "<null>" : ((Object)node).name);
				Debug.LogWarning((object)("[LCTC] TextPostProcess fallback applied on node: " + text2 + ". Error: " + __exception.Message));
				return null;
			}
			return __exception;
		}

		private static string BuildBestiaryList(Terminal terminal)
		{
			if ((Object)(object)terminal == (Object)null)
			{
				return string.Empty;
			}
			List<int> list = TryGetIntList(terminal, "scannedEnemyIDs", "scannedEnemies", "scannedBestiaryIDs");
			if (list == null || list.Count == 0)
			{
				return string.Empty;
			}
			object obj = TryGetMemberValue(terminal, "enemyFiles", "creatureFiles", "bestiaryCreatureFiles", "allCreatureFiles");
			if (!(obj is IList list2) || list2.Count == 0)
			{
				return string.Empty;
			}
			List<string> list3 = new List<string>();
			foreach (int item in list)
			{
				if (item >= 0 && item < list2.Count)
				{
					object fileObj = list2[item];
					string text = TryReadCreatureName(fileObj);
					if (!string.IsNullOrWhiteSpace(text))
					{
						string text2 = TranslateBestiaryName(text.Trim());
						list3.Add("* " + text2);
					}
				}
			}
			return (list3.Count == 0) ? string.Empty : (string.Join("\n", list3) + "\n");
		}

		private static List<int> TryGetIntList(object target, params string[] names)
		{
			foreach (string text in names)
			{
				object obj = TryGetMemberValue(target, text);
				if (obj is IEnumerable<int> source)
				{
					return source.ToList();
				}
				if (!(obj is IEnumerable enumerable))
				{
					continue;
				}
				List<int> list = new List<int>();
				foreach (object item2 in enumerable)
				{
					if (item2 is int item)
					{
						list.Add(item);
					}
				}
				if (list.Count > 0)
				{
					return list;
				}
			}
			return null;
		}

		private static string TryReadCreatureName(object fileObj)
		{
			if (fileObj == null)
			{
				return null;
			}
			Object val = (Object)((fileObj is Object) ? fileObj : null);
			if (val != null && !string.IsNullOrWhiteSpace(val.name))
			{
				return val.name.Replace("File", string.Empty).Trim();
			}
			return TryGetMemberValue(fileObj, "creatureName", "enemyName", "name", "displayName") as string;
		}

		private static string TranslateBestiaryName(string originalName)
		{
			if (string.IsNullOrWhiteSpace(originalName))
			{
				return originalName;
			}
			string key = NormalizeBestiaryKey(originalName);
			if (BestiaryNameMap.TryGetValue(key, out var value) && !string.IsNullOrWhiteSpace(value))
			{
				return originalName + " (" + value + ")";
			}
			return originalName;
		}

		private static string NormalizeBestiaryKey(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(name.Length);
			foreach (char c in name)
			{
				if (char.IsLetterOrDigit(c))
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		private static object TryGetMemberValue(object target, params string[] names)
		{
			if (target == null)
			{
				return null;
			}
			Type type = target.GetType();
			foreach (string name in names)
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field.GetValue(target);
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					return property.GetValue(target, null);
				}
			}
			return null;
		}
	}
}
namespace LCTC
{
	[BepInPlugin("LCTCTerminal", "LCTC Terminal", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static Flags Flags { get; private set; }

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			ApplyDedicatedConfig();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LCTC Terminal loaded.");
			new Harmony("LCTCTerminal.patch").PatchAll();
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				if (value.Metadata.GUID == "NewTerminal")
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Detected old terminal translation plugin (NewTerminal). It may conflict.");
					Flags = Flags.NewTerminalDetected;
				}
			}
		}

		private static void ApplyDedicatedConfig()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "LCTC.Terminal.Debug.cfg");
			ConfigFile val = new ConfigFile(text, true);
			PatchSettings.IsPatchEnabled = val.Bind<bool>("General", "EnableTranslationPatch", true, "Enable terminal translation patch pipeline.").Value;
			PatchSettings.DumpTerminalNodesOnStart = val.Bind<bool>("Debug", "DumpTerminalNodesOnStart", true, "Dump all runtime terminal nodes to BepInExRoot/TerminalNodes_dump.txt on startup.").Value;
			PatchSettings.DebugModeFromConfig = val.Bind<bool>("Debug", "EnableDebugCapture", false, "Capture unknown nodes and untranslated text to BepInExRoot/LCTC_Debug.").Value;
			PatchSettings.UseExternalTranslationFile = val.Bind<bool>("Translation", "UseExternalTranslationFile", true, "Use external translation text file (NODE + REGEX rules).").Value;
			PatchSettings.ExternalTranslationFileName = val.Bind<string>("Translation", "ExternalTranslationFileName", "LCTC.Terminal.Translations.txt", "Translation rules file name under BepInEx/config.").Value;
			PatchSettings.ReloadExternalTranslationOnChange = val.Bind<bool>("Translation", "ReloadExternalTranslationOnChange", true, "Reload external translation file when it changes.").Value;
			PatchSettings.AutoAppendMissingNodeRules = val.Bind<bool>("Translation", "AutoAppendMissingNodeRules", true, "Append missing NODE rules from runtime terminal nodes into external translation file.").Value;
			PatchSettings.ResolveDebugMode();
			ExternalTextTranslator.Initialize();
		}
	}
	internal static class PluginConstants
	{
		public const string Guid = "LCTCTerminal";

		public const string Name = "LCTC Terminal";

		public const string Version = "1.0.0";
	}
	[Flags]
	public enum Flags
	{
		None = 0,
		NewTerminalDetected = 1
	}
}