Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HaesServerMessages v1.6.2
HaesServerMessages.dll
Decompiled 2 months agousing 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 { } } }