Decompiled source of Starstorm2 JP v1.1.0

plugins/Starstorm2Japanese.dll

Decompiled 2 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 MSU;
using Microsoft.CodeAnalysis;
using R2API.Utils;
using RoR2;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Starstorm2Japanese")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("Starstorm2Japanese")]
[assembly: AssemblyTitle("Starstorm2Japanese")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LocalTranslations
{
	[DataContract]
	public sealed class LanguageFile
	{
		[DataMember(Name = "strings")]
		public Dictionary<string, string> Strings = new Dictionary<string, string>();
	}
	public static class Catalog
	{
		public static Dictionary<string, string> LoadFolder(string directory)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
			string[] files = Directory.GetFiles(directory, "*.json");
			Array.Sort(files, (IComparer<string>?)StringComparer.Ordinal);
			if (files.Length == 0)
			{
				throw new InvalidDataException("No translation files: " + directory);
			}
			DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(LanguageFile), new DataContractJsonSerializerSettings
			{
				UseSimpleDictionaryFormat = true
			});
			string[] array = files;
			foreach (string text in array)
			{
				using FileStream stream = File.OpenRead(text);
				foreach (KeyValuePair<string, string> @string in (((LanguageFile)dataContractJsonSerializer.ReadObject(stream)) ?? throw new InvalidDataException("Empty JSON document: " + text)).Strings)
				{
					if (string.IsNullOrWhiteSpace(@string.Key) || @string.Value == null)
					{
						throw new InvalidDataException("Invalid token in " + text);
					}
					if (dictionary.ContainsKey(@string.Key))
					{
						throw new InvalidDataException("Duplicate token: " + @string.Key);
					}
					dictionary.Add(@string.Key, @string.Value);
				}
			}
			return dictionary;
		}
	}
	public static class LiteralTranslationPatch
	{
		private static readonly Dictionary<MethodBase, HashSet<string>> targets = new Dictionary<MethodBase, HashSet<string>>();

		public static void Install(Harmony harmony, MethodBase method, IEnumerable<string> literals)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			targets.Add(method, new HashSet<string>(literals, StringComparer.Ordinal));
			harmony.Patch(method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(LiteralTranslationPatch), "Transpile", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod)
		{
			HashSet<string> selected = targets[__originalMethod];
			MethodInfo getter = AccessTools.Method(typeof(Language), "GetString", new Type[1] { typeof(string) }, (Type[])null);
			HashSet<string> found = new HashSet<string>();
			foreach (CodeInstruction instruction in instructions)
			{
				yield return instruction;
				if (instruction.opcode == OpCodes.Ldstr && instruction.operand is string item && selected.Contains(item))
				{
					found.Add(item);
					yield return new CodeInstruction(OpCodes.Call, (object)getter);
				}
			}
			if (!selected.SetEquals(found))
			{
				throw new InvalidOperationException("Original display text changed: " + __originalMethod);
			}
		}
	}
}
namespace LocalTranslations.Starstorm2Japanese
{
	[BepInPlugin("localtranslations.starstorm2.japanese", "Starstorm2 JP", "1.1.0")]
	[BepInDependency("com.TeamMoonstorm", "0.6.41")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private Harmony? harmony;

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			if (!((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Starstorm 2の日本語訳を有効にします。変更後はゲームを再起動してください。日本語表示だけを変更します。").Value)
			{
				return;
			}
			try
			{
				Dictionary<string, string> dictionary = Catalog.LoadFolder(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "translations", "ja"));
				LanguageFileLoader.AddLanguageFilesFromMod((BaseUnityPlugin)(object)this, "translations");
				harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Assembly assembly = ((object)Chainloader.PluginInfos["com.TeamMoonstorm"].Instance).GetType().Assembly;
				(string, string)[] array = new(string, string)[2]
				{
					("SS2.EliteEventMissionController+EliteObjectiveTracker", "elite kills heehaw: {0}%"),
					("SS2.Components.StormController+StormObjectiveTracker", "effectIntensity: {0} hehe storm level {1}, {2}%")
				};
				for (int i = 0; i < array.Length; i++)
				{
					(string, string) tuple = array[i];
					try
					{
						MethodInfo method = AccessTools.Method(assembly.GetType(tuple.Item1, throwOnError: true), "GenerateString", (Type[])null, (Type[])null) ?? throw new MissingMethodException(tuple.Item1, "GenerateString");
						LiteralTranslationPatch.Install(harmony, method, new string[1] { tuple.Item2 });
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not localize objective " + tuple.Item1 + ": " + ex));
					}
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered {dictionary.Count} Japanese tokens for Starstorm 2 package 0.6.44 (MSU formatting enabled).");
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Japanese dictionary could not be loaded; original text remains available. " + ex2));
			}
		}

		private void OnDestroy()
		{
			Harmony? obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}