Decompiled source of TurnTimerPlugin v1.1.1

TurnTimerPlugin.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Bounce.Singletons;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TurnTimerPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Nth Dimension")]
[assembly: AssemblyProduct("TurnTimerPlugin")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("TurnTimerPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("1.1.1.0")]
namespace LordAshes;

[BepInPlugin("org.lordashes.plugins.turntimer", "Turn Timer Plug-In", "1.1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class TurnTimerPlugin : BaseUnityPlugin
{
	public static class Utility
	{
		public static void PostOnMainPage(MemberInfo plugin)
		{
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
			{
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				try
				{
					if (((Scene)(ref scene)).name == "UI")
					{
						TextMeshProUGUI uITextByName = GetUITextByName("BETA");
						if (Object.op_Implicit((Object)(object)uITextByName))
						{
							((TMP_Text)uITextByName).text = "INJECTED BUILD - unstable mods";
						}
					}
					else
					{
						TextMeshProUGUI uITextByName2 = GetUITextByName("TextMeshPro Text");
						if (Object.op_Implicit((Object)(object)uITextByName2))
						{
							BepInPlugin val = (BepInPlugin)Attribute.GetCustomAttribute(plugin, typeof(BepInPlugin));
							if (((TMP_Text)uITextByName2).text.EndsWith("</size>"))
							{
								((TMP_Text)uITextByName2).text = ((TMP_Text)uITextByName2).text + "\n\nMods Currently Installed:\n";
							}
							TextMeshProUGUI val2 = uITextByName2;
							((TMP_Text)val2).text = ((TMP_Text)val2).text + "\nLord Ashes' " + val.Name + " - " + val.Version;
						}
					}
				}
				catch (Exception ex)
				{
					Debug.Log((object)ex);
				}
			};
		}

		public static bool isBoardLoaded()
		{
			return SimpleSingletonBehaviour<CameraController>.HasInstance && SingletonStateMBehaviour<BoardSessionManager, State<BoardSessionManager>>.HasInstance && !BoardSessionManager.IsLoading;
		}

		public static bool StrictKeyCheck(KeyboardShortcut check)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!((KeyboardShortcut)(ref check)).IsUp())
			{
				return false;
			}
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			KeyCode[] array2 = (KeyCode[])(object)array;
			foreach (KeyCode val in array2)
			{
				if (Input.GetKey(val) != ((KeyboardShortcut)(ref check)).Modifiers.Contains(val))
				{
					return false;
				}
			}
			return true;
		}

		private static TextMeshProUGUI GetUITextByName(string name)
		{
			TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
			for (int i = 0; i < array.Length; i++)
			{
				if (((Object)array[i]).name == name)
				{
					return array[i];
				}
			}
			return null;
		}

		public static string GetCreatureName(string name)
		{
			if (name.Contains("<"))
			{
				name = name.Substring(0, name.IndexOf("<"));
			}
			return name;
		}

		public static GameObject GetBaseLoader(CreatureGuid cid)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreatureBoardAsset val = null;
			CreaturePresenter.TryGetAsset(cid, ref val);
			if ((Object)(object)val != (Object)null)
			{
				CreatureBase match = null;
				StartWith(val, "_base", ref match);
				Transform match2 = null;
				Traverse(((Component)match).transform, "BaseLoader", ref match2);
				if ((Object)(object)match2 != (Object)null)
				{
					return ((Component)match2.GetChild(0)).gameObject;
				}
				Debug.LogWarning((object)"Light Plugin: Could Not Find Base Loader");
				return null;
			}
			return null;
		}

		public static GameObject GetAssetLoader(CreatureGuid cid)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreatureBoardAsset val = null;
			CreaturePresenter.TryGetAsset(cid, ref val);
			if ((Object)(object)val != (Object)null)
			{
				Transform match = null;
				StartWith(val, "_creatureRoot", ref match);
				Transform match2 = null;
				Traverse(match, "AssetLoader", ref match2);
				if ((Object)(object)match2 != (Object)null)
				{
					return ((Component)match2.GetChild(0)).gameObject;
				}
				Debug.LogWarning((object)"Light Plugin: Could Not Find Asset Loader");
				return null;
			}
			return null;
		}

		public static void StartWith<T>(CreatureBoardAsset asset, string seek, ref T match)
		{
			Type typeFromHandle = typeof(CreatureBoardAsset);
			match = default(T);
			foreach (FieldInfo runtimeField in typeFromHandle.GetRuntimeFields())
			{
				if (runtimeField.Name == seek)
				{
					match = (T)runtimeField.GetValue(asset);
					break;
				}
			}
		}

		public static void Traverse(Transform root, string seek, ref Transform match, string path = "")
		{
			path = path + ((Object)root).name + ".";
			Debug.Log((object)("Light Plugin: Found '" + path + "' (with " + root.childCount + " Children)"));
			if ((Object)(object)match != (Object)null)
			{
				return;
			}
			if (Convert.ToString(((Object)root).name) == Convert.ToString(seek))
			{
				match = root;
				return;
			}
			foreach (Transform item in ExtensionMethods.Children(root))
			{
				Traverse(item, seek, ref match, path);
				if ((Object)(object)match != (Object)null)
				{
					break;
				}
			}
		}

		public static float ParseFloat(string value)
		{
			return float.Parse(value, CultureInfo.InvariantCulture);
		}
	}

	public enum CounterType
	{
		countdown = -1,
		countup = 1
	}

	public class TimerEvent
	{
		[NonSerialized]
		public AudioClip audioClip = null;

		public int time { get; set; } = 0;


		public Color color { get; set; } = Color.Green;


		public string audioSource { get; set; } = "";

	}

	public class TimerSequence
	{
		public List<TimerEvent> sequence = new List<TimerEvent>();
	}

	public const string Name = "Turn Timer Plug-In";

	public const string Guid = "org.lordashes.plugins.turntimer";

	public const string Version = "1.1.1.0";

	private GUIStyle labelStyle = new GUIStyle();

	private Texture2D buttonStart = Image.LoadTexture("TurnTimer.Button.Start.png", (CacheType)999);

	private Texture2D buttonPause = Image.LoadTexture("TurnTimer.Button.Pause.png", (CacheType)999);

	private Texture2D buttonClose = Image.LoadTexture("TurnTimer.Button.Stop.png", (CacheType)999);

	private Texture2D buttonExpire = Image.LoadTexture("TurnTimer.Button.Expire.png", (CacheType)999);

	private Texture2D timerBackground = Image.LoadTexture("TurnTimer.Timer.Background.png", (CacheType)999);

	private bool isShowing = false;

	private bool isActive = false;

	private TimeSpan timerValue = default(TimeSpan);

	private TimerSequence timer = new TimerSequence();

	private ConfigEntry<KeyboardShortcut> triggerKey { get; set; }

	private ConfigEntry<int> timerVerticalOffset { get; set; }

	private ConfigEntry<bool> autoStartTimerOnPlayerCharacter { get; set; }

	private ConfigEntry<bool> autoStartTimerOnGMCharacter { get; set; }

	private ConfigEntry<bool> autoAdvanceInitiative { get; set; }

	private ConfigEntry<bool> logDiagnostics { get; set; }

	private CounterType direction { get; set; }

	private void Awake()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)("Turn Timer Plugin: " + ((object)this).GetType().AssemblyQualifiedName + " Active."));
		triggerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Toggle Timer Display", new KeyboardShortcut((KeyCode)116, (KeyCode[])(object)new KeyCode[1] { (KeyCode)305 }), (ConfigDescription)null);
		timerVerticalOffset = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "Timer Vertical Offset", 40, (ConfigDescription)null);
		autoAdvanceInitiative = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Auto Advance Initiative On Timout", false, (ConfigDescription)null);
		autoStartTimerOnPlayerCharacter = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Auto Restart Timer On Initiative To Player Character", true, (ConfigDescription)null);
		autoStartTimerOnGMCharacter = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Auto Restart Timer On Initiative To GM Character", false, (ConfigDescription)null);
		logDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Add Event Diagnostics Into Log", false, (ConfigDescription)null);
		labelStyle.fontSize = 16;
		labelStyle.fontStyle = (FontStyle)1;
		labelStyle.alignment = (TextAnchor)4;
		((MonoBehaviour)this).StartCoroutine(Timer());
		InitiativeManager.OnTurnSwitch += InitiativeTurnSwitch;
		Utility.PostOnMainPage(((object)this).GetType());
	}

	private void Update()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		if (Utility.isBoardLoaded() && Utility.StrictKeyCheck(triggerKey.Value))
		{
			if (LocalClient.IsInGmMode)
			{
				TimerStart(startTimer: false);
			}
			else
			{
				SystemMessage.DisplayInfoText("Don't Even Think Of\r\nTouching The GM's Timer!", 2.5f, 0f);
			}
		}
	}

	private void OnGUI()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		if (!isShowing)
		{
			return;
		}
		if (timerValue.TotalSeconds < 0.0)
		{
			timerValue = new TimeSpan(0, 0, 0);
		}
		GUI.DrawTexture(new Rect(0f, (float)timerVerticalOffset.Value, (float)Screen.width, (float)(labelStyle.fontSize * 2)), (Texture)(object)timerBackground, (ScaleMode)0);
		GUI.Label(new Rect(0f, (float)(timerVerticalOffset.Value + labelStyle.fontSize / 2), (float)Screen.width, (float)labelStyle.fontSize), timerValue.Minutes.ToString("00") + ":" + timerValue.Seconds.ToString("00"), labelStyle);
		if (!LocalClient.IsInGmMode)
		{
			return;
		}
		if (GUI.Button(new Rect((float)(Screen.width / 2 - 122), (float)(timerVerticalOffset.Value + labelStyle.fontSize / 2 - 8), 32f, 32f), (Texture)(object)buttonStart))
		{
			TimerStart(startTimer: true);
		}
		if (timer.sequence.Count > 0)
		{
			if (GUI.Button(new Rect((float)(Screen.width / 2 - 86), (float)(timerVerticalOffset.Value + labelStyle.fontSize / 2 - 8), 32f, 32f), (Texture)(object)buttonPause))
			{
				TimerPause();
			}
			if (GUI.Button(new Rect((float)(Screen.width / 2 + 54), (float)(timerVerticalOffset.Value + labelStyle.fontSize / 2 - 8), 32f, 32f), (Texture)(object)buttonExpire))
			{
				TimerExpire();
			}
		}
		if (GUI.Button(new Rect((float)(Screen.width / 2 + 90), (float)(timerVerticalOffset.Value + labelStyle.fontSize / 2 - 8), 32f, 32f), (Texture)(object)buttonClose))
		{
			TimerClose();
		}
	}

	private void TimerStart(bool startTimer)
	{
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)"Turn Timer Plugin: Start Timer");
		timer = JsonConvert.DeserializeObject<TimerSequence>(File.ReadAllText("TurnTimer.json", (CacheType)999));
		labelStyle.normal.textColor = new Color((float)(int)timer.sequence[0].color.R / 255f, (float)(int)timer.sequence[0].color.G / 255f, (float)(int)timer.sequence[0].color.B / 255f, (float)(int)timer.sequence[0].color.A / 255f);
		timerValue = new TimeSpan(0, 0, timer.sequence[0].time);
		if (timer.sequence[0].time > 0)
		{
			direction = CounterType.countdown;
		}
		else
		{
			direction = CounterType.countup;
		}
		isActive = startTimer;
		isShowing = true;
	}

	private void TimerPause()
	{
		Debug.Log((object)("Turn Timer Plugin: Toggle Pause (isActive=" + !isActive + ")"));
		isActive = !isActive;
		isShowing = true;
	}

	private void TimerExpire()
	{
		Debug.Log((object)"Turn Timer Plugin: Expire Timer");
		timerValue = new TimeSpan(0, 0, timer.sequence[timer.sequence.Count - 1].time - 1);
		isActive = true;
		isShowing = true;
	}

	private void TimerClose()
	{
		Debug.Log((object)"Turn Timer Plugin: Timer Close");
		timerValue = new TimeSpan(0, 0, 0);
		isActive = false;
		isShowing = false;
	}

	private void InitiativeTurnSwitch(CreatureGuid cid)
	{
		//IL_0043: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		if (!isShowing)
		{
			return;
		}
		Debug.Log((object)("Turn Timer Plugin: Turn Initiative Switched To " + ((object)(CreatureGuid)(ref cid)).ToString()));
		bool flag = false;
		foreach (PlayerGuid key in CampaignSessionManager.PlayersInfo.Keys)
		{
			if (CreatureManager.DoesPlayerOwnCreature(key, cid) && !CampaignSessionManager.PlayersInfo[key].Rights.CanGm)
			{
				flag = true;
				break;
			}
		}
		Debug.Log((object)("Turn Timer Plugin: Player Owned = " + flag + ", AutoPlayer = " + autoStartTimerOnPlayerCharacter.Value + ", AutoGM = " + autoStartTimerOnGMCharacter.Value));
		if ((flag && autoStartTimerOnPlayerCharacter.Value) || (!flag && autoStartTimerOnGMCharacter.Value))
		{
			TimerStart(startTimer: true);
		}
	}

	private IEnumerator Timer()
	{
		while (true)
		{
			yield return (object)new WaitForSeconds(1f);
			if (!isActive)
			{
				continue;
			}
			timerValue = new TimeSpan(0, 0, (int)(timerValue.TotalSeconds + (double)direction));
			if ((timerValue.TotalSeconds >= (double)timer.sequence[timer.sequence.Count - 1].time && direction == CounterType.countup) || (timerValue.TotalSeconds <= 0.0 && direction == CounterType.countdown))
			{
				while (timer.sequence.Count > 1)
				{
					timer.sequence.RemoveAt(0);
				}
			}
			if ((!(timerValue.TotalSeconds >= (double)timer.sequence[0].time) || direction != CounterType.countup) && (!(timerValue.TotalSeconds <= (double)timer.sequence[0].time) || direction != CounterType.countdown))
			{
				continue;
			}
			if (logDiagnostics.Value)
			{
				Debug.Log((object)("Turn Timer Plugin: Triggering Event At " + timer.sequence[0].time + " Seconds (" + JsonConvert.SerializeObject((object)timer.sequence[0]) + ")"));
			}
			labelStyle.normal.textColor = new Color((float)(int)timer.sequence[0].color.R / 255f, (float)(int)timer.sequence[0].color.G / 255f, (float)(int)timer.sequence[0].color.B / 255f, (float)(int)timer.sequence[0].color.A / 255f);
			if (timer.sequence[0].audioSource != "")
			{
				((MonoBehaviour)this).StartCoroutine(PlayAudio(timer.sequence[0].audioSource));
			}
			timer.sequence.RemoveAt(0);
			if (timer.sequence.Count != 0)
			{
				continue;
			}
			isActive = false;
			if (!autoAdvanceInitiative.Value)
			{
				continue;
			}
			if (logDiagnostics.Value)
			{
				Debug.Log((object)"Turn Timer Plugin: Auto Advancing The Initiative Turn Order");
			}
			for (int i = 0; i < InitiativeManager.TurnQueueList.Count; i++)
			{
				CreatureGuid val = InitiativeManager.TurnQueueList[i];
				string? text = ((object)(CreatureGuid)(ref val)).ToString();
				val = InitiativeManager.CurrentTurnCreatureId;
				if (text == ((object)(CreatureGuid)(ref val)).ToString())
				{
					if (i + 1 < InitiativeManager.TurnQueueList.Count)
					{
						SimpleSingletonBehaviour<InitiativeManager>.Instance.SetCurrentCreature(InitiativeManager.TurnQueueList[i + 1]);
					}
					else
					{
						SimpleSingletonBehaviour<InitiativeManager>.Instance.SetCurrentCreature(InitiativeManager.TurnQueueList[0]);
					}
				}
			}
		}
	}

	private IEnumerator PlayAudio(string source)
	{
		AudioSource audio = ((Component)this).GetComponent<AudioSource>();
		if ((Object)(object)audio == (Object)null)
		{
			GameObject speaker = new GameObject();
			audio = speaker.AddComponent<AudioSource>();
		}
		string audioFile = File.Find(source, (CacheType)999)[0];
		string audioType = audioFile.Substring(audioFile.Length - 3).ToUpper();
		string text = audioType;
		UnityWebRequest req = ((!(text == "MP3")) ? UnityWebRequestMultimedia.GetAudioClip("file:///" + audioFile, (AudioType)20) : UnityWebRequestMultimedia.GetAudioClip("file:///" + audioFile, (AudioType)13));
		yield return req.SendWebRequest();
		if (logDiagnostics.Value)
		{
			Debug.Log((object)("Turn Timer Plugin: Loading " + audioFile));
		}
		audio.clip = DownloadHandlerAudioClip.GetContent(req);
		if (logDiagnostics.Value)
		{
			Debug.Log((object)("Turn Timer Plugin: Playing " + audioFile));
		}
		audio.Play();
	}
}