Decompiled source of KasetAltyazi v1.2.1

KasetAltyazi.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace KasetAltyazi;

[BepInPlugin("zirvekorku.kasetaltyazi", "Kaset Altyazi", "1.2.1")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	private void Awake()
	{
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Expected O, but got Unknown
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		List<Track> list = Track.LoadAll(directoryName, seen);
		list.AddRange(Track.LoadAll(Path.Combine(directoryName, "altyazilar"), seen));
		Dictionary<string, Track> dictionary = new Dictionary<string, Track>(StringComparer.OrdinalIgnoreCase);
		Dictionary<string, List<Track>> dictionary2 = new Dictionary<string, List<Track>>(StringComparer.OrdinalIgnoreCase);
		int num = 0;
		foreach (Track item in list)
		{
			if (!item.Sound)
			{
				dictionary[item.Key] = item;
				continue;
			}
			if (!dictionary2.TryGetValue(item.Key, out var value))
			{
				value = (dictionary2[item.Key] = new List<Track>());
			}
			value.Add(item);
			num++;
		}
		Log.LogInfo((object)("Loaded subtitles for " + dictionary.Count + " tapes and " + num + " sounds from " + directoryName));
		GameObject val = new GameObject("KasetAltyaziRunner");
		((Object)val).hideFlags = (HideFlags)61;
		Object.DontDestroyOnLoad((Object)(object)val);
		Runner runner = val.AddComponent<Runner>();
		runner.Tracks = dictionary;
		runner.Sounds = dictionary2;
		if (dictionary2.Count > 0 || runner.Dumping)
		{
			Harmony val2 = new Harmony("zirvekorku.kasetaltyazi");
			HarmonyMethod val3 = new HarmonyMethod(typeof(Runner).GetMethod("OnPlayOneShot"));
			val2.Patch((MethodBase)AccessTools.Method(typeof(AudioSource), "PlayOneShot", new Type[1] { typeof(AudioClip) }, (Type[])null), val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val2.Patch((MethodBase)AccessTools.Method(typeof(AudioSource), "PlayOneShot", new Type[2]
			{
				typeof(AudioClip),
				typeof(float)
			}, (Type[])null), val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
}
public class Cue
{
	public double Start;

	public double End;

	public string Text;
}
public class Track
{
	public string Key;

	public double Length = -1.0;

	public bool Sound;

	public List<Cue> Cues = new List<Cue>();

	public static List<Track> LoadAll(string dir, HashSet<string> seen)
	{
		List<Track> list = new List<Track>();
		if (!Directory.Exists(dir))
		{
			return list;
		}
		string[] files = Directory.GetFiles(dir, "*.alt");
		foreach (string path in files)
		{
			if (!seen.Add(Path.GetFileName(path)))
			{
				continue;
			}
			Track track = new Track();
			string key = Path.GetFileNameWithoutExtension(path);
			string[] array = File.ReadAllLines(path);
			foreach (string text in array)
			{
				string text2 = text.Trim();
				if (text2.Length == 0 || text2.StartsWith("#"))
				{
					continue;
				}
				if (text2.StartsWith("@length="))
				{
					track.Length = double.Parse(text2.Substring(8), CultureInfo.InvariantCulture);
					continue;
				}
				if (text2.StartsWith("@sound="))
				{
					track.Sound = true;
					key = text2.Substring(7);
					continue;
				}
				string[] array2 = text2.Split(new char[1] { '|' }, 3);
				if (array2.Length >= 3)
				{
					Cue cue = new Cue();
					cue.Start = double.Parse(array2[0], CultureInfo.InvariantCulture);
					cue.End = double.Parse(array2[1], CultureInfo.InvariantCulture);
					cue.Text = array2[2].Replace("\\n", "\n");
					track.Cues.Add(cue);
				}
			}
			track.Key = key;
			list.Add(track);
		}
		return list;
	}

	public bool Matches(double length)
	{
		if (!(Length < 0.0))
		{
			return Math.Abs(length - Length) < 1.5;
		}
		return true;
	}

	public static Track Find(Dictionary<string, List<Track>> tracks, AudioClip clip)
	{
		if ((Object)(object)clip == (Object)null || tracks == null || !tracks.TryGetValue(((Object)clip).name, out var value))
		{
			return null;
		}
		Track result = null;
		double num = double.MaxValue;
		foreach (Track item in value)
		{
			if (item.Matches(clip.length))
			{
				double num2 = ((item.Length < 0.0) ? 1.4 : Math.Abs((double)clip.length - item.Length));
				if (num2 < num)
				{
					result = item;
					num = num2;
				}
			}
		}
		return result;
	}

	public string TextAt(double time)
	{
		string text = null;
		for (int i = 0; i < Cues.Count; i++)
		{
			if (time >= Cues[i].Start && time < Cues[i].End)
			{
				text = ((text == null) ? Cues[i].Text : (text + "\n" + Cues[i].Text));
			}
		}
		return text;
	}
}
public class OneShot
{
	public AudioSource Source;

	public AudioClip Clip;

	public Track Track;

	public float Start;

	public float Pitch;
}
public class Runner : MonoBehaviour
{
	private const float MaxDistance = 50f;

	public Dictionary<string, Track> Tracks;

	public Dictionary<string, List<Track>> Sounds;

	private static Runner instance;

	private readonly List<VideoPlayer> players = new List<VideoPlayer>();

	private readonly List<AudioSource> voices = new List<AudioSource>();

	private readonly List<OneShot> oneShots = new List<OneShot>();

	private readonly HashSet<string> logged = new HashSet<string>();

	public bool Dumping;

	private float nextScan;

	private float nextSoundScan;

	private GameObject panel;

	private RectTransform panelRect;

	private TextMeshProUGUI label;

	private string shown;

	private void Awake()
	{
		instance = this;
	}

	public static void OnPlayOneShot(AudioSource __instance, AudioClip clip)
	{
		Runner runner = instance;
		if ((Object)(object)runner == (Object)null || (Object)(object)clip == (Object)null || (Object)(object)__instance == (Object)null)
		{
			return;
		}
		Track track = Track.Find(runner.Sounds, clip);
		if (track == null)
		{
			return;
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		foreach (OneShot oneShot2 in runner.oneShots)
		{
			if ((Object)(object)oneShot2.Source == (Object)(object)__instance && (Object)(object)oneShot2.Clip == (Object)(object)clip && realtimeSinceStartup - oneShot2.Start < 0.2f)
			{
				return;
			}
		}
		OneShot oneShot = new OneShot();
		oneShot.Source = __instance;
		oneShot.Clip = clip;
		oneShot.Track = track;
		oneShot.Start = realtimeSinceStartup;
		oneShot.Pitch = ((Mathf.Abs(__instance.pitch) < 0.01f) ? 1f : Mathf.Abs(__instance.pitch));
		runner.oneShots.Add(oneShot);
		runner.LogPlay("Sound", ((Object)clip).name, clip.length);
	}

	private void LogPlay(string kind, string name, double length)
	{
		if (logged.Add(kind + name))
		{
			Plugin.Log.LogInfo((object)(kind + " playing: '" + name + "' (" + length.ToString("0.0", CultureInfo.InvariantCulture) + " s)"));
		}
	}

	private void Update()
	{
		if (Time.unscaledTime >= nextScan && Tracks != null && Tracks.Count > 0)
		{
			nextScan = Time.unscaledTime + 1f;
			players.Clear();
			VideoPlayer[] array = Object.FindObjectsOfType<VideoPlayer>();
			foreach (VideoPlayer val in array)
			{
				if (!((Object)(object)val.clip == (Object)null))
				{
					bool flag = Tracks.ContainsKey(((Object)val.clip).name);
					if (flag)
					{
						players.Add(val);
					}
					if (val.isPlaying && logged.Add(((Object)val.clip).name))
					{
						Plugin.Log.LogInfo((object)("Video playing: '" + ((Object)val.clip).name + "' (" + val.clip.length.ToString("0.0", CultureInfo.InvariantCulture) + " s), subtitles: " + (flag ? "yes" : "no")));
					}
				}
			}
		}
		if (Time.unscaledTime >= nextSoundScan && Sounds != null && Sounds.Count > 0)
		{
			nextSoundScan = Time.unscaledTime + 0.5f;
			voices.Clear();
			AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>();
			foreach (AudioSource val2 in array2)
			{
				if (!((Object)(object)val2.clip == (Object)null) && Sounds.ContainsKey(((Object)val2.clip).name))
				{
					voices.Add(val2);
					if (val2.isPlaying)
					{
						LogPlay("Sound", ((Object)val2.clip).name, val2.clip.length);
					}
				}
			}
		}
		Show(CurrentText());
	}

	private string CurrentText()
	{
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		if (!TryGetEye(out var eye))
		{
			return null;
		}
		string result = null;
		float num = float.MaxValue;
		foreach (VideoPlayer player in players)
		{
			if ((Object)(object)player == (Object)null || !player.isPlaying || (Object)(object)player.clip == (Object)null || !Tracks.TryGetValue(((Object)player.clip).name, out var value) || !value.Matches(player.clip.length))
			{
				continue;
			}
			Vector3 val;
			if (!((Object)(object)player.targetMaterialRenderer != (Object)null))
			{
				val = ((Component)player).transform.position;
			}
			else
			{
				Bounds bounds = player.targetMaterialRenderer.bounds;
				val = ((Bounds)(ref bounds)).center;
			}
			Vector3 val2 = val;
			float num2 = Vector3.Distance(eye, val2);
			if (!(num2 > 50f) && !(num2 >= num))
			{
				string text = value.TextAt(player.time);
				if (text != null)
				{
					result = text;
					num = num2;
				}
			}
		}
		foreach (AudioSource voice in voices)
		{
			if ((Object)(object)voice == (Object)null || !voice.isPlaying || (Object)(object)voice.clip == (Object)null)
			{
				continue;
			}
			Track track = Track.Find(Sounds, voice.clip);
			if (track != null && Audible(voice, eye, out var dist) && !(dist >= num))
			{
				string text2 = track.TextAt(voice.time);
				if (text2 != null)
				{
					result = text2;
					num = dist;
				}
			}
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		for (int num3 = oneShots.Count - 1; num3 >= 0; num3--)
		{
			OneShot oneShot = oneShots[num3];
			double num4 = (realtimeSinceStartup - oneShot.Start) * oneShot.Pitch;
			float dist2;
			if ((Object)(object)oneShot.Source == (Object)null || (Object)(object)oneShot.Clip == (Object)null || num4 > (double)oneShot.Clip.length)
			{
				oneShots.RemoveAt(num3);
			}
			else if (Audible(oneShot.Source, eye, out dist2) && !(dist2 >= num))
			{
				string text3 = oneShot.Track.TextAt(num4);
				if (text3 != null)
				{
					result = text3;
					num = dist2;
				}
			}
		}
		return result;
	}

	private static bool Audible(AudioSource s, Vector3 ear, out float dist)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		dist = 0f;
		if (s.mute || s.volume <= 0.01f)
		{
			return false;
		}
		if (s.spatialBlend < 0.5f)
		{
			return true;
		}
		dist = Vector3.Distance(ear, ((Component)s).transform.position);
		return dist <= Mathf.Max(s.maxDistance, 5f);
	}

	private static bool TryGetEye(out Vector3 eye)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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)
		//IL_003a: 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)
		eye = Vector3.zero;
		if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.activeCamera != (Object)null)
		{
			eye = ((Component)StartOfRound.Instance.activeCamera).transform.position;
			return true;
		}
		if ((Object)(object)Camera.main != (Object)null)
		{
			eye = ((Component)Camera.main).transform.position;
			return true;
		}
		return false;
	}

	private void Show(string text)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		if (text == shown)
		{
			return;
		}
		shown = text;
		if (text == null)
		{
			if ((Object)(object)panel != (Object)null)
			{
				panel.SetActive(false);
			}
			return;
		}
		if ((Object)(object)panel == (Object)null)
		{
			Build();
		}
		panel.SetActive(true);
		((TMP_Text)label).text = text;
		((TMP_Text)label).ForceMeshUpdate(false, false);
		panelRect.sizeDelta = new Vector2(panelRect.sizeDelta.x, ((TMP_Text)label).preferredHeight + 18f);
	}

	private void Build()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: 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_0137: 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_014d: Expected O, but got Unknown
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("KasetAltyaziCanvas");
		((Object)val).hideFlags = (HideFlags)61;
		Object.DontDestroyOnLoad((Object)(object)val);
		Canvas val2 = val.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)0;
		val2.sortingOrder = 400;
		CanvasScaler val3 = val.AddComponent<CanvasScaler>();
		val3.uiScaleMode = (ScaleMode)1;
		val3.referenceResolution = new Vector2(1920f, 1080f);
		panel = new GameObject("Panel");
		panel.transform.SetParent(val.transform, false);
		Image val4 = panel.AddComponent<Image>();
		((Graphic)val4).color = new Color(0f, 0f, 0f, 0.6f);
		((Graphic)val4).raycastTarget = false;
		panelRect = panel.GetComponent<RectTransform>();
		panelRect.anchorMin = new Vector2(0.5f, 0f);
		panelRect.anchorMax = new Vector2(0.5f, 0f);
		panelRect.pivot = new Vector2(0.5f, 0f);
		panelRect.anchoredPosition = new Vector2(0f, 150f);
		panelRect.sizeDelta = new Vector2(1300f, 80f);
		GameObject val5 = new GameObject("Text");
		val5.transform.SetParent(panel.transform, false);
		label = val5.AddComponent<TextMeshProUGUI>();
		if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.chatText != (Object)null)
		{
			((TMP_Text)label).font = ((TMP_Text)HUDManager.Instance.chatText).font;
		}
		((TMP_Text)label).fontSize = 30f;
		((Graphic)label).color = Color.white;
		((TMP_Text)label).alignment = (TextAlignmentOptions)514;
		((TMP_Text)label).enableWordWrapping = true;
		((Graphic)label).raycastTarget = false;
		RectTransform component = val5.GetComponent<RectTransform>();
		component.anchorMin = Vector2.zero;
		component.anchorMax = Vector2.one;
		component.offsetMin = new Vector2(20f, 8f);
		component.offsetMax = new Vector2(-20f, -8f);
	}
}