Decompiled source of CodeYapper v2.1.0

plugins/CodeTalker.dll

Decompiled 15 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodeTalker;
using CodeTalker.Networking;
using CodeTalker.Packets;
using K4os.Compression.LZ4;
using Microsoft.CodeAnalysis;
using Mirror;
using Newtonsoft.Json;
using Steamworks;
using UnityEngine;
using ZstdSharp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Robyn+Soggy_Pancake")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+c62ba9dbcd8168ad1c7f570f8db53d2537b44fd2")]
[assembly: AssemblyProduct("CodeTalker")]
[assembly: AssemblyTitle("CodeTalker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
internal class BinaryPacketWrapper
{
	internal readonly byte[] FullPacketBytes;

	internal readonly string PacketSignature;

	internal BinaryPacketWrapper(string sig, byte[] rawData)
	{
		PacketSignature = sig;
		string cODE_TALKER_BINARY_SIGNATURE = CodeTalkerNetwork.CODE_TALKER_BINARY_SIGNATURE;
		byte[] bytes = Encoding.UTF8.GetBytes(sig);
		int num = cODE_TALKER_BINARY_SIGNATURE.Length + 1 + bytes.Length;
		byte[] array = new byte[num];
		Array.Copy(Encoding.ASCII.GetBytes(cODE_TALKER_BINARY_SIGNATURE), array, cODE_TALKER_BINARY_SIGNATURE.Length);
		array[cODE_TALKER_BINARY_SIGNATURE.Length] = (byte)bytes.Length;
		Array.Copy(bytes, 0, array, cODE_TALKER_BINARY_SIGNATURE.Length + 1, bytes.Length);
		FullPacketBytes = new byte[num + rawData.Length];
		Array.Copy(array, FullPacketBytes, array.Length);
		Array.Copy(rawData, 0, FullPacketBytes, num, rawData.Length);
	}

	internal BinaryPacketWrapper(byte[] rawPacketData)
	{
		int num = rawPacketData[0];
		PacketSignature = Encoding.UTF8.GetString(rawPacketData, 1, num);
		FullPacketBytes = rawPacketData[(num + 1)..];
	}
}
internal enum P2PPacketType : byte
{
	JSON,
	Binary
}
internal class P2PPacketWrapper
{
	internal readonly byte[] PacketBytes;

	internal readonly string PacketSignature;

	internal readonly P2PPacketType PacketType;

	internal readonly Compressors.CompressionType compression;

	internal readonly uint TargetNetId;

	internal P2PPacketWrapper(string sig, byte[] rawData, P2PPacketType packetType, Compressors.CompressionType compressionType, CompressionLevel compressionLevel, uint targetNetId = 0u)
	{
		PacketSignature = sig;
		PacketType = packetType;
		TargetNetId = targetNetId;
		string cODE_TALKER_P2P_SIGNATURE = CodeTalkerNetwork.CODE_TALKER_P2P_SIGNATURE;
		byte[] bytes = Encoding.UTF8.GetBytes(sig);
		int num = cODE_TALKER_P2P_SIGNATURE.Length + 1 + bytes.Length + 5;
		byte[] array = new byte[num];
		int num2 = 0;
		Array.Copy(Encoding.ASCII.GetBytes(cODE_TALKER_P2P_SIGNATURE), array, cODE_TALKER_P2P_SIGNATURE.Length);
		num2 += cODE_TALKER_P2P_SIGNATURE.Length;
		array[num2++] = (byte)bytes.Length;
		Array.Copy(bytes, 0, array, num2, bytes.Length);
		num2 += bytes.Length;
		array[num2++] = (byte)((uint)(((int)compressionType << 4) & 0xF0) + (uint)(packetType & (P2PPacketType)15));
		Array.Copy(BitConverter.GetBytes(targetNetId), 0, array, num2, 4);
		if (compressionType != 0)
		{
			rawData = Compressors.Compress(rawData, compressionType, compressionLevel);
		}
		PacketBytes = new byte[num + rawData.Length];
		Array.Copy(array, PacketBytes, array.Length);
		Array.Copy(rawData, 0, PacketBytes, num, rawData.Length);
	}

	internal P2PPacketWrapper(byte[] rawPacketData)
	{
		int num = rawPacketData[0];
		PacketSignature = Encoding.UTF8.GetString(rawPacketData, 1, num);
		int num2 = num + 1;
		PacketType = (P2PPacketType)(rawPacketData[num2] & 0xFu);
		compression = (Compressors.CompressionType)((rawPacketData[num2] >> 4) & 0xF);
		num2++;
		TargetNetId = BitConverter.ToUInt32(rawPacketData, num2);
		num2 += 4;
		PacketBytes = rawPacketData[num2..];
		if (compression != 0)
		{
			PacketBytes = Compressors.Decompress(PacketBytes, compression);
		}
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "CodeTalker";

	public const string PLUGIN_NAME = "CodeTalker";

	public const string PLUGIN_VERSION = "2.1.0";
}
namespace CodeTalker
{
	[BepInPlugin("CodeTalker", "CodeTalker", "2.1.0")]
	public class CodeTalkerPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Callback<LobbyChatMsg_t>? onNetworkMessage;

		internal static Callback<SteamNetworkingMessagesSessionRequest_t>? onSNMRequest;

		internal static ConfigEntry<bool> EnablePacketDebugging;

		private static bool steamIntialized;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			EnablePacketDebugging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debugging", "EnablePacketDebugging", false, "If CodeTalker should dump packet information (this will be on the debug channel, make sure that is enabled in BepInEx.cfg)");
			Log.LogInfo((object)"Plugin CodeTalker version 2.1.0 is loaded!");
			onNetworkMessage = Callback<LobbyChatMsg_t>.Create((DispatchDelegate<LobbyChatMsg_t>)CodeTalkerNetwork.OnNetworkMessage);
			onSNMRequest = Callback<SteamNetworkingMessagesSessionRequest_t>.Create((DispatchDelegate<SteamNetworkingMessagesSessionRequest_t>)CodeTalkerNetwork.OnSteamSessionRequest);
			Callback<SteamRelayNetworkStatus_t>.Create((DispatchDelegate<SteamRelayNetworkStatus_t>)OnSteamNetworkInitialized);
			Log.LogMessage((object)"Created steam networking callbacks");
		}

		private void OnSteamNetworkInitialized(SteamRelayNetworkStatus_t status)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!steamIntialized)
			{
				steamIntialized = (int)status.m_eAvail == 100;
				if (EnablePacketDebugging.Value)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)$"Steam Relay Network status update: {status.m_eAvail}");
				}
				if (steamIntialized)
				{
					SteamNetworkingUtils.InitRelayNetworkAccess();
				}
			}
		}

		private void Update()
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				IntPtr[] array = new IntPtr[10];
				int num = SteamNetworkingMessages.ReceiveMessagesOnChannel(0, array, array.Length);
				if (num <= 0)
				{
					return;
				}
				try
				{
					for (int i = 0; i < num; i++)
					{
						SteamNetworkingMessage_t val = Marshal.PtrToStructure<SteamNetworkingMessage_t>(array[i]);
						byte[] array2 = new byte[val.m_cbSize];
						Log.LogInfo((object)$"Recieved SNM packet of size {val.m_cbSize}");
						try
						{
							Marshal.Copy(val.m_pData, array2, 0, val.m_cbSize);
							CodeTalkerNetwork.HandleNetworkMessage(((SteamNetworkingIdentity)(ref val.m_identityPeer)).GetSteamID(), array2);
						}
						catch
						{
						}
						SteamNetworkingMessage_t.Release(array[i]);
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Error handling SteamNetworkingMessages message! " + ex));
				}
			}
			catch
			{
			}
		}
	}
	public static class Compressors
	{
		public enum CompressionType
		{
			None,
			Brotli,
			LZ4,
			ZStd,
			GZip
		}

		public static byte[] Compress(byte[] data, CompressionType type = CompressionType.Brotli, CompressionLevel level = CompressionLevel.Fastest)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			switch (type)
			{
			case CompressionType.Brotli:
			{
				MemoryStream memoryStream = new MemoryStream(data);
				MemoryStream memoryStream2 = new MemoryStream();
				BrotliStream brotliStream = new BrotliStream(memoryStream2, level);
				memoryStream.CopyTo(brotliStream);
				brotliStream.Close();
				brotliStream.DisposeAsync();
				return memoryStream2.ToArray();
			}
			case CompressionType.ZStd:
			{
				Compressor val = new Compressor((level == CompressionLevel.Fastest) ? 3 : 10);
				return val.Wrap((ReadOnlySpan<byte>)data).ToArray();
			}
			case CompressionType.GZip:
			{
				MemoryStream memoryStream = new MemoryStream(data);
				MemoryStream memoryStream2 = new MemoryStream();
				GZipStream gZipStream = new GZipStream(memoryStream2, level);
				memoryStream.CopyTo(gZipStream);
				gZipStream.Close();
				return memoryStream2.ToArray();
			}
			case CompressionType.LZ4:
				return LZ4Pickler.Pickle(data, (LZ4Level)((level != CompressionLevel.Fastest) ? 11 : 0));
			default:
				CodeTalkerPlugin.Log.LogError((object)$"[CodeTalker] Unknown compression type: {type}");
				return data;
			}
		}

		public static byte[] Decompress(byte[] data, CompressionType type = CompressionType.Brotli, CompressionLevel level = CompressionLevel.Fastest)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			switch (type)
			{
			case CompressionType.Brotli:
			{
				BrotliStream brotliStream = new BrotliStream(new MemoryStream(data), CompressionMode.Decompress);
				MemoryStream memoryStream = new MemoryStream();
				brotliStream.CopyTo(memoryStream);
				return memoryStream.ToArray();
			}
			case CompressionType.ZStd:
			{
				Decompressor val = new Decompressor();
				return val.Unwrap((ReadOnlySpan<byte>)data, int.MaxValue).ToArray();
			}
			case CompressionType.GZip:
			{
				MemoryStream memoryStream = new MemoryStream();
				GZipStream gZipStream = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
				gZipStream.CopyTo(memoryStream);
				return memoryStream.ToArray();
			}
			case CompressionType.LZ4:
				return LZ4Pickler.Unpickle(data);
			default:
				CodeTalkerPlugin.Log.LogError((object)$"[CodeTalker] Unknown decompression type: {type}");
				return data;
			}
		}

		public static void CompressTest(byte[] rawBytes)
		{
			Stopwatch stopwatch = new Stopwatch();
			CompressionLevel compressionLevel = CompressionLevel.Fastest;
			long num = 1000000000 / Stopwatch.Frequency;
			foreach (CompressionType value in Enum.GetValues(typeof(CompressionType)))
			{
				if (value != 0)
				{
					Compress(rawBytes, value);
					Compress(rawBytes, value, CompressionLevel.Optimal);
				}
			}
			for (int i = 0; i < 2; i++)
			{
				CodeTalkerPlugin.Log.LogInfo((object)$"{compressionLevel}:");
				foreach (CompressionType value2 in Enum.GetValues(typeof(CompressionType)))
				{
					if (value2 != 0)
					{
						stopwatch.Start();
						byte[] array = Compress(rawBytes, value2, compressionLevel);
						stopwatch.Stop();
						CodeTalkerPlugin.Log.LogInfo((object)$"{value2}: {array.Length} bytes - ratio: {(float)rawBytes.Length / (float)array.Length} - time to compress: {stopwatch.ElapsedTicks * num / 1000}us");
						stopwatch.Reset();
					}
				}
				compressionLevel = CompressionLevel.Optimal;
			}
		}

		public static void CompressTest(PacketBase packet)
		{
			string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			CompressTest(bytes);
		}
	}
}
namespace CodeTalker.Packets
{
	public abstract class BinaryPacketBase
	{
		public abstract string PacketSignature { get; }

