Decompiled source of XPShared v0.3.4

XPRising.XPShared.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Bloodstone.API;
using Bloodstone.Hooks;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Network;
using ProjectM.UI;
using Stunlock.Network;
using Unity.Collections;
using Unity.Entities;
using XPShared.BloodstoneExtensions;
using XPShared.Transport;
using XPShared.Transport.Messages;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("XPRising.XPShared")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Framework for transport between server and client for XPRising ClientUI")]
[assembly: AssemblyFileVersion("0.3.4.0")]
[assembly: AssemblyInformationalVersion("0.3.4+1.Branch.main.Sha.cc4004fabbd61aa88089f9eaf54b839fcb80fcc5.cc4004fabbd61aa88089f9eaf54b839fcb80fcc5")]
[assembly: AssemblyProduct("XPRising.XPShared")]
[assembly: AssemblyTitle("XPRising.XPShared")]
[assembly: AssemblyVersion("0.3.4.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
namespace XPShared
{
	public class FrameTimer
	{
		private bool _enabled;

		private bool _isRunning;

		private bool _runOnce;

		private DateTime _executeAfter = DateTime.MinValue;

		private DateTime _lastExecution = DateTime.MinValue;

		private TimeSpan _delay;

		private Action _action;

		private Func<TimeSpan> _delayGenerator;

		public TimeSpan TimeSinceLastRun => DateTime.Now - _lastExecution;

		public bool Enabled => _enabled;

		public FrameTimer Initialise(Action action, TimeSpan delay, bool runOnce = true)
		{
			_delayGenerator = null;
			_delay = delay;
			_executeAfter = DateTime.Now + delay;
			_action = action;
			_runOnce = runOnce;
			return this;
		}

		public FrameTimer Initialise(Action action, Func<TimeSpan> delayGenerator, bool runOnce = true)
		{
			_delayGenerator = delayGenerator;
			_delay = _delayGenerator();
			_executeAfter = DateTime.Now + _delay;
			_action = action;
			_runOnce = runOnce;
			return this;
		}

		public void Start()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			Refresh();
			if (!_enabled)
			{
				_lastExecution = DateTime.MinValue;
				GameFrame.OnUpdate += new GameFrameUpdateEventHandler(GameFrame_OnUpdate);
				_enabled = true;
			}
		}

		public void Stop()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (_enabled)
			{
				GameFrame.OnUpdate -= new GameFrameUpdateEventHandler(GameFrame_OnUpdate);
				_enabled = false;
			}
		}

		private void Refresh()
		{
			if (_delayGenerator != null)
			{
				_delay = _delayGenerator();
			}
			_executeAfter = DateTime.Now + _delay;
		}

		private void GameFrame_OnUpdate()
		{
			Update();
		}

		private void Update()
		{
			if (!_enabled || _isRunning || _executeAfter >= DateTime.Now)
			{
				return;
			}
			_isRunning = true;
			try
			{
				_action();
				_lastExecution = DateTime.Now;
			}
			catch (Exception ex)
			{
				Plugin.Log((LogLevel)2, "Timer failed " + ex.Message + "\n" + ex.StackTrace);
				_runOnce = true;
				Stop();
			}
			finally
			{
				if (_runOnce)
				{
					Stop();
				}
				else
				{
					Refresh();
				}
				_isRunning = false;
			}
		}
	}
	[BepInPlugin("XPRising.XPShared", "XPRising.XPShared", "0.3.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		private static ManualLogSource _logger;

		public static bool IsDebug { get; private set; }

		public override void Load()
		{
			_logger = ((BasePlugin)this).Log;
			if (VWorld.IsClient)
			{
				ClientChat.Initialize();
			}
			MessageHandler.RegisterClientAction();
			MessageUtils.RegisterClientInitialisationType();
			IsDebug = typeof(Plugin).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration == "Debug";
			MessageUtils.OnClientConnectionEvent += delegate(User character)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				MessageHandler.ServerReceiveFromClient(character, new ClientAction(ClientAction.ActionType.Connect, ""));
			};
			Log((LogLevel)16, "Plugin is loaded [version: 0.3.4]");
		}

		public override bool Unload()
		{
			if (VWorld.IsClient)
			{
				ClientChat.Uninitialize();
			}
			MessageHandler.UnregisterClientAction();
			MessageUtils.UnregisterClientInitialisationType();
			return true;
		}

		public static void Log(LogLevel level, string message)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (IsDebug || (int)level <= 16)
			{
				ManualLogSource logger = _logger;
				bool flag = default(bool);
				BepInExLogInterpolatedStringHandler val = new BepInExLogInterpolatedStringHandler(13, 2, level, ref flag);
				if (flag)
				{
					val.AppendFormatted<DateTime>(DateTime.Now, "u");
					val.AppendLiteral(": [XPShared] ");
					val.AppendFormatted<string>(message);
				}
				logger.Log(level, val);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "XPRising.XPShared";

		public const string PLUGIN_NAME = "XPRising.XPShared";

		public const string PLUGIN_VERSION = "0.3.4";
	}
}
namespace XPShared.Transport
{
	public delegate void ServerMessageHandler(User fromCharacter, ClientAction msg);
	public class MessageHandler
	{
		public static event ServerMessageHandler OnServerMessageEvent;

		public static void RegisterClientAction()
		{
			Plugin.Log((LogLevel)4, "Registering ClientAction");
			VNetworkRegistry.RegisterServerbound<ClientAction>((Action<FromCharacter, ClientAction>)delegate(FromCharacter fromCharacter, ClientAction msg)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				EntityManager entityManager = VWorld.Server.EntityManager;
				ServerReceiveFromClient(((EntityManager)(ref entityManager)).GetComponentData<User>(fromCharacter.User), msg);
			});
		}

		public static void UnregisterClientAction()
		{
			Plugin.Log((LogLevel)32, "Unregistering ClientAction");
			VNetworkRegistry.Unregister<ClientAction>();
		}

		public static void ClientSendToServer(ClientAction message)
		{
			Plugin.Log((LogLevel)32, $"[CLIENT] [SEND] ClientAction: [{message.Action}] [{message.Value}]");
			VNetwork.SendToServer((VNetworkMessage)(object)message);
		}

		public static void ServerSendToClient<T>(User toCharacter, T msg) where T : VNetworkChatMessage
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log((LogLevel)32, $"[SERVER] [SEND] {msg.GetType()}");
			MessageUtils.SendToClient(toCharacter, msg);
		}

		internal static void ServerReceiveFromClient(User fromCharacter, ClientAction msg)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log((LogLevel)32, $"[SERVER] [RECEIVED] ClientAction {msg.Action} {msg.Value}");
			MessageHandler.OnServerMessageEvent?.Invoke(fromCharacter, msg);
		}
	}
	public static class Utils
	{
		public static void ServerSetBarData(User playerCharacter, string barGroup, string bar, string header, float progressPercentage, string tooltip, ProgressSerialisedMessage.ActiveState activeState, string colour, string change = "")
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ProgressSerialisedMessage msg = new ProgressSerialisedMessage
			{
				Group = barGroup,
				Label = bar,
				ProgressPercentage = progressPercentage,
				Header = header,
				Tooltip = tooltip,
				Active = activeState,
				Colour = colour,
				Change = change,
				Flash = (change != "")
			};
			MessageHandler.ServerSendToClient(playerCharacter, msg);
		}

		public static void ServerSetAction(User playerCharacter, string group, string id, string label, string colour = "#808080")
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			ActionSerialisedMessage msg = new ActionSerialisedMessage
			{
				Group = group,
				ID = id,
				Label = label,
				Colour = colour
			};
			MessageHandler.ServerSendToClient(playerCharacter, msg);
		}

		public static void ServerSendNotification(User playerCharacter, string id, string message, LogLevel severity, string colourOverride = "")
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			NotificationMessage msg = new NotificationMessage
			{
				ID = id,
				Message = message,
				Severity = severity,
				Colour = colourOverride
			};
			MessageHandler.ServerSendToClient(playerCharacter, msg);
		}

		public static void SendClientInitialisation()
		{
			MessageUtils.InitialiseClient();
		}
	}
}
namespace XPShared.Transport.Messages
{
	public class ActionSerialisedMessage : VNetworkChatMessage
	{
		public string Group = "";

