Decompiled source of SeHunTranslationLoader v0.6.0

BepInEx/plugins/SeHun-TranslationLoader/SeHun.Core.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SeHun.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.0.0")]
[assembly: AssemblyInformationalVersion("0.6.0-dev.1")]
[assembly: AssemblyProduct("SeHun.Core")]
[assembly: AssemblyTitle("SeHun.Core")]
[assembly: AssemblyVersion("0.6.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SeHun.Core
{
	public sealed class Package
	{
		public int SchemaVersion { get; internal set; }

		public string Id { get; internal set; }

		public string Language { get; internal set; }

		public string Adapter { get; internal set; }

		public string Game { get; internal set; }

		public string TargetPlugin { get; internal set; }

		public string LocalizationField { get; internal set; }

		public string FilePath { get; internal set; }

		public string ManifestPath { get; internal set; }
	}
	public static class Packages
	{
		public const string Marker = "SeHunTranslation.json";

		public const int MaxBytes = 4194304;

		private static XElement ReadObject(string path)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.None)
			{
				throw new InvalidDataException("Linked files are not supported.");
			}
			using FileStream fileStream = File.OpenRead(path);
			if (fileStream.Length > 4194304)
			{
				throw new InvalidDataException("JSON exceeds 4 MiB.");
			}
			string json;
			using (StreamReader streamReader = new StreamReader(fileStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true), detectEncodingFromByteOrderMarks: true, 4096, leaveOpen: true))
			{
				json = streamReader.ReadToEnd();
			}
			ValidateFlatJson(json);
			fileStream.Position = 0L;
			XmlDictionaryReader val = JsonReaderWriterFactory.CreateJsonReader((Stream)fileStream, new XmlDictionaryReaderQuotas
			{
				MaxDepth = 8,
				MaxStringContentLength = 4194304,
				MaxArrayLength = 4194304,
				MaxBytesPerRead = 4096,
				MaxNameTableCharCount = 4194304
			});
			try
			{
				XElement val2 = XElement.Load((XmlReader)(object)val);
				if ((string)val2.Attribute(XName.op_Implicit("type")) != "object")
				{
					throw new InvalidDataException("Expected a JSON object.");
				}
				HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
				foreach (XElement item in ((XContainer)val2).Elements())
				{
					if (!hashSet.Add(Name(item)))
					{
						throw new InvalidDataException("Duplicate JSON key: " + Name(item));
					}
				}
				return val2;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private static void ValidateFlatJson(string json)
		{
			int at = 0;
			Action action = delegate
			{
				for (; at < json.Length && " \r\n\t".IndexOf(json[at]) >= 0; at++)
				{
				}
			};
			Action action2 = delegate
			{
				if (at >= json.Length || json[at++] != '"')
				{
					throw new InvalidDataException("Expected JSON string.");
				}
				while (at < json.Length)
				{
					char c = json[at++];
					if (c == '"')
					{
						return;
					}
					if (c < ' ')
					{
						throw new InvalidDataException("Unescaped control character.");
					}
					if (c == '\\')
					{
						if (at >= json.Length)
						{
							throw new InvalidDataException("Incomplete escape.");
						}
						c = json[at++];
						if (c == 'u')
						{
							for (int i = 0; i < 4; i++)
							{
								if (at >= json.Length || !Uri.IsHexDigit(json[at++]))
								{
									throw new InvalidDataException("Invalid Unicode escape.");
								}
							}
						}
						else if ("\"\\/bfnrt".IndexOf(c) < 0)
						{
							throw new InvalidDataException("Invalid escape.");
						}
					}
				}
				throw new InvalidDataException("Unclosed string.");
			};
			action();
			if (at >= json.Length || json[at++] != '{')
			{
				throw new InvalidDataException("Expected JSON object.");
			}
			action();
			if (at < json.Length && json[at] != '}')
			{
				while (true)
				{
					action2();
					action();
					if (at >= json.Length || json[at++] != ':')
					{
						throw new InvalidDataException("Expected colon.");
					}
					action();
					if (at < json.Length && json[at] == '"')
					{
						action2();
					}
					else
					{
						int num = at;
						for (; at < json.Length && ",} \r\n\t".IndexOf(json[at]) < 0; at++)
						{
						}
						if (!Regex.IsMatch(json.Substring(num, at - num), "\\A(?:null|true|false|-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)\\z"))
						{
							throw new InvalidDataException("Only flat JSON scalar values are supported.");
						}
					}
					action();
					if (at >= json.Length || json[at] != ',')
					{
						break;
					}
					at++;
					action();
				}
			}
			if (at >= json.Length || json[at++] != '}')
			{
				throw new InvalidDataException("Expected closing brace.");
			}
			action();
			if (at != json.Length)
			{
				throw new InvalidDataException("Trailing JSON content.");
			}
		}

		private static string Name(XElement node)
		{
			return ((string)node.Attribute(XName.op_Implicit("item"))) ?? node.Name.LocalName;
		}

		private static string StringValue(XElement node)
		{
			if ((string)node.Attribute(XName.op_Implicit("type")) != "string" || node.HasElements)
			{
				throw new InvalidDataException("Expected a string: " + Name(node));
			}
			return node.Value;
		}

		public static Dictionary<string, string> ReadTranslations(string path)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
			foreach (XElement item in ((XContainer)ReadObject(path)).Elements())
			{
				string text = Name(item);
				if (string.IsNullOrWhiteSpace(text))
				{
					throw new InvalidDataException("Empty translation key.");
				}
				dictionary.Add(text, StringValue(item));
			}
			if (dictionary.Count == 0)
			{
				throw new InvalidDataException("Empty translation file.");
			}
			return dictionary;
		}

		public static Package ReadManifest(string path)
		{
			Dictionary<string, XElement> fields = ((XContainer)ReadObject(path)).Elements().ToDictionary<XElement, string, XElement>(Name, (XElement x) => x, StringComparer.Ordinal);
			XElement value2;
			Func<string, string> func = (string key) => (!fields.TryGetValue(key, out value2)) ? null : StringValue(value2);
			int result = 0;
			if (fields.TryGetValue("schemaVersion", out var value) && ((string)value.Attribute(XName.op_Implicit("type")) != "number" || !int.TryParse(value.Value, out result)))
			{
				throw new InvalidDataException("Invalid schemaVersion.");
			}
			if (result != 0 && result != 1)
			{
				throw new InvalidDataException("Unsupported schemaVersion: " + result);
			}
			Package package = new Package
			{
				SchemaVersion = result,
				Id = func("id"),
				Language = func("language"),
				Adapter = func("adapter"),
				Game = func("game"),
				TargetPlugin = func("targetPlugin"),
				LocalizationField = func("localizationField"),
				ManifestPath = Path.GetFullPath(path)
			};
			if (string.IsNullOrWhiteSpace(package.Id) || string.IsNullOrWhiteSpace(package.Language))
			{
				throw new InvalidDataException("id and language are required.");
			}
			if (result == 1 && (string.IsNullOrWhiteSpace(package.Adapter) || string.IsNullOrWhiteSpace(package.Game)))
			{
				throw new InvalidDataException("Version 1 requires game and adapter.");
			}
			string text = func("file");
			if (!string.IsNullOrEmpty(text))
			{
				if (text == "." || text == ".." || text.IndexOfAny(new char[9] { '/', '\\', ':', '<', '>', '"', '|', '?', '*' }) >= 0 || text.Any(char.IsControl) || text.EndsWith(".") || text.EndsWith(" ") || Path.IsPathRooted(text))
				{
					throw new InvalidDataException("Unsafe translation filename.");
				}
				package.FilePath = Path.Combine(Path.GetDirectoryName(package.ManifestPath), text);
			}
			return package;
		}

		public static IReadOnlyList<Package> Discover(string root, Action<string> warning)
		{
			List<Package> list = new List<Package>();
			Scan(Path.GetFullPath(root), list, warning, 0);
			List<Package> list2 = new List<Package>();
			foreach (IGrouping<string, Package> item in list.GroupBy<Package, string>((Package p) => p.Id + "\0" + p.Language, StringComparer.OrdinalIgnoreCase))
			{
				if (item.Count() != 1)
				{
					warning("Duplicate package id/language; all copies skipped: " + item.First().Id);
				}
				else
				{
					list2.Add(item.First());
				}
			}
			return list2.AsReadOnly();
		}

		private static void Scan(string directory, List<Package> found, Action<string> warning, int depth)
		{
			try
			{
				if ((File.GetAttributes(directory) & FileAttributes.ReparsePoint) != FileAttributes.None)
				{
					warning("Linked directory skipped: " + directory);
					return;
				}
				if (depth > 32)
				{
					warning("Directory depth exceeded: " + directory);
					return;
				}
				string text = Path.Combine(directory, "SeHunTranslation.json");
				if (File.Exists(text))
				{
					try
					{
						found.Add(ReadManifest(text));
					}
					catch (Exception ex)
					{
						warning("Invalid package: " + text + " - " + ex.Message);
					}
				}
				foreach (string item in Directory.GetDirectories(directory).OrderBy<string, string>((string x) => x, StringComparer.Ordinal))
				{
					Scan(item, found, warning, depth + 1);
				}
			}
			catch (Exception ex2)
			{
				warning("Cannot scan: " + directory + " - " + ex2.Message);
			}
		}
	}
	public interface ITranslationAdapter
	{
		string Id { get; }

		void Load(Package package, Action<string> info, Action<string> warning);
	}
	public sealed class AdapterRegistry
	{
		private readonly Dictionary<string, ITranslationAdapter> adapters = new Dictionary<string, ITranslationAdapter>(StringComparer.Ordinal);

		public void Register(ITranslationAdapter adapter)
		{
			if (adapter == null || string.IsNullOrWhiteSpace(adapter.Id))
			{
				throw new ArgumentException("An adapter ID is required.");
			}
			if (adapters.ContainsKey(adapter.Id))
			{
				throw new InvalidOperationException("Adapter already registered: " + adapter.Id);
			}
			adapters.Add(adapter.Id, adapter);
		}

		public void Load(string adapterId, Package package, Action<string> info, Action<string> warning)
		{
			if (adapterId == null || !adapters.TryGetValue(adapterId, out var value))
			{
				warning("Unsupported adapter: " + (adapterId ?? "(missing)") + " for " + package.Id);
				return;
			}
			try
			{
				value.Load(package, info, warning);
			}
			catch (Exception ex)
			{
				warning("Adapter failed: " + package.Id + " - " + ex.Message);
			}
		}
	}
}

