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 KALI Welcome Rules v1.0.2
BepInEx/plugins/KALI_Welcome_Rules/FinallyWelcome.dll
Decompiled 19 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FinallyWelcome")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("FinallyWelcome")] [assembly: AssemblyTitle("FinallyWelcome")] [assembly: AssemblyVersion("1.0.2.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; } } } [BepInPlugin("local.finally.welcome", "Finally Welcome", "1.0.2")] [BepInProcess("valheim_server.exe")] public sealed class FinallyWelcome : BaseUnityPlugin { private sealed class Delivery { public ZNetPeer Peer; public string Key; public int Step; public float Due; } private readonly HashSet<string> seen = new HashSet<string>(StringComparer.Ordinal); private readonly Dictionary<long, Delivery> pending = new Dictionary<long, Delivery>(); private string seenPath; private string[] rules; private float nextPoll; private int introKey; private void Awake() { string text = Path.Combine(Paths.ConfigPath, "FinallyWelcome"); Directory.CreateDirectory(text); seenPath = Path.Combine(text, "seen-players.txt"); rules = (from line in File.ReadAllLines(Path.Combine(text, "rules.txt")) where !string.IsNullOrWhiteSpace(line) select line).ToArray(); if (rules.Length != 6) { throw new InvalidDataException("Expected the six server rules in rules.txt."); } if (File.Exists(seenPath)) { string[] array = File.ReadAllLines(seenPath); foreach (string text2 in array) { if (!string.IsNullOrWhiteSpace(text2)) { seen.Add(text2.Trim()); } } } introKey = 438569 + ZSyncAnimation.GetHash("intro"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Ready: six rules, private first-join messages, no client mod required. Previously welcomed: " + seen.Count)); } private static string Identity(ZNetPeer peer) { string text = peer.m_socket.GetHostName(); if (string.IsNullOrWhiteSpace(text)) { return null; } if (ulong.TryParse(text, out var _)) { text = "Steam_" + text; } using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", ""); } private static string Wrap(string text) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; string[] array = text.Split(' '); foreach (string text2 in array) { if (num > 0 && num + text2.Length + 1 > 72) { stringBuilder.Append('\n'); num = 0; } if (num > 0) { stringBuilder.Append(' '); num++; } stringBuilder.Append(text2); num += text2.Length; } return stringBuilder.ToString(); } private void Update() { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < nextPoll) { return; } nextPoll = realtimeSinceStartup + 1f; if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZRoutedRpc.instance == null) { return; } try { Tick(realtimeSinceStartup); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); nextPoll = realtimeSinceStartup + 30f; } } private void Tick(float now) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) ZNetPeer[] array = ZNet.instance.GetPeers().ToArray(); long[] array2 = pending.Keys.ToArray(); foreach (long key in array2) { if (!array.Contains(pending[key].Peer)) { pending.Remove(key); } } ZNetPeer[] array3 = array; foreach (ZNetPeer val in array3) { if (val.m_server || !val.IsReady() || val.m_characterID == ZDOID.None) { continue; } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(val.m_characterID) : null); if (val2 == null) { continue; } if (!pending.TryGetValue(val.m_uid, out var value)) { string text = Identity(val); if (text == null || seen.Contains(text)) { continue; } value = new Delivery { Peer = val, Key = text, Due = now + 15f }; pending.Add(val.m_uid, value); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Welcome queued for " + val.m_playerName)); } if (val2.GetInt(introKey, 0) != 0) { value.Due = now + 15f; } else { if (now < value.Due) { continue; } if (value.Step > rules.Length) { File.AppendAllText(seenPath, value.Key + Environment.NewLine); seen.Add(value.Key); pending.Remove(val.m_uid); ((BaseUnityPlugin)this).Logger.LogInfo((object)("All six welcome rules sent to " + val.m_playerName)); continue; } string text2; if (value.Step == 0) { text2 = "<color=#FFD700>Welcome</color>"; } else { string text3 = rules[value.Step - 1]; string text4 = value.Step + ". "; if (text3.StartsWith(text4, StringComparison.Ordinal)) { text3 = text3.Substring(text4.Length); } text2 = "<color=#FFD700>Rule #" + value.Step + "</color>\n<size=24>" + Wrap(text3) + "</size>"; } ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, "ShowMessage", new object[2] { 2, text2 }); value.Step++; value.Due = now + 5f; } } } }