		public string ID = "";

		public string Label = "";

		public string Colour = "#808080";

		public bool Enabled = true;

		public void Serialize(BinaryWriter writer)
		{
			writer.Write(Group);
			writer.Write(ID);
			writer.Write(Label);
			writer.Write(Colour);
			writer.Write(Enabled);
		}

		public void Deserialize(BinaryReader reader)
		{
			Group = reader.ReadString();
			ID = reader.ReadString();
			Label = reader.ReadString();
			Colour = reader.ReadString();
			Enabled = reader.ReadBoolean();
		}
	}
	public class ClientAction : VNetworkMessage
	{
		public enum ActionType
		{
			Connect,
			Disconnect,
			ButtonClick
		}

		public ActionType Action { get; private set; }

		public string Value { get; private set; }

		public ClientAction()
		{
			Value = "";
		}

		public ClientAction(ActionType actionType, string value)
		{
			Action = actionType;
			Value = value;
		}

		public void Deserialize(NetBufferIn reader)
		{
			Action = Enum.Parse<ActionType>(((NetBufferIn)(ref reader)).ReadString((Allocator)2));
			Value = ((NetBufferIn)(ref reader)).ReadString((Allocator)2);
		}

		public void Serialize(ref NetBufferOut writer)
		{
			((NetBufferOut)(ref writer)).Write(Enum.GetName(Action), (Allocator)2);
			((NetBufferOut)(ref writer)).Write(Value, (Allocator)2);
		}
	}
	public class ConnectedMessage : VNetworkChatMessage
	{
		public void Serialize(BinaryWriter writer)
		{
		}

