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)
{
}
}
}