Decompiled source of FastDialogue v0.2.1

FastDialogue.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("FastDialogue")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FastDialogue")]
[assembly: AssemblyTitle("FastDialogue")]
[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 FastDialogue
{
	internal static class Diag
	{
		internal static ManualLogSource Log;

		internal static bool Enabled = true;

		internal static void Write(string msg)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (Enabled && Log != null)
			{
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(6, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<DateTime>(DateTime.Now, "HH:mm:ss.fff");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" t=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Time.realtimeSinceStartup, "F2");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(msg);
				}
				log.LogInfo(val);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechController), "SetSpeechActive")]
	internal static class SetSpeechActivePatch
	{
		private static readonly Dictionary<IntPtr, bool> _last = new Dictionary<IntPtr, bool>();

		private static void Postfix(SpeechController __instance, bool val)
		{
			try
			{
				if (!_last.TryGetValue(((Il2CppObjectBase)__instance).Pointer, out var value) || value != val)
				{
					_last[((Il2CppObjectBase)__instance).Pointer] = val;
					int value2 = ((__instance.speechQueue != null) ? __instance.speechQueue.Count : (-1));
					Diag.Write($"SpeechController.SetSpeechActive({val}) em '{((Object)__instance).name}' fila={value2} speechDelay={__instance.speechDelay:F2}");
				}
			}
			catch (Exception ex)
			{
				Diag.Write("SetSpeechActivePatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(DialogButtonController), "SetSelectable")]
	internal static class SetSelectablePatch
	{
		private static void Postfix(DialogButtonController __instance, bool val)
		{
			try
			{
				Diag.Write($"DialogButtonController.SetSelectable({val}) em '{((Object)__instance).name}'");
			}
			catch (Exception ex)
			{
				Diag.Write("SetSelectablePatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechBubbleController), "Setup")]
	internal static class BubbleSetupPatch
	{
		private static void Postfix(SpeechBubbleController __instance)
		{
			try
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(79, 4);
				defaultInterpolatedStringHandler.AppendLiteral("SpeechBubbleController.Setup texto=\"");
				defaultInterpolatedStringHandler.AppendFormatted(__instance.actualString);
				defaultInterpolatedStringHandler.AppendLiteral("\" oncreenTime=");
				defaultInterpolatedStringHandler.AppendFormatted(__instance.oncreenTime, "F2");
				defaultInterpolatedStringHandler.AppendLiteral(" delayProgress=");
				defaultInterpolatedStringHandler.AppendFormatted(__instance.delayProgress, "F2");
				defaultInterpolatedStringHandler.AppendLiteral(" delay(queue)=");
				QueueElement speech = __instance.speech;
				defaultInterpolatedStringHandler.AppendFormatted((speech != null) ? new float?(speech.delay) : ((float?)null), "F2");
				Diag.Write(defaultInterpolatedStringHandler.ToStringAndClear());
			}
			catch (Exception ex)
			{
				Diag.Write("BubbleSetupPatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechBubbleController), "Update")]
	internal static class BubbleTracePatch
	{
		private static float _next;

		private static void Postfix(SpeechBubbleController __instance)
		{
			if (!Diag.Enabled || Time.realtimeSinceStartup < _next)
			{
				return;
			}
			try
			{
				InteractionController instance = InteractionController.Instance;
				if (!((Object)(object)instance == (Object)null) && instance.dialogMode && instance.talkingTo != null)
				{
					SpeechController speechController = instance.talkingTo.speechController;
					SpeechController speechController2 = __instance.speechController;
					if (!((Object)(object)speechController == (Object)null) && !((Object)(object)speechController2 == (Object)null) && !(((Il2CppObjectBase)speechController).Pointer != ((Il2CppObjectBase)speechController2).Pointer))
					{
						_next = Time.realtimeSinceStartup + 0.2f;
						int value = ((__instance.actualString != null) ? __instance.actualString.Length : 0);
						Diag.Write($"[bolha] len={value} stringReveal={__instance.stringReveal:F1} revealedChars={__instance.revealedChars} words={__instance.wordsRevealed} timeStamp={__instance.timeStamp:F2} oncreenTime={__instance.oncreenTime:F2} delayProgress={__instance.delayProgress:F2} fade={__instance.fadeProgress:F2} final={__instance.setFinalText} skip={Skip.IsTarget(speechController2)}");
					}
				}
			}
			catch (Exception ex)
			{
				Diag.Write("BubbleTracePatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechBubbleController), "OnDestroy")]
	internal static class BubbleDestroyPatch
	{
		private static void Prefix(SpeechBubbleController __instance)
		{
			try
			{
				Diag.Write($"SpeechBubbleController.OnDestroy setFinalText={__instance.setFinalText} stringReveal={__instance.stringReveal:F2} fade={__instance.fadeProgress:F2}");
			}
			catch (Exception ex)
			{
				Diag.Write("BubbleDestroyPatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(InteractionController), "SetDialog")]
	internal static class SetDialogPatch
	{
		private static void Postfix(bool val)
		{
			Diag.Write($"InteractionController.SetDialog({val})");
		}
	}
	[HarmonyPatch(typeof(InteractionController), "RefreshDialogOptions")]
	internal static class RefreshDialogOptionsPatch
	{
		private static void Postfix(InteractionController __instance)
		{
			try
			{
				Diag.Write("InteractionController.RefreshDialogOptions -> " + DialogWatch.DescribeOptions(__instance));
			}
			catch (Exception ex)
			{
				Diag.Write("RefreshDialogOptionsPatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(InteractionController), "Update")]
	internal static class DialogWatch
	{
		private static string _last;

		private static void Postfix(InteractionController __instance)
		{
			if (!Diag.Enabled)
			{
				return;
			}
			try
			{
				if (!__instance.dialogMode)
				{
					_last = null;
					return;
				}
				string text = Snapshot(__instance);
				if (text != _last)
				{
					Diag.Write("[watch] " + text);
					_last = text;
				}
			}
			catch (Exception ex)
			{
				Diag.Write("DialogWatch erro: " + ex.Message);
			}
		}

		private static string Snapshot(InteractionController ic)
		{
			string text = "sem speechController";
			Interactable talkingTo = ic.talkingTo;
			SpeechController val = ((talkingTo != null) ? talkingTo.speechController : null);
			if ((Object)(object)val != (Object)null)
			{
				int value = ((val.speechQueue != null) ? val.speechQueue.Count : (-1));
				string value2 = "sem actor";
				if ((Object)(object)val.actor != (Object)null)
				{
					value2 = $"isSpeaking={val.actor.isSpeaking} inConversation={val.actor.inConversation}";
				}
				text = $"speechActive={val.speechActive} fila={value} bolha={(Object)(object)val.activeSpeechBubble != (Object)null} endAfterThisSpeech={val.endAfterThisSpeech} {value2}";
			}
			return text + " | " + DescribeOptions(ic);
		}

		internal static string DescribeOptions(InteractionController ic)
		{
			List<DialogButtonController> dialogOptions = ic.dialogOptions;
			if (dialogOptions == null)
			{
				return "opções=null";
			}
			int num = 0;
			for (int i = 0; i < dialogOptions.Count; i++)
			{
				DialogButtonController val = dialogOptions[i];
				if ((Object)(object)val != (Object)null && val.selectable)
				{
					num++;
				}
			}
			return $"opções={dialogOptions.Count} selecionáveis={num}";
		}
	}
	[BepInPlugin("com.eckylise.fastdialogue", "FastDialogue", "0.2.1")]
	public class Plugin : BasePlugin
	{
		private static readonly Type[] SkipPatches = new Type[3]
		{
			typeof(SkipInputPatch),
			typeof(SkipBubblePatch),
			typeof(SkipBubbleDestroyPatch)
		};

		private static readonly Type[] DiagnosticPatches = new Type[8]
		{
			typeof(SetSpeechActivePatch),
			typeof(SetSelectablePatch),
			typeof(BubbleSetupPatch),
			typeof(BubbleTracePatch),
			typeof(BubbleDestroyPatch),
			typeof(SetDialogPatch),
			typeof(RefreshDialogOptionsPatch),
			typeof(DialogWatch)
		};

		public override void Load()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			Diag.Log = ((BasePlugin)this).Log;
			Diag.Enabled = ((BasePlugin)this).Config.Bind<bool>("Debug", "DiagnosticLogs", false, "Loga no console/LogOutput.log quando a fala começa/termina e quando as opções de diálogo liberam.").Value;
			Skip.Key = ((BasePlugin)this).Config.Bind<KeyCode>("Skip", "SkipKey", (KeyCode)323, "Tecla que pula a fala do NPC durante o diálogo (Mouse0 = botão esquerdo).").Value;
			Skip.WholeAnswer = ((BasePlugin)this).Config.Bind<bool>("Skip", "SkipWholeAnswer", false, "true: um clique pula a resposta inteira (todas as falas na fila). false: um clique por fala.").Value;
			Skip.MinVisibleSeconds = ((BasePlugin)this).Config.Bind<float>("Skip", "MinVisibleSeconds", 0.3f, "Tempo (s) que o texto completo fica na tela depois do clique, antes de sumir.").Value;
			Harmony val = new Harmony("com.eckylise.fastdialogue");
			Type[] skipPatches = SkipPatches;
			foreach (Type type in skipPatches)
			{
				val.CreateClassProcessor(type).Patch();
			}
			if (Diag.Enabled)
			{
				skipPatches = DiagnosticPatches;
				foreach (Type type2 in skipPatches)
				{
					val.CreateClassProcessor(type2).Patch();
				}
			}
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("FastDialogue carregado (diagnóstico ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Diag.Enabled ? "ligado" : "desligado");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
			}
			log.LogInfo(val2);
		}
	}
	internal static class Skip
	{
		internal static KeyCode Key = (KeyCode)323;

		internal static bool WholeAnswer = false;

		internal static float MinVisibleSeconds = 0.3f;

		internal static IntPtr Target;

		internal static bool IsTarget(SpeechController sc)
		{
			if (Target != IntPtr.Zero && (Object)(object)sc != (Object)null)
			{
				return ((Il2CppObjectBase)sc).Pointer == Target;
			}
			return false;
		}

		internal static void Clear(string reason)
		{
			if (!(Target == IntPtr.Zero))
			{
				Target = IntPtr.Zero;
				Diag.Write("[skip] desligado (" + reason + ")");
			}
		}
	}
	[HarmonyPatch(typeof(InteractionController), "Update")]
	internal static class SkipInputPatch
	{
		private const float IgnoreAfterOptionsSeconds = 0.15f;

		private static float _optionsLastSeen;

		private static void Postfix(InteractionController __instance)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<DialogButtonController> dialogOptions = __instance.dialogOptions;
				if (dialogOptions != null && dialogOptions.Count > 0)
				{
					_optionsLastSeen = Time.realtimeSinceStartup;
				}
				if (!__instance.dialogMode)
				{
					Skip.Clear("saiu do diálogo");
					return;
				}
				Interactable talkingTo = __instance.talkingTo;
				SpeechController val = ((talkingTo != null) ? talkingTo.speechController : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				int num = ((val.speechQueue != null) ? val.speechQueue.Count : 0);
				if (!val.speechActive && num <= 0)
				{
					Skip.Clear("fala terminou");
				}
				else if (Skip.Target == IntPtr.Zero && Input.GetKeyDown(Skip.Key))
				{
					bool flag = (Object)(object)val.activeSpeechBubble != (Object)null;
					bool flag2 = Time.realtimeSinceStartup - _optionsLastSeen > 0.15f;
					if (!flag || !flag2)
					{
						Diag.Write($"[skip] clique ignorado (bolha={flag} opçõesSumiram={flag2})");
					}
					else
					{
						Skip.Target = ((Il2CppObjectBase)val).Pointer;
						Diag.Write($"[skip] clique: pulando fala de '{((Object)val).name}' (fila={num})");
					}
				}
			}
			catch (Exception ex)
			{
				Diag.Write("SkipInputPatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechBubbleController), "Update")]
	internal static class SkipBubblePatch
	{
		private static void Prefix(SpeechBubbleController __instance)
		{
			try
			{
				if (Skip.IsTarget(__instance.speechController))
				{
					int num = __instance.actualString?.Length ?? 0;
					if (__instance.stringReveal < (float)num)
					{
						__instance.stringReveal = num;
					}
					if (__instance.oncreenTime > Skip.MinVisibleSeconds)
					{
						__instance.oncreenTime = Skip.MinVisibleSeconds;
					}
				}
			}
			catch (Exception ex)
			{
				Diag.Write("SkipBubblePatch erro: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(SpeechBubbleController), "OnDestroy")]
	internal static class SkipBubbleDestroyPatch
	{
		private static void Prefix(SpeechBubbleController __instance)
		{
			try
			{
				if (!Skip.WholeAnswer && Skip.IsTarget(__instance.speechController))
				{
					Skip.Clear("balão pulado terminou");
				}
			}
			catch (Exception ex)
			{
				Diag.Write("SkipBubbleDestroyPatch erro: " + ex.Message);
			}
		}
	}
}