BepInEx/plugins/SeHun-TranslationLoader/SeHunTranslationLoader.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using SeHun.Core;
using SeHunTranslationLoader.Adapters;
using UnityEngine;
using ValheimProfessions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SeHunTranslationLoader")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.0.0")]
[assembly: AssemblyInformationalVersion("0.6.0-dev.1")]
[assembly: AssemblyProduct("SeHunTranslationLoader")]
[assembly: AssemblyTitle("SeHunTranslationLoader")]
[assembly: AssemblyVersion("0.6.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SeHunTranslationLoader
{
	[BepInPlugin("sehun.translationloader", "SeHun Translation Loader DEV", "0.6.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SeHunPlugin : BaseUnityPlugin
	{
		private sealed class CallbackAdapter : ITranslationAdapter
		{
			private readonly Action<Package, Action<string>, Action<string>> load;

			private bool attempted;

			public string Id { get; }

			public CallbackAdapter(string id, Action<Package, Action<string>, Action<string>> load)
			{
				Id = id;
				this.load = load;
			}

			public void Load(Package package, Action<string> info, Action<string> warning)
			{
				if (attempted)
				{
					throw new InvalidOperationException("Ehhez a Harmony-adapterhez csak egy csomag tölthető be: " + Id);
				}
				attempted = true;
				load(package, info, warning);
			}
		}

		private IReadOnlyList<Package> packages;

		private readonly HashSet<Package> loaded = new HashSet<Package>();

		public static AdapterRegistry Adapters { get; } = CreateRegistry();

		private static AdapterRegistry CreateRegistry()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			AdapterRegistry val = new AdapterRegistry();
			val.Register((ITranslationAdapter)(object)new JotunnAdapter(useField: false));
			val.Register((ITranslationAdapter)(object)new JotunnAdapter(useField: true));
			val.Register((ITranslationAdapter)(object)new CallbackAdapter("valheim.marketplace", LoadMarketplace));
			val.Register((ITranslationAdapter)(object)new CallbackAdapter("valheim.aeresprofessions", LoadAeres));
			return val;
		}

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SeHun Translation Loader 0.6.0-dev.1 — NEM stabil kiadás.");
			packages = Packages.Discover(Paths.PluginPath, (Action<string>)Warn);
			foreach (Package package in packages)
			{
				string text = ResolveAdapter(package);
				if (text == "valheim.jotunn" || (text == "valheim.jotunn.field" && !string.IsNullOrEmpty(package.TargetPlugin) && Chainloader.PluginInfos.ContainsKey(package.TargetPlugin)))
				{
					Load(package, text);
					loaded.Add(package);
				}
			}
		}

		private void Start()
		{
			foreach (Package package in packages)
			{
				if (!loaded.Contains(package))
				{
					Load(package, ResolveAdapter(package));
				}
			}
		}

		private void Load(Package package, string adapter)
		{
			if (package.SchemaVersion == 1 && package.Game != "valheim")
			{
				Warn("Más játékhoz tartozó csomag kihagyva: " + package.Id);
				return;
			}
			Adapters.Load(adapter, package, (Action<string>)delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)message);
			}, (Action<string>)Warn);
		}

		private void Warn(string message)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)message);
		}

		public static string ResolveAdapter(Package package)
		{
			if (package.SchemaVersion == 1)
			{
				return package.Adapter;
			}
			if (!string.Equals(package.Language, "Hungarian", StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			return package.Id switch
			{
				"NorseDemigodsUI" => "valheim.jotunn", 
				"Marketplace" => "valheim.marketplace", 
				"AeresProfessions" => "valheim.aeresprofessions", 
				_ => null, 
			};
		}

		private static void LoadMarketplace(Package package, Action<string> info, Action<string> warning)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			RequireHungarian(package);
			Packages.ReadTranslations(package.FilePath);
			MarketplaceAdapter.Initialize(new Harmony("sehun.translationloader.marketplace"), package.FilePath, info, warning);
		}

		private static void LoadAeres(Package package, Action<string> info, Action<string> warning)
		{
			RequireHungarian(package);
			if (!Chainloader.PluginInfos.ContainsKey("com.danle.professions"))
			{
				warning("AeresProfessions mod nem található, adapter kihagyva.");
				return;
			}
			if (Chainloader.PluginInfos.ContainsKey("sehun.aeresprofessions.hu"))
			{
				warning("Korábbi AeresProfessions magyarító aktív, adapter kihagyva.");
				return;
			}
			ApplyAeres();
			info("AeresProfessions Harmony-adapter aktiválva (7 patchosztály).");
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ApplyAeres()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			AeresProfessionsPatchRegistration.Apply(new Harmony("sehun.translationloader.aeresprofessions"));
		}

		private static void RequireHungarian(Package package)
		{
			if (!string.Equals(package.Language, "Hungarian", StringComparison.OrdinalIgnoreCase))
			{
				throw new NotSupportedException("Ez a meglévő Harmony-adapter csak Hungarian nyelvet támogat.");
			}
		}
	}
}
namespace SeHunTranslationLoader.Adapters
{
	[HarmonyPatch(typeof(ProfessionInfo), "DisplayName")]
	internal static class DisplayNamePatch
	{
		private static void Postfix(ProfessionType type, ref string __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			switch ((int)type)
			{
			case 0:
				__result = "Bányász";
				break;
			case 1:
				__result = "Favágó";
				break;
			case 2:
				__result = "Vadász";
				break;
			case 3:
				__result = "Földműves";
				break;
			case 4:
				__result = "Kovács";
				break;
			case 5:
				__result = "Alkimista";
				break;
			case 6:
				__result = "Kőműves";
				break;
			case 7:
				__result = "Tengerész";
				break;
			case 8:
				__result = "Fogadós";
				break;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionInfo), "Summary")]
	internal static class SummaryPatch
	{
		private static void Postfix(ProfessionType type, ref string __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			switch ((int)type)
			{
			case 0:
				__result = "Kő és érc bányászata csákánnyal";
				break;
			case 1:
				__result = "Fák kivágása és rönkök darabolása";
				break;
			case 2:
				__result = "Állatok és szörnyek elleni harc";
				break;
			case 3:
				__result = "Növények betakarítása és ültetése";
				break;
			case 4:
				__result = "Tárgyak készítése és fejlesztése a kovácsműhelyben";
				break;
			case 5:
				__result = "Mézsörök és főzetek készítése";
				break;
			case 6:
				__result = "Kőépítés és kőfaragás";
				break;
			case 7:
				__result = "Hajózás és halászat";
				break;
			case 8:
				__result = "Ételek készítése és főzőállomások használata";
				break;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionInfo), "Perk")]
	internal static class PerkPatch
	{
		private static void Postfix(ProfessionType type, ref string __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			switch ((int)type)
			{
			case 0:
				__result = "csákánysebzés";
				break;
			case 1:
				__result = "favágási sebzés";
				break;
			case 2:
				__result = "lények elleni sebzés";
				break;
			case 3:
				__result = "esély a dupla betakarításra";
				break;
			case 4:
				__result = "esély az anyagmegtakarításra kovácsoláskor";
				break;
			case 5:
				__result = "esély az anyagmegtakarításra főzetkészítéskor";
				break;
			case 6:
				__result = "esély az anyagmegtakarításra kőmunkáknál";
				break;
			case 7:
				__result = "hajózási sebesség";
				break;
			case 8:
				__result = "hosszabb ételhatás";
				break;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionMenu), "DrawWindow")]
	internal static class DrawWindowHungarianPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr)
				{
					switch (instruction.operand as string)
					{
					case "Professions":
						instruction.operand = "Szakmák";
						break;
					case "Choose a profession. Only your active one earns XP and gives its perk.":
						instruction.operand = "Válassz szakmát! Csak az aktív szakmád szerez XP-t és ad bónuszt.";
						break;
					case "Switching professions is disabled on this server.":
						instruction.operand = "A szakmaváltás le van tiltva ezen a szerveren.";
						break;
					case "Active: ":
						instruction.operand = "Aktív szakma: ";
						break;
					case ". Other professions keep their XP while you're away.":
						instruction.operand = ". A többi szakma megszerzett XP-je megmarad.";
						break;
					case "Close":
						instruction.operand = "Bezárás";
						break;
					case " or Esc to close":
						instruction.operand = " vagy Esc a bezáráshoz";
						break;
					}
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionMenu), "DrawRow")]
	internal static class DrawRowHungarianPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr)
				{
					string text = instruction.operand as string;
					switch (text)
					{
					case "Choose":
						text = "Választás";
						goto IL_00da;
					case "ACTIVE":
						text = "AKTÍV";
						goto IL_00da;
					default:
						if (text.Contains("Lv {0}"))
						{
							text = text.Replace("Lv {0}", "{0}. szint");
						}
						else if (text.StartsWith("Lv ", StringComparison.Ordinal))
						{
							text = "Szint " + text.Substring(3);
						}
						goto IL_00da;
					case null:
						break;
						IL_00da:
						if (text.Contains("Perk: +"))
						{
							text = text.Replace("Perk: +", "Bónusz: +");
						}
						if (text.Contains(" XP (max level)"))
						{
							text = text.Replace(" XP (max level)", " XP (maximális szint)");
						}
						instruction.operand = text;
						break;
					}
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionMenu), "Choose")]
	internal static class ChooseHungarianPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr && instruction.operand as string == "You are now a ")
				{
					instruction.operand = "Mostantól a választott szakmád: ";
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(ProfessionMenu), "Update")]
	internal static class UpdateHungarianPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr)
				{
					if (instruction.operand as string == "Press ")
					{
						instruction.operand = "Nyomd meg a(z) ";
					}
					else if (instruction.operand as string == " to choose a profession")
					{
						instruction.operand = " billentyűkombinációt a szakmaválasztáshoz";
					}
				}
				yield return instruction;
			}
		}
	}
	internal static class AeresProfessionsPatchRegistration
	{
		internal static void Apply(Harmony harmony)
		{
			Type[] array = new Type[7]
			{
				typeof(DisplayNamePatch),
				typeof(SummaryPatch),
				typeof(PerkPatch),
				typeof(DrawWindowHungarianPatch),
				typeof(DrawRowHungarianPatch),
				typeof(ChooseHungarianPatch),
				typeof(UpdateHungarianPatch)
			};
			foreach (Type type in array)
			{
				harmony.CreateClassProcessor(type).Patch();
			}
		}
	}
	internal sealed class JotunnAdapter : ITranslationAdapter
	{
		private readonly bool useField;

		private readonly Dictionary<CustomLocalization, Dictionary<string, HashSet<string>>> claimed = new Dictionary<CustomLocalization, Dictionary<string, HashSet<string>>>();

		public string Id
		{
			get
			{
				if (!useField)
				{
					return "valheim.jotunn";
				}
				return "valheim.jotunn.field";
			}
		}

		public JotunnAdapter(bool useField)
		{
			this.useField = useField;
		}

		public void Load(Package package, Action<string> info, Action<string> warning)
		{
			Dictionary<string, string> dictionary = Packages.ReadTranslations(package.FilePath);
			foreach (string key in dictionary.Keys)
			{
				if (key.StartsWith("$") || key.IndexOfAny(" (){}[]+-!?/\\&%,.:-=<>\n\r\t".ToCharArray()) >= 0)
				{
					throw new InvalidOperationException("Érvénytelen Jötunn-kulcs: " + key);
				}
			}
			string text = ((package.SchemaVersion == 0) ? "Hungarian" : package.Language);
			if (!char.IsUpper(text[0]))
			{
				throw new InvalidOperationException("A Jötunn nyelvnév nagybetűvel kezdődik.");
			}
			CustomLocalization val;
			if (useField)
			{
				if (string.IsNullOrWhiteSpace(package.TargetPlugin) || string.IsNullOrWhiteSpace(package.LocalizationField))
				{
					throw new InvalidOperationException("targetPlugin és localizationField megadása szükséges.");
				}
				if (!Chainloader.PluginInfos.TryGetValue(package.TargetPlugin, out var value) || (Object)(object)value.Instance == (Object)null)
				{
					throw new InvalidOperationException("Célmod nem aktív: " + package.TargetPlugin);
				}
				FieldInfo field = ((object)value.Instance).GetType().GetField(package.LocalizationField, BindingFlags.Static | BindingFlags.Public);
				if (field == null || field.FieldType != typeof(CustomLocalization))
				{
					throw new NotSupportedException("A célmező nem nyilvános, statikus Jötunn CustomLocalization.");
				}
				object? value2 = field.GetValue(null);
				val = (CustomLocalization)((value2 is CustomLocalization) ? value2 : null);
				if (val == null)
				{
					throw new InvalidOperationException("A célmod szótára még nincs inicializálva.");
				}
			}
			else
			{
				val = LocalizationManager.Instance.GetLocalization();
			}
			if (!claimed.TryGetValue(val, out var value3))
			{
				claimed.Add(val, value3 = new Dictionary<string, HashSet<string>>(StringComparer.Ordinal));
			}
			if (!value3.TryGetValue(text, out var value4))
			{
				value3.Add(text, value4 = new HashSet<string>(StringComparer.Ordinal));
			}
			foreach (string key2 in dictionary.Keys)
			{
				if (value4.Contains(key2))
				{
					throw new InvalidOperationException("Ütköző fordítási kulcs; csomag kihagyva: " + key2);
				}
			}
			val.AddTranslation(ref text, dictionary);
			IReadOnlyDictionary<string, string> translations = val.GetTranslations(ref text);
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				if (!translations.TryGetValue(item.Key, out var value5) || value5 != item.Value)
				{
					throw new InvalidOperationException("Jötunn nem regisztrálta a kulcsot: " + item.Key);
				}
			}
			value4.UnionWith(dictionary.Keys);
			info(package.Id + " fordítás betöltve: " + dictionary.Count + " kulcs, " + text + ", " + Id);
		}
	}
	internal static class MarketplaceAdapter
	{
		private static Dictionary<string, string> translations;

		internal static bool Initialize(Harmony harmony, string jsonPath, Action<string> info, Action<string> warning)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			if (!File.Exists(jsonPath))
			{
				warning("Marketplace magyar JSON nem található: " + jsonPath);
				return false;
			}
			Dictionary<string, string> dictionary;
			using (FileStream fileStream = File.OpenRead(jsonPath))
			{
				dictionary = ((XmlObjectSerializer)new DataContractJsonSerializer(typeof(Dictionary<string, string>), new DataContractJsonSerializerSettings
				{
					UseSimpleDictionaryFormat = true
				})).ReadObject((Stream)fileStream) as Dictionary<string, string>;
			}
			if (dictionary == null || dictionary.Count == 0)
			{
				warning("Marketplace magyar JSON üres vagy nem megfelelő.");
				return false;
			}
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (string.Equals(assembly.GetName().Name, "Marketplace", StringComparison.OrdinalIgnoreCase))
				{
					type = assembly.GetType("Marketplace.Loc", throwOnError: false) ?? assembly.GetType("Loc", throwOnError: false);
					if (type != null)
					{
						break;
					}
				}
			}
			if (type == null)
			{
				warning("Marketplace.Loc osztály nem található; az adapter nem indult.");
				return false;
			}
			MethodInfo method = type.GetMethod("T", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
			if (method == null)
			{
				warning("Marketplace Loc.T(string) nem található; az adapter nem indult.");
				return false;
			}
			MethodInfo method2 = typeof(MarketplaceAdapter).GetMethod("TranslationPostfix", BindingFlags.Static | BindingFlags.NonPublic);
			translations = dictionary;
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			info("Marketplace Harmony-adapter aktiválva. Betöltött kulcsok: " + translations.Count);
			return true;
		}

		private static void TranslationPostfix(string key, ref string __result)
		{
			if (key != null && translations != null && translations.TryGetValue(key, out var value))
			{
				__result = value;
			}
		}
	}
}