		public abstract byte[] Serialize();

		public abstract void Deserialize(byte[] data);
	}
	public abstract class PacketBase
	{
		[JsonProperty]
		public abstract string PacketSourceGUID { get; }
	}
	public class PacketHeader
	{
		public readonly ulong SenderID;

		public readonly ulong TargetNetId;

		public bool SenderIsLobbyOwner => SteamMatchmaking.GetLobbyOwner(new CSteamID(SteamLobby._current._currentLobbyID)).m_SteamID == SenderID;

		public PacketHeader(ulong senderID, uint targetNetId = 0u)
		{
			SenderID = senderID;
			TargetNetId = targetNetId;
			base..ctor();
		}
	}
	public static class PacketSerializer
	{
		internal static readonly JsonSerializerSettings JSONOptions = new JsonSerializerSettings
		{
			TypeNameHandling = (TypeNameHandling)0,
			PreserveReferencesHandling = (PreserveReferencesHandling)1,
			Formatting = (Formatting)0,
			NullValueHandling = (NullValueHandling)1,
			DefaultValueHandling = (DefaultValueHandling)1
		};
	}
	internal class PacketWrapper
	{
		[JsonProperty]
		public readonly string PacketType;

		[JsonProperty]
		public readonly string PacketPayload;

		[JsonConstructor]
		public PacketWrapper(string PacketType, string PacketPayload)
		{
			this.PacketType = PacketType;
			this.PacketPayload = PacketPayload;
		}
	}
}
namespace CodeTalker.Networking
{
	public static class CodeTalkerNetwork
	{
		public delegate void PacketListener(PacketHeader header, PacketBase packet);

