Decompiled source of HaesServerMessages v1.6.2

HaesServerMessages.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using UnityEngine;

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

[BepInPlugin("haes.servermessages", "HAES Server Messages", "1.6.2")]
public class HaesServerMessagesPlugin : BaseUnityPlugin
{
	private class PendingWelcome
	{
		public float FireAt;

		public long Uid;

		public string Text;
	}

	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	private static class ZRoutedRpc_Ctor_Patch
	{
		private static void Postfix(ZRoutedRpc __instance)
		{
			__instance.Register<string>("HAES_Msg", (Action<long, string>)RPC_HAES_Msg);
		}
	}

	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	private static class ZNet_RPC_PeerInfo_Patch
	{
		private static void Postfix(ZNet __instance, ZRpc rpc)
		{
			if ((Object)(object)__instance == (Object)null || !__instance.IsServer() || (Object)(object)Instance == (Object)null)
			{
				return;
			}
			ZNetPeer val = null;
			foreach (ZNetPeer peer in __instance.GetPeers())
			{
				if (peer.m_rpc == rpc)
				{
					val = peer;
					break;
				}
			}
			if (val != null)
			{
				string newValue = (string.IsNullOrEmpty(val.m_playerName) ? "" : val.m_playerName);
				string text = ((Instance._welcomeTemplate.Length > 0) ? Instance._welcomeTemplate.Replace("{name}", newValue) : "");
				string nextJoke = Instance.GetNextJoke();
				if (!string.IsNullOrEmpty(nextJoke))
				{
					text = ((text.Length > 0) ? (text + "\n" + nextJoke) : nextJoke);
				}
				if (text.Length != 0)
				{
					Instance._pendingWelcomes.Add(new PendingWelcome
					{
						FireAt = Time.time + Instance._welcomeDelaySeconds,
						Uid = val.m_uid,
						Text = text
					});
				}
			}
		}
	}

	[HarmonyPatch(typeof(MessageHud), "UpdateMessage")]
	private static class MessageHud_UpdateMessage_Patch
	{
		private static void Prefix(ref float dt)
		{
			if (Time.time < _holdUntil)
			{
				dt = 0f;
			}
		}
	}

	private const float HoldSeconds = 15f;

	public static HaesServerMessagesPlugin Instance;

	private Harmony _harmony;

	private readonly List<KeyValuePair<TimeSpan, string>> _schedule = new List<KeyValuePair<TimeSpan, string>>();

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

	private DateTime _lastCheckedDay = DateTime.MinValue;

	private string _scheduleFile;

	private DateTime _scheduleFileWriteTime = DateTime.MinValue;

	private float _reloadCheckTimer;

	private string _welcomeFile;

	private string _welcomeTemplate = "";

	private float _welcomeDelaySeconds = 5f;

	private DateTime _welcomeFileWriteTime = DateTime.MinValue;

	private readonly List<PendingWelcome> _pendingWelcomes = new List<PendingWelcome>();

	private string _jokesFile;

	private string _jokeIndexFile;

	private readonly List<string> _jokes = new List<string>();

	private int _jokeIndex;

	private DateTime _jokesFileWriteTime = DateTime.MinValue;

	private readonly Random _rng = new Random();

	private static FieldInfo _msgQueueTimerField;

	private static float _holdUntil;