		public void Deserialize(BinaryReader reader)
		{
		}
	}
	public class NotificationMessage : VNetworkChatMessage
	{
		public string ID = "";

		public string Message = "";

		public LogLevel Severity = (LogLevel)8;

		public string Colour = "";

		public void Serialize(BinaryWriter writer)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected I4, but got Unknown
			writer.Write(ID);
			writer.Write(Message);
			writer.Write((int)Severity);
			writer.Write(Colour);
		}

		public void Deserialize(BinaryReader reader)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ID = reader.ReadString();
			Message = reader.ReadString();
			Severity = (LogLevel)reader.ReadInt32();
			Colour = reader.ReadString();
		}
	}
	public class ProgressSerialisedMessage : VNetworkChatMessage
	{
		public enum ActiveState
		{
			Unchanged,
			NotActive,
			Active,
			OnlyActive
		}

		public string Group = "";

		public string Label = "";

		public string Header = "";

		public float ProgressPercentage;

		public string Tooltip = "";

		public ActiveState Active;

		public string Change = "";

		public string Colour = "";

		public bool Flash;

		public void Serialize(BinaryWriter writer)
		{
			writer.Write(Group);
			writer.Write(Label);
			writer.Write(Header);
			writer.Write(ProgressPercentage);
			writer.Write(Tooltip);
			writer.Write((int)Active);
			writer.Write(Change);
			writer.Write(Colour);
			writer.Write(Flash);
		}

		public void Deserialize(BinaryReader reader)
		{
			Group = reader.ReadString();
			Label = reader.ReadString();
			Header = reader.ReadString();
			ProgressPercentage = reader.ReadSingle();
			Tooltip = reader.ReadString();
			Active = (ActiveState)reader.ReadInt32();
			Change = reader.ReadString();
			Colour = reader.ReadString();
			Flash = reader.ReadBoolean();
		}
	}
}
namespace XPShared.BloodstoneExtensions
{
	public static class ClientChat
	{
		private static Harmony? _harmony;

		public static void Initialize()
		{
			if (_harmony != null)
			{
				throw new Exception("Detour already initialized. You don't need to call this. The Bloodstone plugin will do it for you.");
			}
			_harmony = Harmony.CreateAndPatchAll(typeof(ClientChat), "XPRising.XPShared");
		}