		public delegate void BinaryPacketListener(PacketHeader header, BinaryPacketBase packet);

		private struct BinaryListenerEntry
		{
			public BinaryPacketListener Listener;

			public Type PacketType;
		}

		private const ushort NETWORK_PACKET_VERSION = 3;

		internal static string CODE_TALKER_SIGNATURE = $"!!CODE_TALKER_NETWORKING:PV{(ushort)3}!!";

		internal static string CODE_TALKER_BINARY_SIGNATURE = $"!CTN:BIN{(ushort)3}!";

		internal static string CODE_TALKER_P2P_SIGNATURE = $"!CTN:P2P{(ushort)3}!";

		private static readonly Dictionary<string, PacketListener> packetListeners = new Dictionary<string, PacketListener>();

		private static readonly Dictionary<string, Func<string, PacketBase>> packetDeserializers = new Dictionary<string, Func<string, PacketBase>>();

		private static string lastSkippedPacketType = "";

		private static readonly Dictionary<string, BinaryListenerEntry> binaryListeners = new Dictionary<string, BinaryListenerEntry>();

		internal static string GetTypeNameString(Type type)
		{
			return type.Assembly.GetName().Name + "," + (type.DeclaringType?.Name ?? "NONE") + ":" + (type.Namespace ?? "NONE") + "." + type.Name;
		}