	private void Awake()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		Instance = this;
		_harmony = new Harmony("haes.servermessages");
		_harmony.PatchAll();
		_scheduleFile = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), "haes_messages.txt");
		LoadSchedule();
		_welcomeFile = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), "haes_welcome.txt");
		LoadWelcome();
		_jokesFile = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), "haes_jokes.txt");
		_jokeIndexFile = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), "haes_joke_index.txt");
		LoadJokes();
		LoadJokeIndex();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"HAES Server Messages v1.6.2 loaded.");
	}

	private void LoadJokes()
	{
		_jokes.Clear();
		if (!File.Exists(_jokesFile))
		{
			File.WriteAllLines(_jokesFile, new string[6] { "# One joke per line. Shown one at a time to each joining player,", "# in order, looping back to the top when the list runs out.", "# Lines starting with # are ignored. Edit and save - picked up automatically.", "Why did the skeleton go to the party alone? He had no body to go with.", "I'd tell you a joke about Odin, but you might not get the reference.", "Why don't trolls share? They're boulder than that." });
		}
		string[] array = File.ReadAllLines(_jokesFile);
		foreach (string text in array)
		{
			string text2 = text.Trim();
			if (text2.Length != 0 && !text2.StartsWith("#"))
			{
				_jokes.Add(text2);
			}
		}
		Shuffle(_jokes);
		_jokesFileWriteTime = File.GetLastWriteTimeUtc(_jokesFile);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded " + _jokes.Count + " joke(s) from " + _jokesFile + " (shuffled)"));
		if (_jokeIndex >= _jokes.Count)
		{
			_jokeIndex = 0;
		}
	}

	private void Shuffle(List<string> list)
	{
		for (int num = list.Count - 1; num > 0; num--)
		{
			int index = _rng.Next(num + 1);
			string value = list[num];
			list[num] = list[index];
			list[index] = value;
		}
	}

	private void LoadJokeIndex()
	{
		_jokeIndex = 0;
		try
		{
			if (File.Exists(_jokeIndexFile) && int.TryParse(File.ReadAllText(_jokeIndexFile).Trim(), out var result) && result >= 0)
			{
				_jokeIndex = result;
			}
		}
		catch
		{
		}
		if (_jokes.Count > 0)
		{
			_jokeIndex %= _jokes.Count;
		}
	}

	private string GetNextJoke()
	{
		if (_jokes.Count == 0)
		{
			return null;
		}
		string result = _jokes[_jokeIndex];
		_jokeIndex++;
		if (_jokeIndex >= _jokes.Count)
		{
			_jokeIndex = 0;
			Shuffle(_jokes);
		}
		try
		{
			File.WriteAllText(_jokeIndexFile, _jokeIndex.ToString());
		}
		catch
		{
		}
		return result;
	}

	private void LoadWelcome()
	{
		if (!File.Exists(_welcomeFile))
		{
			File.WriteAllLines(_welcomeFile, new string[6] { "# HAES welcome message, shown only to the player who just joined.", "# {name} is replaced with the player's character name.", "# First line = delay in seconds after connecting before it's shown.", "# Second line = the message. Edit and save - picked up automatically.", "5", "Welcome to HAES, {name}!" });
		}
		string[] array = File.ReadAllLines(_welcomeFile);
		List<string> list = new List<string>();
		string[] array2 = array;
		foreach (string text in array2)
		{
			string text2 = text.Trim();
			if (text2.Length != 0 && !text2.StartsWith("#"))
			{
				list.Add(text2);
			}
		}
		_welcomeDelaySeconds = 5f;
		_welcomeTemplate = "";
		if (list.Count >= 1)
		{
			_welcomeDelaySeconds = (float.TryParse(list[0], out var result) ? result : 5f);
		}
		if (list.Count >= 2)
		{
			_welcomeTemplate = list[1];
		}
		_welcomeFileWriteTime = File.GetLastWriteTimeUtc(_welcomeFile);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Welcome message loaded (delay " + _welcomeDelaySeconds + "s): " + _welcomeTemplate));
	}

	private void LoadSchedule()
	{
		_schedule.Clear();
		if (!File.Exists(_scheduleFile))
		{
			File.WriteAllLines(_scheduleFile, new string[5] { "# HAES Server Messages", "# One line per message: HH:mm message text  (24-hour, this machine's local time)", "# Lines starting with # are ignored. Edit and save - picked up automatically, no restart needed.", "17:30 Server restarts in 60 minutes.", "18:29 Server restarts in 1 minute. Find somewhere safe!" });
		}
		string[] array = File.ReadAllLines(_scheduleFile);
		foreach (string text in array)
		{
			string text2 = text.Trim();
			if (text2.Length == 0 || text2.StartsWith("#"))
			{
				continue;
			}
			int num = text2.IndexOf(' ');
			if (num >= 0)
			{
				string s = text2.Substring(0, num);
				string text3 = text2.Substring(num + 1).Trim();
				if (TimeSpan.TryParse(s, out var result) && text3.Length > 0)
				{
					_schedule.Add(new KeyValuePair<TimeSpan, string>(result, text3));
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not parse schedule line: " + text));
				}
			}
		}
		_scheduleFileWriteTime = File.GetLastWriteTimeUtc(_scheduleFile);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded " + _schedule.Count + " scheduled message(s) from " + _scheduleFile));
	}

	private void Update()
	{
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return;
		}
		_reloadCheckTimer += Time.unscaledDeltaTime;
		if (_reloadCheckTimer > 10f)
		{
			_reloadCheckTimer = 0f;
			try
			{
				DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(_scheduleFile);
				if (lastWriteTimeUtc != _scheduleFileWriteTime)
				{
					LoadSchedule();
				}
				DateTime lastWriteTimeUtc2 = File.GetLastWriteTimeUtc(_welcomeFile);
				if (lastWriteTimeUtc2 != _welcomeFileWriteTime)
				{
					LoadWelcome();
				}
				DateTime lastWriteTimeUtc3 = File.GetLastWriteTimeUtc(_jokesFile);
				if (lastWriteTimeUtc3 != _jokesFileWriteTime)
				{
					LoadJokes();
				}
			}
			catch
			{
			}
		}
		if (_pendingWelcomes.Count > 0)
		{
			List<PendingWelcome> list = new List<PendingWelcome>();
			foreach (PendingWelcome pendingWelcome in _pendingWelcomes)
			{
				if (Time.time >= pendingWelcome.FireAt)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Sending welcome to peer " + pendingWelcome.Uid + ": " + pendingWelcome.Text));
					ZRoutedRpc.instance.InvokeRoutedRPC(pendingWelcome.Uid, "HAES_Msg", new object[1] { pendingWelcome.Text });
				}
				else
				{
					list.Add(pendingWelcome);
				}
			}
			_pendingWelcomes.Clear();
			_pendingWelcomes.AddRange(list);
		}
		DateTime now = DateTime.Now;
		if (now.Date != _lastCheckedDay)
		{
			_firedToday.Clear();
			_lastCheckedDay = now.Date;
		}
		TimeSpan timeOfDay = now.TimeOfDay;
		foreach (KeyValuePair<TimeSpan, string> item2 in _schedule)
		{
			string item = item2.Key.ToString();
			if (!_firedToday.Contains(item) && timeOfDay >= item2.Key && timeOfDay < item2.Key + TimeSpan.FromSeconds(20.0))
			{
				Broadcast(item2.Value);
				_firedToday.Add(item);
			}
		}
	}

	public void Broadcast(string text)
	{
		if (ZRoutedRpc.instance != null)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Broadcasting: " + text));
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "HAES_Msg", new object[1] { text });
		}
	}

	private static void RPC_HAES_Msg(long sender, string text)
	{
		if ((Object)(object)MessageHud.instance == (Object)null)
		{
			return;
		}
		_holdUntil = Time.time + 15f;
		MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, false);
		try
		{
			if (_msgQueueTimerField == null)
			{
				_msgQueueTimerField = typeof(MessageHud).GetField("m_msgQueueTimer", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if (_msgQueueTimerField != null)
			{
				float num = (float)_msgQueueTimerField.GetValue(MessageHud.instance);
				if (num < 15f)
				{
					_msgQueueTimerField.SetValue(MessageHud.instance, 15f);
				}
			}
		}
		catch
		{
		}
	}
}