Decompiled source of Sweet RU WesleysEnemies v1.0.0

SweetRuWesleysEnemies.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SweetRu;
using UnityEngine;

[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("SweetRuWesleysEnemies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SweetRuWesleysEnemies")]
[assembly: AssemblyTitle("SweetRuWesleysEnemies")]
[assembly: AssemblyVersion("1.0.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 SweetRu
{
	internal static class Core
	{
		internal static ManualLogSource Log;

		internal static string Folder;

		internal static readonly Dictionary<string, string> ItemNames = new Dictionary<string, string>();

		internal static readonly Dictionary<string, string> EnemyNames = new Dictionary<string, string>();

		internal static readonly Dictionary<string, string> ChatLines = new Dictionary<string, string>();

		internal static bool UseLocalizedNames;

		internal static Dictionary<string, string> LoadTsv(string fileName, Dictionary<string, string> into = null)
		{
			Dictionary<string, string> dictionary = into ?? new Dictionary<string, string>();
			string text = Path.Combine(Folder, fileName);
			if (!File.Exists(text))
			{
				Log.LogWarning((object)("Missing translation file: " + text));
				return dictionary;
			}
			try
			{
				string[] array = File.ReadAllLines(text, Encoding.UTF8);
				foreach (string text2 in array)
				{
					if (!string.IsNullOrWhiteSpace(text2) && !text2.StartsWith("#"))
					{
						string[] array2 = text2.Split('\t');
						if (array2.Length == 2 && !string.IsNullOrWhiteSpace(array2[1]))
						{
							dictionary[Unescape(array2[0])] = Unescape(array2[1]);
						}
					}
				}
				Log.LogInfo((object)("Loaded " + dictionary.Count + " lines from " + fileName + "."));
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to read " + fileName + ": " + ex.Message));
			}
			return dictionary;
		}

		private static string Unescape(string value)
		{
			return value.Replace("\\n", "\n").Replace("\\t", "\t").Replace("\\s", " ");
		}

		internal static Assembly AssemblyOfPlugin(string pluginGuid)
		{
			if (Chainloader.PluginInfos.TryGetValue(pluginGuid, out var value) && (Object)(object)value.Instance != (Object)null)
			{
				return ((object)value.Instance).GetType().Assembly;
			}
			Log.LogError((object)("Plugin " + pluginGuid + " is not loaded."));
			return null;
		}
	}
	internal static class Literals
	{
		private const BindingFlags AllMembers = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private const byte LdstrOpcode = 114;

		private const int StringTokenType = 1879048192;

		private static Dictionary<string, string> map;

		internal static int Apply(Harmony harmony, Assembly target, Dictionary<string, string> dictionary)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if (target == null)
			{
				Core.Log.LogError((object)"Target assembly not loaded, nothing to rewrite.");
				return 0;
			}
			if (dictionary.Count == 0)
			{
				return 0;
			}
			map = dictionary;
			HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(Literals), "Transpiler", (Type[])null, (Type[])null));
			int num = 0;
			foreach (Type item in TypesOf(target))
			{
				if (item == null || item.IsGenericTypeDefinition)
				{
					continue;
				}
				foreach (MethodBase item2 in MembersOf(item))
				{
					if (LoadsTranslatedString(item2, item.Module))
					{
						try
						{
							harmony.Patch(item2, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null);
							num++;
						}
						catch (Exception ex)
						{
							Core.Log.LogWarning((object)("Could not rewrite " + item.FullName + "." + item2.Name + ": " + ex.Message));
						}
					}
				}
			}
			Core.Log.LogInfo((object)("Rewrote text in " + num + " methods of " + target.GetName().Name + "."));
			return num;
		}

		private static IEnumerable<Type> TypesOf(Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type t) => t != null);
			}
		}

		private static IEnumerable<MethodBase> MembersOf(Type type)
		{
			return from m in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Cast<MethodBase>().Concat(type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
				where !m.IsAbstract && !m.ContainsGenericParameters
				select m;
		}

		private static bool LoadsTranslatedString(MethodBase method, Module module)
		{
			byte[] array;
			try
			{
				array = method.GetMethodBody()?.GetILAsByteArray();
			}
			catch
			{
				return false;
			}
			if (array == null)
			{
				return false;
			}
			for (int i = 0; i + 4 < array.Length; i++)
			{
				if (array[i] != 114)
				{
					continue;
				}
				int num = BitConverter.ToInt32(array, i + 1);
				if ((num & -16777216) != 1879048192)
				{
					continue;
				}
				try
				{
					if (map.ContainsKey(module.ResolveString(num)))
					{
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldstr && instruction.operand is string key && map.TryGetValue(key, out var value))
				{
					instruction.operand = value;
				}
				yield return instruction;
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "ShowingInfo")]
	internal static class ItemNamePatch
	{
		private const string TagMarker = " <color=#FFFFFF>[";

		[HarmonyPostfix]
		private static void Postfix(ref string ___promptName)
		{
			if (!string.IsNullOrEmpty(___promptName))
			{
				int num = ___promptName.IndexOf(" <color=#FFFFFF>[", StringComparison.Ordinal);
				string key = ((num >= 0) ? ___promptName.Substring(0, num) : ___promptName);
				if (Core.ItemNames.TryGetValue(key, out var value))
				{
					___promptName = ((num >= 0) ? (value + ___promptName.Substring(num)) : value);
				}
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "Awake")]
	internal static class EnemyNamePatch
	{
		[HarmonyPostfix]
		private static void Postfix(EnemyParent __instance)
		{
			if (Core.UseLocalizedNames && (Object)(object)__instance.enemyNameLocalized != (Object)null)
			{
				string text = null;
				try
				{
					text = __instance.enemyNameLocalized.GetLocalizedString();
				}
				catch
				{
				}
				if (!string.IsNullOrEmpty(text))
				{
					__instance.enemyName = text;
				}
			}
			if (__instance.enemyName != null && Core.EnemyNames.TryGetValue(__instance.enemyName, out var value))
			{
				__instance.enemyName = value;
			}
		}
	}
	[HarmonyPatch(typeof(ChatManager), "PossessChat")]
	internal static class ChatLinePatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string message)
		{
			if (message != null && Core.ChatLines.TryGetValue(message, out var value))
			{
				message = value;
			}
		}
	}
}
namespace SweetRuWesleysEnemies
{
	[BepInPlugin("sweet.ru.wesleysenemies", "Sweet RU: Wesley's Enemies", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "sweet.ru.wesleysenemies";

		public const string Version = "1.0.0";

		private const string TargetGuid = "WesleysEnemies";

		private void Awake()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Core.Log = ((BaseUnityPlugin)this).Logger;
			Core.Folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Core.LoadTsv("Enemies.tsv", Core.EnemyNames);
			if (Core.EnemyNames.Count > 0)
			{
				new Harmony("sweet.ru.wesleysenemies").PatchAll(typeof(EnemyNamePatch));
			}
		}
	}
}