		public static bool RegisterListener<T>(PacketListener listener) where T : PacketBase
		{
			Type typeFromHandle = typeof(T);
			string typeNameString = GetTypeNameString(typeFromHandle);
			if (packetListeners.ContainsKey(typeNameString))
			{
				return false;
			}
			packetListeners.Add(typeNameString, listener);
			packetDeserializers.Add(typeNameString, (string payload) => JsonConvert.DeserializeObject<T>(payload, PacketSerializer.JSONOptions));
			return true;
		}

		public static bool RegisterBinaryListener<T>(BinaryPacketListener listener) where T : BinaryPacketBase, new()
		{
			Type typeFromHandle = typeof(T);
			BinaryPacketBase binaryPacketBase = new T();
			string packetSignature = binaryPacketBase.PacketSignature;
			if (binaryListeners.ContainsKey(packetSignature))
			{
				return false;
			}
			int num = Encoding.UTF8.GetBytes(packetSignature).Length;
			if (packetSignature.Length == 0 || packetSignature.Length > 255)
			{
				CodeTalkerPlugin.Log.LogError((object)("Failed to register binary Listener for type " + typeFromHandle.FullName + ", PacketSignature can't be " + ((packetSignature.Length > 255) ? "longer than 255 bytes" : "empty") + "!"));
				return false;
			}
			binaryListeners.Add(packetSignature, new BinaryListenerEntry
			{
				Listener = listener,
				PacketType = typeFromHandle
			});
			return true;
		}

