Decompiled source of Dotoo IME Input v1.0.0

BepInEx/plugins/dotoo_ime_input.dll

Decompiled 20 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Movement;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;

[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("dotoo_ime_input")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("dotoo_ime_input")]
[assembly: AssemblyTitle("dotoo_ime_input")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 dotoo_ime_input
{
	internal static class ImeCaret
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("dotoo_ime_input");

		private static bool created;

		private static IntPtr hwnd = IntPtr.Zero;

		[DllImport("user32.dll")]
		private static extern IntPtr GetActiveWindow();

		[DllImport("user32.dll")]
		private static extern bool CreateCaret(IntPtr hWnd, IntPtr hBitmap, int nWidth, int nHeight);

		[DllImport("user32.dll")]
		private static extern bool SetCaretPos(int x, int y);

		[DllImport("user32.dll")]
		private static extern bool ShowCaret(IntPtr hWnd);

		[DllImport("user32.dll")]
		private static extern bool DestroyCaret();

		internal static void Set(Vector2 pos)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!created)
				{
					hwnd = GetActiveWindow();
					if (hwnd == IntPtr.Zero)
					{
						Log.LogWarning((object)"caret: hwnd is zero");
						return;
					}
					created = CreateCaret(hwnd, IntPtr.Zero, 2, 20);
					ShowCaret(hwnd);
				}
				SetCaretPos(Mathf.RoundToInt(pos.x), Mathf.RoundToInt(pos.y));
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex.ToString());
			}
		}

		internal static void Destroy()
		{
			try
			{
				if (created)
				{
					DestroyCaret();
					created = false;
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex.ToString());
			}
		}
	}
	internal static class ImeComposition
	{
		internal static readonly ManualLogSource Log = Logger.CreateLogSource("dotoo_ime_input");

		internal static string Current = "";

		private static bool subscribed;

		internal static void Subscribe(bool on)
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				if (on && !subscribed)
				{
					current.onIMECompositionChange += OnChange;
					subscribed = true;
				}
				if (!on && subscribed)
				{
					current.onIMECompositionChange -= OnChange;
					subscribed = false;
					Current = "";
				}
			}
		}

		private unsafe static void OnChange(IMECompositionString s)
		{
			try
			{
				Current = ((object)(*(IMECompositionString*)(&s))/*cast due to .constrained prefix*/).ToString();
				PlayerLook instance = PlayerLook.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Traverse.Create((object)instance).Method("UpdateInputText", Array.Empty<object>()).GetValue();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex.ToString());
			}
		}
	}
	[HarmonyPatch(typeof(PlayerLook), "UpdateInputText")]
	internal static class ImeDisplayPatch
	{
		private static void Postfix(PlayerLook __instance)
		{
			try
			{
				if (!string.IsNullOrEmpty(ImeComposition.Current))
				{
					Traverse val = Traverse.Create((object)__instance);
					int value = val.Field("textChatInputLength").GetValue<int>();
					object value2 = val.Field("textChatInputText").GetValue();
					char[] value3 = Traverse.Create(typeof(PlayerLook)).Field("textChatInputBuffer").GetValue<char[]>();
					string text = new string(value3, 0, value) + ImeComposition.Current + "_";
					Traverse.Create(value2).Method("SetCharArray", new Type[3]
					{
						typeof(char[]),
						typeof(int),
						typeof(int)
					}, (object[])null).GetValue(new object[3]
					{
						text.ToCharArray(),
						0,
						text.Length
					});
				}
			}
			catch (Exception ex)
			{
				ImeComposition.Log.LogError((object)ex.ToString());
			}
		}
	}
	internal static class ImeCursor
	{
		private const string PluginGuid = "dotoo.ime_input";

		private static ConfigEntry<float> offsetX;

		private static ConfigEntry<float> offsetY;

		private static bool configTried;

		private static readonly ManualLogSource Log = Logger.CreateLogSource("dotoo_ime_input");

		private static void EnsureConfig()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			if (configTried)
			{
				return;
			}
			configTried = true;
			try
			{
				if (!Chainloader.PluginInfos.TryGetValue("dotoo.ime_input", out var value) || (Object)(object)value.Instance == (Object)null)
				{
					Log.LogWarning((object)"config: plugin not found by GUID 'dotoo.ime_input' (using defaults)");
					return;
				}
				ConfigFile config = value.Instance.Config;
				offsetX = config.Bind<float>("Position", "OffsetX", 0f, new ConfigDescription("変換窓の横位置の調整(px)。プラスで右、マイナスで左。チャットを開き直すと反映される。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3000f, 3000f), Array.Empty<object>()));
				offsetY = config.Bind<float>("Position", "OffsetY", -280f, new ConfigDescription("変換窓の縦位置の調整(px)。プラスで下、マイナスで上。チャットを開き直すと反映される。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3000f, 3000f), Array.Empty<object>()));
			}
			catch (Exception ex)
			{
				Log.LogError((object)("config init failed: " + ex));
			}
		}

		internal static void Apply(PlayerLook look)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Invalid comparison between Unknown and I4
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Keyboard current = Keyboard.current;
				if (current == null || (Object)(object)look == (Object)null)
				{
					return;
				}
				EnsureConfig();
				float num = ((offsetX != null) ? offsetX.Value : 0f);
				float num2 = ((offsetY != null) ? offsetY.Value : (-280f));
				object value = Traverse.Create((object)look).Field("textChatInputText").GetValue();
				Component val = (Component)((value is Component) ? value : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Canvas componentInParent = val.GetComponentInParent<Canvas>();
				Camera val2 = null;
				if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode > 0)
				{
					val2 = (((Object)(object)componentInParent.worldCamera != (Object)null) ? componentInParent.worldCamera : Camera.main);
				}
				Vector3 val3 = val.transform.position;
				Transform transform = val.transform;
				RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val4 != (Object)null)
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					val4.GetWorldCorners(array);
					val3 = array[1];
				}
				Vector2 val5 = RectTransformUtility.WorldToScreenPoint(val2, val3);
				Vector2 val6 = default(Vector2);
				((Vector2)(ref val6))..ctor(val5.x + num, (float)Screen.height - val5.y + num2);
				val6.x = Mathf.Clamp(val6.x, 0f, (float)Screen.width - 400f);
				val6.y = Mathf.Clamp(val6.y, 0f, (float)Screen.height - 40f);
				current.SetIMECursorPosition(val6);
				ImeCaret.Set(val6);
				try
				{
					Input.compositionCursorPos = val6;
				}
				catch (Exception)
				{
				}
			}
			catch (Exception ex2)
			{
				Log.LogError((object)ex2.ToString());
			}
		}
	}
	[HarmonyPatch(typeof(PlayerLook), "Update")]
	internal static class ImePatch
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("dotoo_ime_input");

		private static bool lastOpen;

		private static void Postfix(PlayerLook __instance)
		{
			try
			{
				bool isTextChatOpen = __instance.IsTextChatOpen;
				if (isTextChatOpen != lastOpen)
				{
					lastOpen = isTextChatOpen;
					Keyboard current = Keyboard.current;
					if (current != null)
					{
						current.SetIMEEnabled(isTextChatOpen);
					}
					Input.imeCompositionMode = (IMECompositionMode)(isTextChatOpen ? 1 : 0);
					ImeComposition.Subscribe(isTextChatOpen);
					if (!isTextChatOpen)
					{
						ImeCaret.Destroy();
					}
					if (isTextChatOpen)
					{
						ImeCursor.Apply(__instance);
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)ex.ToString());
			}
		}
	}
	[BepInPlugin("dotoo.ime_input", "Dotoo IME Input", "1.0.0")]
	[MycoMod(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			new Harmony("dotoo.ime_input").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"dotoo_ime_input loaded");
		}
	}
}