using System;
using System.Buffers.Binary;
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.2.2.0")]
[assembly: AssemblyInformationalVersion("2.2.2+e99f7b5d48c19da82d983d2513981f4f1ba84679")]
[assembly: AssemblyProduct("CodeTalker")]
[assembly: AssemblyTitle("CodeTalker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.2.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 enum PacketType : byte
{
JSON,
Binary
}
internal class PacketWrapper
{
internal readonly byte[] PacketBytes;
internal readonly ulong PacketSignature;
internal readonly PacketType PacketType;
internal readonly Compressors.CompressionType compression;
internal readonly uint TargetNetId;
internal PacketWrapper(string sig, Span<byte> rawData, PacketType packetType, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest, uint targetNetId = 0u)
{
Span<byte> span = CodeTalkerNetwork.CODE_TALKER_SIGNATURE;
Span<byte> signature = Encoding.UTF8.GetBytes(sig);
PacketType = packetType;
PacketSignature = CodeTalkerNetwork.signatureHash(signature);
if (compressionType != 0)
{
rawData = Compressors.Compress(rawData.ToArray(), compressionType, compressionLevel);
}
int num = span.Length + 8 + 5;
PacketBytes = new byte[num + rawData.Length];
Span<byte> span2 = new Span<byte>(PacketBytes);
int num2 = 0;
span.CopyTo(span2.Slice(num2));
num2 += span.Length;
BinaryPrimitives.WriteUInt64LittleEndian(span2.Slice(num2), PacketSignature);
num2 += 8;
span2[num2++] = (byte)((uint)(((int)compressionType << 4) & 0xF0) + (uint)(packetType & (PacketType)15));
BinaryPrimitives.WriteUInt32LittleEndian(span2.Slice(num2), targetNetId);
num2 += 4;
rawData.CopyTo(span2.Slice(num2));
}
internal PacketWrapper(Span<byte> rawPacketData)
{
PacketSignature = BinaryPrimitives.ReadUInt64LittleEndian(rawPacketData);
PacketType = (PacketType)(rawPacketData[8] & 0xFu);
compression = (Compressors.CompressionType)((rawPacketData[8] >> 4) & 0xF);
TargetNetId = BinaryPrimitives.ReadUInt32LittleEndian(rawPacketData.Slice(9, 4));
PacketBytes = rawPacketData.Slice(13).ToArray();
if (compression != 0)
{
PacketBytes = Compressors.Decompress(PacketBytes, compression);
}
}
public override string ToString()
{
return $"[Type: {PacketType} Compression: {compression} Target: {TargetNetId}]";
}
}
internal static class LCMPluginInfo
{
public const string PLUGIN_GUID = "CodeTalker";
public const string PLUGIN_NAME = "CodeTalker";
public const string PLUGIN_VERSION = "2.2.2";
}
namespace CodeTalker
{
[BepInPlugin("CodeTalker", "CodeTalker", "2.2.2")]
public class CodeTalkerPlugin : BaseUnityPlugin
{
internal static ManualLogSource Log = null;
internal static Callback<LobbyChatMsg_t>? onNetworkMessage;
internal static Callback<SteamNetworkingMessagesSessionRequest_t>? onSNMRequest;
internal static ConfigEntry<bool> EnablePacketDebugging = null;
internal static ConfigEntry<bool> devMode = null;
private static bool steamIntialized = false;
private static IntPtr[] messagePtrBuffer = new IntPtr[10];
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)");
devMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableDevMode", false, "If CodeTalker should log extremely verbosely. This should only be used when actively debugging codetalker!");
Log.LogInfo((object)"Plugin CodeTalker version 2.2.2 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");
CodeTalkerNetwork.dbg = EnablePacketDebugging.Value;
CodeTalkerNetwork.dev = devMode.Value;
byte[] array = new byte[64];
new Random().NextBytes(array);
foreach (Compressors.CompressionType value in Enum.GetValues(typeof(Compressors.CompressionType)))
{
if (value != 0)
{
byte[] data = Compressors.Compress(array, value);
Compressors.Decompress(data, value);
}
}
}
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 (devMode.Value)
{
((BaseUnityPlugin)this).Logger.LogDebug((object)$"Steam Relay Network status update: {status.m_eAvail}");
}
if (steamIntialized)
{
SteamNetworkingUtils.InitRelayNetworkAccess();
}
}
}
private void Update()
{
//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_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
try
{
int num = SteamNetworkingMessages.ReceiveMessagesOnChannel(0, messagePtrBuffer, messagePtrBuffer.Length);
if (num <= 0)
{
return;
}
try
{
for (int i = 0; i < num; i++)
{
SteamNetworkingMessage_t val = Marshal.PtrToStructure<SteamNetworkingMessage_t>(messagePtrBuffer[i]);
byte[] array = new byte[val.m_cbSize];
if (devMode.Value)
{
Log.LogDebug((object)$"Recieved SNM packet of size {val.m_cbSize}");
}
try
{
Marshal.Copy(val.m_pData, array, 0, val.m_cbSize);
Span<byte> span = new Span<byte>(array);
if (CodeTalkerNetwork.signatureCheck(array, CodeTalkerNetwork.CODE_TALKER_SIGNATURE))
{
if (devMode.Value)
{
Log.LogDebug((object)("Got P2P message! " + CodeTalkerNetwork.BinaryToHexString(array)));
}
CodeTalkerNetwork.HandleNetworkMessage(((SteamNetworkingIdentity)(ref val.m_identityPeer)).GetSteamID(), span.Slice(CodeTalkerNetwork.CODE_TALKER_SIGNATURE.Length));
}
}
catch
{
}
SteamNetworkingMessage_t.Release(messagePtrBuffer[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 uint 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
};
}
}
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 = 4;
internal static byte[] CODE_TALKER_SIGNATURE = Encoding.UTF8.GetBytes($"!CTN:PV{(ushort)4}!");
private static readonly Dictionary<ulong, PacketListener> packetListeners = new Dictionary<ulong, PacketListener>();
private static readonly Dictionary<ulong, Func<string, PacketBase>> packetDeserializers = new Dictionary<ulong, Func<string, PacketBase>>();
private static ulong lastSkippedPacketSig = 0uL;
private static readonly Dictionary<ulong, BinaryListenerEntry> binaryListeners = new Dictionary<ulong, BinaryListenerEntry>();
internal static bool dbg = false;
internal static bool dev = false;
private static object? packet;
private static Type? type;
private static PacketWrapper? wrapper;
internal static string GetTypeNameString(Type type)
{
return type.Assembly.GetName().Name + "," + (type.DeclaringType?.Name ?? "NONE") + ":" + (type.Namespace ?? "NONE") + "." + type.Name;
}
internal static bool signatureCheck(Span<byte> data, Span<byte> sig)
{
if (data.Length < sig.Length)
{
return false;
}
return data.Slice(0, sig.Length).SequenceEqual(sig);
}
internal static ulong signatureHash(Span<byte> signature)
{
ulong num = 14695981039346656037uL;
Span<byte> span = signature;
for (int i = 0; i < span.Length; i++)
{
byte b = span[i];
num ^= b;
num *= 1099511628211L;
}
return num;
}
public static bool RegisterListener<T>(PacketListener listener) where T : PacketBase
{
Type typeFromHandle = typeof(T);
string typeNameString = GetTypeNameString(typeFromHandle);
ulong key = signatureHash(Encoding.UTF8.GetBytes(typeNameString));
if (packetListeners.ContainsKey(key))
{
CodeTalkerPlugin.Log.LogError((object)("Failed to register listener for type " + typeFromHandle.FullName + "! A listener for this type is already registered or a hash collision has occurred!"));
return false;
}
packetListeners.Add(key, listener);
packetDeserializers.Add(key, (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();
if (binaryPacketBase.PacketSignature == string.Empty)
{
CodeTalkerPlugin.Log.LogError((object)("Failed to register binary Listener for type " + typeFromHandle.FullName + ", PacketSignature can't be empty!"));
return false;
}
ulong key = signatureHash(Encoding.UTF8.GetBytes(binaryPacketBase.PacketSignature));
if (binaryListeners.ContainsKey(key))
{
CodeTalkerPlugin.Log.LogError((object)("Failed to register listener for type " + binaryPacketBase.PacketSignature + "! A listener for this type is already registered or a hash collision has occurred!"));
return false;
}
binaryListeners.Add(key, new BinaryListenerEntry
{
Listener = listener,
PacketType = typeFromHandle
});
return true;
}
public static void SendNetworkPacket(PacketBase packet)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
PacketWrapper packetWrapper = new PacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(s), PacketType.JSON);
if (packetWrapper.PacketBytes.Length > 4096)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to send packet of type {GetTypeNameString(packet.GetType())}, packet size exceeds maximum of 4kb! Size: {packetWrapper.PacketBytes.Length}");
}
else
{
SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), packetWrapper.PacketBytes, packetWrapper.PacketBytes.Length);
}
}
public static void SendNetworkPacket(BinaryPacketBase packet)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
byte[] array = packet.Serialize();
PacketWrapper packetWrapper = new PacketWrapper(packet.PacketSignature, array, PacketType.Binary);
if (packetWrapper.PacketBytes.Length > 4096)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to send binary packet of signature {packet.PacketSignature}, packet size exceeds maximum of 4kb! Size: {packetWrapper.PacketBytes.Length}");
}
else
{
SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), packetWrapper.PacketBytes, packetWrapper.PacketBytes.Length);
}
}
public static void SendNetworkPacket(PacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
PacketWrapper packetWrapper = new PacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(s), PacketType.JSON, compressionType, compressionLevel);
if (packetWrapper.PacketBytes.Length > 4096)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to send packet of type {GetTypeNameString(packet.GetType())}, packet size exceeds maximum of 4kb! Size: {packetWrapper.PacketBytes.Length}");
}
else
{
SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), packetWrapper.PacketBytes, packetWrapper.PacketBytes.Length);
}
}
public static void SendNetworkPacket(BinaryPacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
byte[] array = packet.Serialize();
PacketWrapper packetWrapper = new PacketWrapper(packet.PacketSignature, array, PacketType.Binary, compressionType, compressionLevel);
if (packetWrapper.PacketBytes.Length > 4096)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to send binary packet of signature {packet.PacketSignature}, packet size exceeds maximum of 4kb! Size: {packetWrapper.PacketBytes.Length}");
}
else
{
SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), packetWrapper.PacketBytes, packetWrapper.PacketBytes.Length);
}
}
[Obsolete("Use SendNetworkPacket(BinaryPacketBase) instead")]
public static void SendBinaryNetworkPacket(BinaryPacketBase packet)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
byte[] array = packet.Serialize();
PacketWrapper packetWrapper = new PacketWrapper(packet.PacketSignature, array, PacketType.Binary);
if (packetWrapper.PacketBytes.Length > 4096)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to send binary packet of signature {packet.PacketSignature}, packet size exceeds maximum of 4kb! Size: {packetWrapper.PacketBytes.Length}");
}
else
{
SteamMatchmaking.SendLobbyChatMsg(new CSteamID(SteamLobby._current._currentLobbyID), packetWrapper.PacketBytes, packetWrapper.PacketBytes.Length);
}
}
public static void SendNetworkPacket(Player player, BinaryPacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
if (player.Network_steamID == string.Empty || !ulong.TryParse(player.Network_steamID, out var result))
{
CodeTalkerPlugin.Log.LogError((object)("Unable to send a packet of type '" + packet.PacketSignature + "' to \"" + player.Network_nickname + "\" which has an empty or invalid steam id!"));
}
else
{
byte[] array = packet.Serialize();
PacketWrapper wrappedPacket = new PacketWrapper(packet.PacketSignature, array, PacketType.Binary, compressionType, compressionLevel, ((NetworkBehaviour)player).netId);
SendSteamNetworkingMessage(new CSteamID(result), wrappedPacket);
}
}
public static void SendNetworkPacket(Player player, PacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
if (player.Network_steamID == string.Empty || !ulong.TryParse(player.Network_steamID, out var result))
{
CodeTalkerPlugin.Log.LogError((object)("Unable to send a packet of type '" + packet.PacketSourceGUID + "' to \"" + player.Network_nickname + "\" which has an empty or invalid steam id!"));
}
else
{
string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
PacketWrapper wrappedPacket = new PacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(s), PacketType.JSON, compressionType, compressionLevel, ((NetworkBehaviour)player).netId);
SendSteamNetworkingMessage(new CSteamID(result), wrappedPacket);
}
}
public static void SendNetworkPacket(ulong steamID, BinaryPacketBase packet, Compressors.CompressionType compressionType = Compressors.CompressionType.None, CompressionLevel compressionLevel = CompressionLevel.Fastest)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
byte[] array = packet.Serialize();
PacketWrapper wrappedPacket = new PacketWrapper(packet.PacketSignature, array, PacketType.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_0032: Unknown result type (might be due to invalid IL or missing references)
string s = JsonConvert.SerializeObject((object)packet, PacketSerializer.JSONOptions);
PacketWrapper wrappedPacket = new PacketWrapper(GetTypeNameString(packet.GetType()), Encoding.UTF8.GetBytes(s), PacketType.JSON, compressionType, compressionLevel);
SendSteamNetworkingMessage(new CSteamID(steamID), wrappedPacket);
}
internal static void SendSteamNetworkingMessage(CSteamID id, PacketWrapper 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_0021: 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_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
if (dev)
{
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);
Span<byte> span = new Span<byte>(array);
if (signatureCheck(array, CODE_TALKER_SIGNATURE))
{
HandleNetworkMessage(senderID, span.Slice(CODE_TALKER_SIGNATURE.Length, lobbyChatEntry - CODE_TALKER_SIGNATURE.Length));
}
}
internal static void OnSteamSessionRequest(SteamNetworkingMessagesSessionRequest_t request)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)$"Accepting messages session request from {((SteamNetworkingIdentity)(ref request.m_identityRemote)).GetSteamID()}");
}
SteamNetworkingMessages.AcceptSessionWithUser(ref request.m_identityRemote);
}
internal static string BinaryToUtf8String(Span<byte> data)
{
return new string((from c in Encoding.UTF8.GetString(data)
select (!char.IsControl(c) || c == '\r' || c == '\n') ? c : '\ufffd').ToArray());
}
internal static string BinaryToHexString(Span<byte> data)
{
return BitConverter.ToString(data.ToArray()).Replace("-", "");
}
private static void printWrapperInfo(CSteamID senderID, PacketWrapper wrapper, LogLevel level = 32)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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)
CodeTalkerPlugin.Log.Log(level, (object)$"Sender: {senderID} Wrapper: {wrapper}");
CodeTalkerPlugin.Log.Log(level, (object)("Message hex: " + BinaryToHexString(wrapper.PacketBytes)));
}
[DebuggerNonUserCode]
internal static void ExecuteHandler(Delegate listener, CSteamID senderID, object packetObj)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
try
{
if (packetObj is PacketBase packetBase)
{
if (dbg)
{
printWrapperInfo(senderID, wrapper, (LogLevel)32);
CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for \"" + GetTypeNameString(packetBase.GetType()) + "\""));
}
((PacketListener)listener)(new PacketHeader(senderID.m_SteamID), packetBase);
}
else if (packetObj is BinaryPacketBase binaryPacketBase)
{
if (dbg)
{
printWrapperInfo(senderID, wrapper, (LogLevel)32);
CodeTalkerPlugin.Log.LogDebug((object)("Sending an event for \"" + binaryPacketBase.PacketSignature + "\""));
}
((BinaryPacketListener)listener)(new PacketHeader(senderID.m_SteamID), binaryPacketBase);
}
}
catch (Exception arg2)
{
Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
PluginInfo val = pluginInfos.Values.Where((PluginInfo mod) => ((object)mod.Instance)?.GetType().Assembly == type?.Assembly).FirstOrDefault();
string arg = ((val != null) ? $"{val.Metadata.Name} version {val.Metadata.Version}" : (type?.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}");
}
}
internal static void HandleNetworkMessage(CSteamID senderID, Span<byte> rawData)
{
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02da: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
try
{
wrapper = new PacketWrapper(rawData);
}
catch (Exception arg)
{
CodeTalkerPlugin.Log.LogError((object)$"Failed to create packet wrapper for valid packet!\nStackTrace: {arg}");
return;
}
if (wrapper.TargetNetId != 0 && ((Object)(object)Player._mainPlayer == (Object)null || ((NetworkBehaviour)Player._mainPlayer).netId != wrapper.TargetNetId))
{
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)$"Target netId doesn't match this client! Targeted netId: {wrapper.TargetNetId}");
}
return;
}
switch (wrapper.PacketType)
{
case PacketType.JSON:
{
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)"Recieved JSON packet!");
}
if (!packetListeners.TryGetValue(wrapper.PacketSignature, out PacketListener value2))
{
if (dbg && wrapper.PacketSignature != lastSkippedPacketSig)
{
CodeTalkerPlugin.Log.LogDebug((object)$"Skipping packet of type: {wrapper.PacketSignature} because this client does not have it installed, this is safe!");
lastSkippedPacketSig = wrapper.PacketSignature;
}
break;
}
try
{
PacketBase packetBase = packetDeserializers[wrapper.PacketSignature](Encoding.UTF8.GetString(wrapper.PacketBytes));
if (packetBase == null)
{
break;
}
type = packetBase.GetType();
packet = packetBase;
}
catch (Exception ex)
{
CodeTalkerPlugin.Log.LogError((object)$"Error while unwrapping a packet!\r\nException: {ex.GetType().Name}\r\nExpected Type: {wrapper.PacketSignature}");
break;
}
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)("Raw message: " + BinaryToHexString(rawData)));
}
ExecuteHandler(value2, senderID, packet);
break;
}
case PacketType.Binary:
{
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)"Recieved binary packet!");
}
if (!binaryListeners.TryGetValue(wrapper.PacketSignature, out var value))
{
if (dev && wrapper.PacketSignature != lastSkippedPacketSig)
{
CodeTalkerPlugin.Log.LogDebug((object)("Skipping binary packet of unknown signature hash: 0x" + wrapper.PacketSignature.ToString("x2") + " because this client does not have it installed, this is safe!"));
lastSkippedPacketSig = wrapper.PacketSignature;
}
break;
}
try
{
type = value.PacketType;
object obj = Activator.CreateInstance(type);
if (!(obj is BinaryPacketBase binaryPacketBase))
{
throw new InvalidOperationException("Failed to create instance of binary packet type!");
}
packet = obj;
try
{
binaryPacketBase.Deserialize(wrapper.PacketBytes);
}
catch (Exception arg2)
{
CodeTalkerPlugin.Log.LogError((object)$"Error while deserializing binary packet! THIS IS NOT A CODETALKER ISSUE! DO NOT REPORT THIS TO THE CODETALKER DEV!!\nStackTrace: {arg2}");
printWrapperInfo(senderID, wrapper, (LogLevel)2);
break;
}
}
catch (Exception arg3)
{
CodeTalkerPlugin.Log.LogError((object)$"Error while creating binary packet instance! This should be reported to either codetalker or the plugin dev!\nStackTrace: {arg3}");
printWrapperInfo(senderID, wrapper, (LogLevel)2);
break;
}
if (dev)
{
CodeTalkerPlugin.Log.LogDebug((object)("Raw message: " + BinaryToHexString(rawData)));
}
ExecuteHandler(value.Listener, senderID, packet);
break;
}
default:
CodeTalkerPlugin.Log.LogError((object)$"UNKNOWN PACKET TYPE RECIEVED! THERE IS LIKELY A BUG IN CODEYAPPER. REPORT THIS TO @Soggy_Pancake! {wrapper}\nRecieved data: {BinaryToHexString(rawData)}");
break;
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}