		public static void SendNetworkPacket(PacketBase packet)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			string packetPayload = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
			PacketWrapper packetWrapper = new PacketWrapper(GetTypeNameString(packet.GetType()), packetPayload);
			string s = CODE_TALKER_SIGNATURE + JsonConvert.SerializeObject((object)packetWrapper, PacketSerializer.JSONOptions);
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			if (bytes.Length > 4096)
			{
				CodeTalkerPlugin.Log.LogError((object)$"Failed to send packet of type {GetTypeNameString(packet.GetType())}, packet size exceeds maximum of 4kb! Size: {bytes.Length}");
			}
			else
			{
				SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), bytes, bytes.Length);
			}
		}

		public static void SendNetworkPacket(BinaryPacketBase packet)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			byte[] rawData = packet.Serialize();
			BinaryPacketWrapper binaryPacketWrapper = new BinaryPacketWrapper(packet.PacketSignature, rawData);
			if (binaryPacketWrapper.FullPacketBytes.Length > 4096)
			{
				CodeTalkerPlugin.Log.LogError((object)$"Failed to send binary packet of signature {packet.PacketSignature}, packet size exceeds maximum of 4kb! Size: {binaryPacketWrapper.FullPacketBytes.Length}");
			}
			else
			{
				SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), binaryPacketWrapper.FullPacketBytes, binaryPacketWrapper.FullPacketBytes.Length);
			}
		}

		[Obsolete("Use SendNetworkPacket(BinaryPacketBase) instead")]
		public static void SendBinaryNetworkPacket(BinaryPacketBase packet)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			byte[] rawData = packet.Serialize();
			BinaryPacketWrapper binaryPacketWrapper = new BinaryPacketWrapper(packet.PacketSignature, rawData);
			if (binaryPacketWrapper.FullPacketBytes.Length > 4096)
			{
				CodeTalkerPlugin.Log.LogError((object)$"Failed to send binary packet of signature {packet.PacketSignature}, packet size exceeds maximum of 4kb! Size: {binaryPacketWrapper.FullPacketBytes.Length}");
			}
			else
			{
				SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), binaryPacketWrapper.FullPacketBytes, binaryPacketWrapper.FullPacketBytes.Length);
			}
		}

		public static void SendNetworkPacket(Player player, BinaryPacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			byte[] rawData = packet.Serialize();
			P2PPacketWrapper wrappedPacket = new P2PPacketWrapper(packet.PacketSignature, rawData, P2PPacketType.Binary, compressionType, compressionLevel, ((NetworkBehaviour)player).netId);
			SendSteamNetworkingMessage(new CSteamID(ulong.Parse(player.Network_steamID)), wrappedPacket);
		}

		public static void SendNetworkPacket(Player player, PacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			string text = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
			PacketWrapper packetWrapper = new PacketWrapper(GetTypeNameString(packet.GetType()), text);
			P2PPacketWrapper wrappedPacket = new P2PPacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(text), P2PPacketType.JSON, compressionType, compressionLevel, ((NetworkBehaviour)player).netId);
			SendSteamNetworkingMessage(new CSteamID(ulong.Parse(player.Network_steamID)), wrappedPacket);
		}

		public static void SendNetworkPacket(ulong steamID, BinaryPacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			byte[] rawData = packet.Serialize();
			P2PPacketWrapper wrappedPacket = new P2PPacketWrapper(packet.PacketSignature, rawData, P2PPacketType.Binary, compressionType, compressionLevel);
			SendSteamNetworkingMessage(new CSteamID(steamID), wrappedPacket);
		}

		public static void SendNetworkPacket(ulong steamID, PacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
			P2PPacketWrapper wrappedPacket = new P2PPacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(s), P2PPacketType.JSON, compressionType, compressionLevel);
			SendSteamNetworkingMessage(new CSteamID(steamID), wrappedPacket);
		}

		internal static void SendSteamNetworkingMessage(CSteamID id, P2PPacketWrapper wrappedPacket)
		{
			//IL_0002: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			SteamNetworkingIdentity val = default(SteamNetworkingIdentity);
			((SteamNetworkingIdentity)(ref val)).SetSteamID(id);
			GCHandle gCHandle = GCHandle.Alloc(wrappedPacket.PacketBytes, GCHandleType.Pinned);
			try
			{
				IntPtr intPtr = gCHandle.AddrOfPinnedObject();
				SteamNetworkingMessages.SendMessageToUser(ref val, intPtr, (uint)wrappedPacket.PacketBytes.Length, 0, 0);
			}
			catch
			{
			}
			gCHandle.Free();
		}

		internal static void OnNetworkMessage(LobbyChatMsg_t message)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (CodeTalkerPlugin.EnablePacketDebugging.Value)
			{
				CodeTalkerPlugin.Log.LogDebug((object)"Called back!");
			}
			byte[] array = new byte[4096];
			CSteamID senderID = default(CSteamID);
			EChatEntryType val = default(EChatEntryType);
			int lobbyChatEntry = SteamMatchmaking.GetLobbyChatEntry(new CSteamID(message.m_ulSteamIDLobby), (int)message.m_iChatID, ref senderID, array, 4096, ref val);
			HandleNetworkMessage(senderID, array[..lobbyChatEntry]);
		}

		internal static void OnSteamSessionRequest(SteamNetworkingMessagesSessionRequest_t request)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			CodeTalkerPlugin.Log.LogDebug((object)$"Accepting messages session request from {((SteamNetworkingIdentity)(ref request.m_identityRemote)).GetSteamID()}");
			SteamNetworkingMessages.AcceptSessionWithUser(ref request.m_identityRemote);
		}

		internal static void HandleNetworkMessage(CSteamID senderID, byte[] rawData)
		{
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bb2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c8f: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_082e: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a1: Unknown result type (might be due to invalid IL or missing references)
			bool value = CodeTalkerPlugin.EnablePacketDebugging.Value;
			string text = Encoding.UTF8.GetString(rawData);
			if (!text.StartsWith(CODE_TALKER_SIGNATURE) && !text.StartsWith(CODE_TALKER_BINARY_SIGNATURE) && !text.StartsWith(CODE_TALKER_P2P_SIGNATURE))
			{
				return;
			}
			Type inType;
			if (text.StartsWith(CODE_TALKER_SIGNATURE))
			{
				text = text.Replace(CODE_TALKER_SIGNATURE, string.Empty);
				PacketWrapper packetWrapper2;
				try
				{
					PacketWrapper packetWrapper = JsonConvert.DeserializeObject<PacketWrapper>(text, PacketSerializer.JSONOptions);
					if (packetWrapper == null)
					{
						throw new InvalidOperationException("Failed to deserialize a valid packet wrapper");
					}
					packetWrapper2 = packetWrapper;
				}
				catch (Exception ex)
				{
					string text2 = ((text.Length >= 24) ? text.Substring(0, 24) : text);
					CodeTalkerPlugin.Log.LogError((object)("Error while receiving a packet!\r\nException: " + ex.GetType().Name + "\r\nPacket:\r\n" + text2));
					return;
				}
				if (!packetListeners.TryGetValue(packetWrapper2.PacketType, out PacketListener value2))
				{
					if (value && packetWrapper2.PacketType != lastSkippedPacketType)
					{
						CodeTalkerPlugin.Log.LogDebug((object)("Skipping packet of type: " + packetWrapper2.PacketType + " because this client does not have it installed, this is safe!"));
						lastSkippedPacketType = packetWrapper2.PacketType;
					}
					return;
				}
				PacketBase packet;
				try
				{
					PacketBase packetBase = packetDeserializers[packetWrapper2.PacketType](packetWrapper2.PacketPayload);
					if (packetBase == null)
					{
						return;
					}
					inType = packetBase.GetType();
					packet = packetBase;
				}
				catch (Exception ex2)
				{
					CodeTalkerPlugin.Log.LogError((object)("Error while unwrapping a packet!\r\nException: " + ex2.GetType().Name + "\r\nExpected Type: " + packetWrapper2.PacketType));
					return;
				}
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)$"Heard {rawData.Length} from GetLobbyChat. Sender {senderID}");
					CodeTalkerPlugin.Log.LogDebug((object)("Full message: " + text));
					CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for type " + packetWrapper2.PacketType));
				}
				try
				{
					value2(new PacketHeader(senderID.m_SteamID), packet);
				}
				catch (Exception arg2)
				{
					Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
					PluginInfo val = pluginInfos.Values.Where((PluginInfo mod) => ((object)mod.Instance)?.GetType().Assembly == inType.Assembly).FirstOrDefault();
					string arg = ((val != null) ? $"{val.Metadata.Name} version {val.Metadata.Version}" : inType.Assembly.GetName().Name);
					CodeTalkerPlugin.Log.LogError((object)$"The following mod encountered an error while responding to a network packet, please do not report this as a CodeTalker error!\r\nMod: {arg}\r\nStackTrace:\r\n{arg2}");
				}
			}
			if (text.StartsWith(CODE_TALKER_BINARY_SIGNATURE))
			{
				text = text.Replace(CODE_TALKER_BINARY_SIGNATURE, string.Empty);
				BinaryPacketWrapper binaryPacketWrapper;
				try
				{
					binaryPacketWrapper = new BinaryPacketWrapper(rawData[CODE_TALKER_BINARY_SIGNATURE.Length..]);
				}
				catch (Exception arg3)
				{
					CodeTalkerPlugin.Log.LogError((object)$"Failed to create binary packet wrapper for valid packet!\nStackTrace: {arg3}");
					return;
				}
				if (!binaryListeners.TryGetValue(binaryPacketWrapper.PacketSignature, out var value3))
				{
					if (value && binaryPacketWrapper.PacketSignature != lastSkippedPacketType)
					{
						CodeTalkerPlugin.Log.LogDebug((object)("Skipping binary packet of signature: " + binaryPacketWrapper.PacketSignature + " because this client does not have it installed, this is safe!"));
						lastSkippedPacketType = binaryPacketWrapper.PacketSignature;
					}
					return;
				}
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)"Recieved binary packet!");
				}
				BinaryPacketBase binaryPacketBase;
				try
				{
					inType = value3.PacketType;
					object obj = Activator.CreateInstance(inType);
					if (!(obj is BinaryPacketBase))
					{
						throw new InvalidOperationException("Failed to create instance of binary packet type!");
					}
					binaryPacketBase = (BinaryPacketBase)obj;
					try
					{
						binaryPacketBase.Deserialize(binaryPacketWrapper.FullPacketBytes);
					}
					catch (Exception arg4)
					{
						CodeTalkerPlugin.Log.LogError((object)$"Error while deserializing binary packet! THIS IS NOT A CODETALKER ISSUE! DO NOT REPORT THIS TO THE CODETALKER DEV!!\nStackTrace: {arg4}");
						CodeTalkerPlugin.Log.LogError((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
							select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
						CodeTalkerPlugin.Log.LogError((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
						return;
					}
				}
				catch (Exception arg5)
				{
					CodeTalkerPlugin.Log.LogError((object)$"Error while creating binary packet instance! This should be reported to either codetalker or the plugin dev!\nStackTrace: {arg5}");
					CodeTalkerPlugin.Log.LogError((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
						select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
					CodeTalkerPlugin.Log.LogError((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
					return;
				}
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)$"Heard {rawData.Length} from GetLobbyChat. Sender {senderID}");
					CodeTalkerPlugin.Log.LogDebug((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
						select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
					CodeTalkerPlugin.Log.LogDebug((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
					CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for binary signature \"" + binaryPacketWrapper.PacketSignature + "\""));
				}
				try
				{
					value3.Listener(new PacketHeader(senderID.m_SteamID), binaryPacketBase);
				}
				catch (Exception arg7)
				{
					Dictionary<string, PluginInfo> pluginInfos2 = Chainloader.PluginInfos;
					inType = value3.GetType();
					PluginInfo val2 = pluginInfos2.Values.Where((PluginInfo mod) => ((object)mod.Instance)?.GetType().Assembly == inType.Assembly).FirstOrDefault();
					string arg6 = ((val2 != null) ? $"{val2.Metadata.Name} version {val2.Metadata.Version}" : inType.Assembly.GetName().Name);
					CodeTalkerPlugin.Log.LogError((object)$"The following mod encountered an error while responding to a network packet, please do not report this as a CodeTalker error!\r\nMod: {arg6}\r\nStackTrace:\r\n{arg7}");
				}
			}
			if (!text.StartsWith(CODE_TALKER_P2P_SIGNATURE))
			{
				return;
			}
			text = text.Replace(CODE_TALKER_P2P_SIGNATURE, string.Empty);
			P2PPacketWrapper p2PPacketWrapper;
			try
			{
				p2PPacketWrapper = new P2PPacketWrapper(rawData[CODE_TALKER_P2P_SIGNATURE.Length..]);
			}
			catch (Exception arg8)
			{
				CodeTalkerPlugin.Log.LogError((object)$"Failed to create P2P packet wrapper for valid packet!\nStackTrace: {arg8}");
				return;
			}
			if (p2PPacketWrapper.TargetNetId != 0 && ((Object)(object)Player._mainPlayer == (Object)null || ((NetworkBehaviour)Player._mainPlayer).netId != p2PPacketWrapper.TargetNetId))
			{
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)$"P2P netId doesn't match this client! Targeted netId: {p2PPacketWrapper.TargetNetId}");
				}
				return;
			}
			if (value)
			{
				CodeTalkerPlugin.Log.LogDebug((object)$"Got P2P packet! Type: {p2PPacketWrapper.PacketType} TargetNetID: {p2PPacketWrapper.TargetNetId}");
			}
			if (p2PPacketWrapper.PacketType == P2PPacketType.JSON)
			{
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)"Recieved P2P JSON packet!");
				}
				if (!packetListeners.TryGetValue(p2PPacketWrapper.PacketSignature, out PacketListener value4))
				{
					if (value && p2PPacketWrapper.PacketSignature != lastSkippedPacketType)
					{
						CodeTalkerPlugin.Log.LogDebug((object)("Skipping packet of type: " + p2PPacketWrapper.PacketSignature + " because this client does not have it installed, this is safe!"));
						lastSkippedPacketType = p2PPacketWrapper.PacketSignature;
					}
					return;
				}
				PacketBase packet;
				try
				{
					PacketBase packetBase2 = packetDeserializers[p2PPacketWrapper.PacketSignature](Encoding.UTF8.GetString(p2PPacketWrapper.PacketBytes));
					if (packetBase2 == null)
					{
						return;
					}
					inType = packetBase2.GetType();
					packet = packetBase2;
				}
				catch (Exception ex3)
				{
					CodeTalkerPlugin.Log.LogError((object)("Error while unwrapping a packet!\r\nException: " + ex3.GetType().Name + "\r\nExpected Type: " + p2PPacketWrapper.PacketSignature));
					return;
				}
				if (value)
				{
					CodeTalkerPlugin.Log.LogDebug((object)$"Heard {rawData.Length} from steam network. Sender {senderID}");
					CodeTalkerPlugin.Log.LogDebug((object)("Full raw message: " + text));
					CodeTalkerPlugin.Log.LogError((object)("Packet hex: " + BitConverter.ToString(p2PPacketWrapper.PacketBytes).Replace("-", "")));
					CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for type " + p2PPacketWrapper.PacketSignature));
				}
				try
				{
					value4(new PacketHeader(senderID.m_SteamID), packet);
				}
				catch (Exception arg10)
				{
					Dictionary<string, PluginInfo> pluginInfos3 = Chainloader.PluginInfos;
					PluginInfo val3 = pluginInfos3.Values.Where((PluginInfo mod) => ((object)mod.Instance)?.GetType().Assembly == inType.Assembly).FirstOrDefault();
					string arg9 = ((val3 != null) ? $"{val3.Metadata.Name} version {val3.Metadata.Version}" : inType.Assembly.GetName().Name);
					CodeTalkerPlugin.Log.LogError((object)$"The following mod encountered an error while responding to a network packet, please do not report this as a CodeTalker error!\r\nMod: {arg9}\r\nStackTrace:\r\n{arg10}");
				}
			}
			if (p2PPacketWrapper.PacketType != P2PPacketType.Binary)
			{
				return;
			}
			text = text.Replace(CODE_TALKER_BINARY_SIGNATURE, string.Empty);
			if (!binaryListeners.TryGetValue(p2PPacketWrapper.PacketSignature, out var value5))
			{
				if (value && p2PPacketWrapper.PacketSignature != lastSkippedPacketType)
				{
					CodeTalkerPlugin.Log.LogDebug((object)("Skipping binary packet of signature: " + p2PPacketWrapper.PacketSignature + " because this client does not have it installed, this is safe!"));
					lastSkippedPacketType = p2PPacketWrapper.PacketSignature;
				}
				return;
			}
			if (value)
			{
				CodeTalkerPlugin.Log.LogDebug((object)"Recieved P2P binary packet!");
			}
			BinaryPacketBase binaryPacketBase2;
			try
			{
				inType = value5.PacketType;
				object obj2 = Activator.CreateInstance(inType);
				if (!(obj2 is BinaryPacketBase))
				{
					throw new InvalidOperationException("Failed to create instance of binary packet type!");
				}
				binaryPacketBase2 = (BinaryPacketBase)obj2;
				try
				{
					binaryPacketBase2.Deserialize(p2PPacketWrapper.PacketBytes);
				}
				catch (Exception arg11)
				{
					CodeTalkerPlugin.Log.LogError((object)$"Error while deserializing binary packet! THIS IS NOT A CODETALKER ISSUE! DO NOT REPORT THIS TO THE CODETALKER DEV!!\nStackTrace: {arg11}");
					CodeTalkerPlugin.Log.LogError((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
						select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
					CodeTalkerPlugin.Log.LogError((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
					CodeTalkerPlugin.Log.LogError((object)("Packet hex: " + BitConverter.ToString(p2PPacketWrapper.PacketBytes).Replace("-", "")));
					return;
				}
			}
			catch (Exception arg12)
			{
				CodeTalkerPlugin.Log.LogError((object)$"Error while creating binary packet instance! This should be reported to either codetalker or the plugin dev!\nStackTrace: {arg12}");
				CodeTalkerPlugin.Log.LogError((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
					select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
				CodeTalkerPlugin.Log.LogError((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
				CodeTalkerPlugin.Log.LogError((object)("Packet hex: " + BitConverter.ToString(p2PPacketWrapper.PacketBytes).Replace("-", "")));
				return;
			}
			if (value)
			{
				CodeTalkerPlugin.Log.LogDebug((object)$"Heard {rawData.Length} from steam network. Sender {senderID}");
				CodeTalkerPlugin.Log.LogDebug((object)("Full message: " + new string((from c in Encoding.UTF8.GetString(rawData)
					select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray())));
				CodeTalkerPlugin.Log.LogDebug((object)("Full message hex: " + BitConverter.ToString(rawData).Replace("-", "")));
				CodeTalkerPlugin.Log.LogDebug((object)("Packet hex: " + BitConverter.ToString(p2PPacketWrapper.PacketBytes).Replace("-", "")));
				CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for binary signature \"" + p2PPacketWrapper.PacketSignature + "\""));
			}
			try
			{
				value5.Listener(new PacketHeader(senderID.m_SteamID), binaryPacketBase2);
			}
			catch (Exception arg14)
			{
				Dictionary<string, PluginInfo> pluginInfos4 = Chainloader.PluginInfos;
				inType = value5.GetType();
				PluginInfo val4 = pluginInfos4.Values.Where((PluginInfo mod) => ((object)mod.Instance)?.GetType().Assembly == inType.Assembly).FirstOrDefault();
				string arg13 = ((val4 != null) ? $"{val4.Metadata.Name} version {val4.Metadata.Version}" : inType.Assembly.GetName().Name);
				CodeTalkerPlugin.Log.LogError((object)$"The following mod encountered an error while responding to a network packet, please do not report this as a CodeTalker error!\r\nMod: {arg13}\r\nStackTrace:\r\n{arg14}");
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}