		public static void Uninitialize()
		{
			if (_harmony == null)
			{
				throw new Exception("Detour wasn't initialized. Are you trying to unload Bloodstone twice?");
			}
			_harmony.UnpatchSelf();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ClientChatSystem), "OnUpdate")]
		private static void OnUpdatePrefix(ClientChatSystem __instance)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			EntityQuery receiveChatMessagesQuery = __instance._ReceiveChatMessagesQuery;
			Enumerator<Entity> enumerator = ((EntityQuery)(ref receiveChatMessagesQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)).GetEnumerator();
			while (enumerator.MoveNext())
			{
				Entity current = enumerator.Current;
				EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager;
				ChatMessageServerEvent componentData = ((EntityManager)(ref entityManager)).GetComponentData<ChatMessageServerEvent>(current);
				if ((int)componentData.MessageType == 6 && MessageUtils.DeserialiseMessage(((object)(FixedString512Bytes)(ref componentData.MessageText)).ToString()))
				{
					entityManager = ((ComponentSystemBase)__instance).EntityManager;
					((EntityManager)(ref entityManager)).DestroyEntity(current);
				}
			}
		}
	}
	internal class MessageChatRegistry
	{
		internal static Dictionary<string, RegisteredChatEventHandler> _eventHandlers = new Dictionary<string, RegisteredChatEventHandler>();

		internal static void Register<T>(RegisteredChatEventHandler handler)
		{
			string text = MessageUtils.DeriveKey(typeof(T));
			if (_eventHandlers.ContainsKey(text))
			{
				throw new Exception("Network event " + text + " is already registered");
			}
			_eventHandlers.Add(text, handler);
		}

		internal static void Unregister<T>()
		{
			string key = MessageUtils.DeriveKey(typeof(T));
			_eventHandlers.Remove(key);
		}
	}
	internal class RegisteredChatEventHandler
	{
		internal Action<BinaryReader> OnReceiveFromServer { get; init; }
	}
	public delegate void ClientConnectionMessageHandler(User fromCharacter);
	public static class MessageUtils
	{
		private struct ClientRegister
		{
			public int clientNonce;
		}

		private static readonly int ClientNonce = Random.Shared.Next();

		private static readonly Dictionary<ulong, int> SupportedUsers = new Dictionary<ulong, int>();

		public static event ClientConnectionMessageHandler? OnClientConnectionEvent;

		internal static string DeriveKey(Type name)
		{
			return name.ToString();
		}

		public static void InitialiseClient()
		{
			if (VWorld.IsServer)
			{
				throw new Exception("InitialiseClient can only be called on the client.");
			}
			ClientRegister clientRegister = default(ClientRegister);
			clientRegister.clientNonce = ClientNonce;
			VNetwork.SendToServerStruct<ClientRegister>(clientRegister);
		}

		public static void SendToClient<T>(User toCharacter, T msg) where T : VNetworkChatMessage
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log((LogLevel)32, "[SERVER] [SEND] VNetworkChatMessage");
			if (SupportedUsers.TryGetValue(toCharacter.PlatformId, out var value))
			{
				ServerChatUtils.SendSystemMessageToClient(VWorld.Server.EntityManager, toCharacter, SerialiseMessage(msg, value) ?? "");
			}
			else
			{
				Plugin.Log((LogLevel)32, "user nonce not present in supportedUsers");
			}
		}

		internal static void RegisterClientInitialisationType()
		{
			VNetworkRegistry.RegisterServerboundStruct<ClientRegister>((Action<FromCharacter, ClientRegister>)delegate(FromCharacter from, ClientRegister register)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				EntityManager entityManager = VWorld.Server.EntityManager;
				User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(from.User);
				SupportedUsers[componentData.PlatformId] = register.clientNonce;
				MessageUtils.OnClientConnectionEvent?.Invoke(componentData);
			});
		}

		internal static void UnregisterClientInitialisationType()
		{
			VNetworkRegistry.UnregisterStruct<ClientRegister>();
		}

		public static void RegisterType<T>(Action<T> onServerMessageEvent) where T : VNetworkChatMessage, new()
		{
			Action<T> onServerMessageEvent2 = onServerMessageEvent;
			MessageChatRegistry.Register<T>(new RegisteredChatEventHandler
			{
				OnReceiveFromServer = delegate(BinaryReader br)
				{
					T obj = new T();
					obj.Deserialize(br);
					onServerMessageEvent2(obj);
				}
			});
		}

		private static string SerialiseMessage<T>(T msg, int clientNonce) where T : VNetworkChatMessage
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter writer = new BinaryWriter(memoryStream);
			VNetworkChatMessage.WriteHeader(writer, DeriveKey(msg.GetType()), clientNonce);
			msg.Serialize(writer);
			return Convert.ToBase64String(memoryStream.ToArray());
		}

		internal static bool DeserialiseMessage(string message)
		{
			string type = "";
			try
			{
				using MemoryStream input = new MemoryStream(Convert.FromBase64String(message));
				using BinaryReader binaryReader = new BinaryReader(input);
				if (!VNetworkChatMessage.ReadHeader(binaryReader, out var clientNonce, out type))
				{
					return false;
				}
				if (clientNonce != ClientNonce)
				{
					Plugin.Log((LogLevel)4, $"ClientNonce did not match: [actual: {clientNonce}, expected: {ClientNonce}]");
					return true;
				}
				if (MessageChatRegistry._eventHandlers.TryGetValue(type, out var value))
				{
					value.OnReceiveFromServer(binaryReader);
				}
				return true;
			}
			catch (FormatException)
			{
				Plugin.Log((LogLevel)32, "Invalid base64");
				return false;
			}
			catch (Exception ex2)
			{
				Plugin.Log((LogLevel)2, "Error handling incoming network event " + type + ":");
				Plugin.Log((LogLevel)2, ex2.ToString());
				return false;
			}
		}
	}
	public interface VNetworkChatMessage
	{
		internal const int CHAT_NETWORK_EVENT_ID = 218160557;

		internal static void WriteHeader(BinaryWriter writer, string type, int clientNonce)
		{
			writer.Write(218160557);
			writer.Write(clientNonce);
			writer.Write(type);
		}

		internal static bool ReadHeader(BinaryReader reader, out int clientNonce, out string type)
		{
			type = "";
			clientNonce = 0;
			try
			{
				int num = reader.ReadInt32();
				clientNonce = reader.ReadInt32();
				type = reader.ReadString();
				return num == 218160557;
			}
			catch (Exception ex)
			{
				Plugin.Log((LogLevel)32, "Failed to read chat message header: " + ex.Message);
				return false;
			}
		}

		void Serialize(BinaryWriter writer);

		void Deserialize(BinaryReader reader);
	}
}