Decompiled source of KALI Welcome Rules v1.0.2

BepInEx/plugins/KALI_Welcome_Rules/FinallyWelcome.dll

Decompiled 19 hours ago
using 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;
			}
		}
	}
}