using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using Photon.Client; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Exit Games GmbH")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("(c) Exit Games GmbH, http://www.exitgames.com")] [assembly: AssemblyDescription("Photon Chat Api. Debug.")] [assembly: AssemblyFileVersion("5.1.9.0")] [assembly: AssemblyInformationalVersion("5.1.9")] [assembly: AssemblyProduct("Photon Chat Api. Debug.")] [assembly: AssemblyTitle("PhotonChat")] [assembly: AssemblyVersion("5.1.9.0")] namespace Photon.Chat; public class ChannelCreationOptions { public static ChannelCreationOptions Default = new ChannelCreationOptions(); public bool PublishSubscribers { get; set; } public int MaxSubscribers { get; set; } } public class ChannelWellKnownProperties { public const byte MaxSubscribers = byte.MaxValue; public const byte PublishSubscribers = 254; } public class ChatAppSettings { public string AppIdChat; public string AppVersion; public string FixedRegion; public string Server; public ushort Port; public string ProxyServer; public ConnectionProtocol Protocol = (ConnectionProtocol)0; public bool EnableProtocolFallback = true; public LogLevel NetworkLogging = (LogLevel)1; public LogLevel ClientLogging = (LogLevel)2; public bool IsDefaultNameServer => string.IsNullOrEmpty(Server); public bool IsDefaultPort => Port <= 0; public ChatAppSettings() { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) public ChatAppSettings(ChatAppSettings original) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) original?.CopyTo(this); } public ChatAppSettings CopyTo(ChatAppSettings target) { //IL_004b: 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_0057: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) target.AppIdChat = AppIdChat; target.AppVersion = AppVersion; target.FixedRegion = FixedRegion; target.Server = Server; target.Port = Port; target.ProxyServer = ProxyServer; target.Protocol = Protocol; target.ClientLogging = ClientLogging; target.NetworkLogging = NetworkLogging; target.EnableProtocolFallback = EnableProtocolFallback; return target; } } public class ChatChannel { public readonly string Name; public readonly List Senders = new List(); public readonly List Messages = new List(); public int MessageLimit; public int ChannelID; private Dictionary properties; public readonly HashSet Subscribers = new HashSet(); private Dictionary> usersProperties; public bool IsPrivate { get; protected internal set; } public int MessageCount => Messages.Count; public int LastMsgId { get; protected set; } public bool PublishSubscribers { get; protected set; } public int MaxSubscribers { get; protected set; } public ChatChannel(string name) { Name = name; } public void Add(string sender, object message, int msgId) { Senders.Add(sender); Messages.Add(message); LastMsgId = msgId; TruncateMessages(); } public void Add(string[] senders, object[] messages, int lastMsgId) { Senders.AddRange(senders); Messages.AddRange(messages); LastMsgId = lastMsgId; TruncateMessages(); } public void TruncateMessages() { if (MessageLimit > 0 && Messages.Count > MessageLimit) { int count = Messages.Count - MessageLimit; Senders.RemoveRange(0, count); Messages.RemoveRange(0, count); } } public void ClearMessages() { Senders.Clear(); Messages.Clear(); } public string ToStringMessages() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < Messages.Count; i++) { stringBuilder.AppendLine($"{Senders[i]}: {Messages[i]}"); } return stringBuilder.ToString(); } internal void ReadChannelProperties(Dictionary newProperties) { if (newProperties == null || newProperties.Count <= 0) { return; } if (properties == null) { properties = new Dictionary(newProperties.Count); } foreach (KeyValuePair newProperty in newProperties) { if (newProperty.Value == null) { properties.Remove(newProperty.Key); } else { properties[newProperty.Key] = newProperty.Value; } } if (properties.TryGetValue((byte)254, out var value)) { PublishSubscribers = (bool)value; } if (properties.TryGetValue(byte.MaxValue, out value)) { MaxSubscribers = (int)value; } } internal bool AddSubscribers(string[] users) { if (users == null) { return false; } bool result = true; for (int i = 0; i < users.Length; i++) { if (!Subscribers.Add(users[i])) { result = false; } } return result; } internal bool AddSubscriber(string userId) { return Subscribers.Add(userId); } internal bool RemoveSubscriber(string userId) { if (usersProperties != null) { usersProperties.Remove(userId); } return Subscribers.Remove(userId); } } public class ChatClient : IPhotonPeerListener { private const int FriendRequestListMax = 1024; public const int DefaultMaxSubscribers = 100; private const byte HttpForwardWebFlag = 1; private readonly string chatRegion = "eu"; public int MessageLimit; public int PrivateChatHistoryLength = -1; public readonly Dictionary PublicChannels; public readonly Dictionary PrivateChannels; private readonly HashSet PublicChannelsUnsubscribing; private readonly IChatClientListener listener = null; public readonly PhotonPeer Peer; private const string ChatAppName = "chat"; private bool didAuthenticate; private int msDeltaForServiceCalls = 50; private Timer stateTimer; private int msTimestampOfLastServiceCall; public string NameServerHost = "ns.photonengine.io"; private static readonly Dictionary ProtocolToNameServerPort = new Dictionary { { (ConnectionProtocol)0, 5058 }, { (ConnectionProtocol)1, 4533 }, { (ConnectionProtocol)4, 9093 }, { (ConnectionProtocol)5, 19093 } }; public ushort NameServerPortOverride; public ChatAppSettings AppSettings { get; private set; } [Obsolete("Replaced by this.AppSettings. Calling ConnectUsingSettings() will set/replace this.AppSettings.")] public bool EnableProtocolFallback { get { return AppSettings?.EnableProtocolFallback ?? false; } set { if (AppSettings != null) { AppSettings.EnableProtocolFallback = value; } } } [Obsolete("Replaced by this.FixedRegionOrDefault. Setting a region should be done via ConnectUsingSettings() parameter AppSettings.")] public string ChatRegion => FixedRegionOrDefault; public string FixedRegionOrDefault { get { if (AppSettings != null && !string.IsNullOrEmpty(AppSettings.FixedRegion)) { return AppSettings.FixedRegion; } return chatRegion; } } [Obsolete("Replaced by this.AppSettings. Calling ConnectUsingSettings() will set/replace this.AppSettings.")] public string ProxyServerAddress => AppSettings?.ProxyServer ?? null; public string CurrentServerAddress => Peer.ServerAddress; public string FrontendAddress { get; private set; } public ChatState State { get; private set; } public ChatDisconnectCause DisconnectedCause { get; private set; } public LogLevel LogLevelPeer { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return Peer.LogLevel; } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Peer.LogLevel = value; AppSettings.NetworkLogging = value; } } public LogLevel LogLevelClient { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return AppSettings.ClientLogging; } set { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) AppSettings.ClientLogging = value; } } public bool CanChat => State == ChatState.ConnectedToFrontEnd; [Obsolete("Replaced by this.AppSettings. Calling ConnectUsingSettings() will set/replace this.AppSettings.")] public string AppVersion => AppSettings?.AppVersion ?? null; [Obsolete("Replaced by this.AppSettings. Calling ConnectUsingSettings() will set/replace this.AppSettings.")] public string AppId => AppSettings?.AppIdChat ?? null; public AuthenticationValues AuthValues { get; set; } public string UserId { get { return (AuthValues != null) ? AuthValues.UserId : null; } private set { if (AuthValues == null) { AuthValues = new AuthenticationValues(); } AuthValues.UserId = value; } } public bool UseBackgroundWorkerForSending { get; set; } public ConnectionProtocol TransportProtocol { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return Peer.TransportProtocol; } private set { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (Peer == null || (int)Peer.PeerState > 0) { IChatClientListener chatClientListener = listener; object obj; if (Peer == null) { obj = "The Peer is null."; } else { PeerStateValue peerState = Peer.PeerState; obj = "PeerState: " + ((object)(PeerStateValue)(ref peerState)).ToString(); } chatClientListener.DebugReturn((LogLevel)2, "Can't set TransportProtocol. Disconnect first! " + (string?)obj); } else { Peer.TransportProtocol = value; } } } public Dictionary SocketImplementationConfig => Peer.SocketImplementationConfig; public string NameServerAddress => GetNameServerAddress(); internal virtual bool IsProtocolSecure => (int)TransportProtocol == 5; public bool CanChatInChannel(string channelName) { return CanChat && PublicChannels.ContainsKey(channelName) && !PublicChannelsUnsubscribing.Contains(channelName); } public ChatClient(IChatClientListener listener, ConnectionProtocol protocol = 0) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown this.listener = listener; State = ChatState.Uninitialized; AppSettings = new ChatAppSettings(); Peer = new PhotonPeer((IPhotonPeerListener)(object)this, protocol); Peer.SerializationProtocolType = (SerializationProtocol)1; PublicChannels = new Dictionary(); PrivateChannels = new Dictionary(); PublicChannelsUnsubscribing = new HashSet(); } public bool ConnectUsingSettings(ChatAppSettings appSettings, AuthenticationValues authValues) { AuthValues = authValues; return ConnectUsingSettings(appSettings); } public bool ConnectUsingSettings(ChatAppSettings appSettings) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (appSettings == null) { listener.DebugReturn((LogLevel)1, "ConnectUsingSettings() failed. The appSettings can't be null.'"); return false; } AppSettings = new ChatAppSettings(appSettings); LogLevelPeer = appSettings.NetworkLogging; TransportProtocol = appSettings.Protocol; if (!appSettings.IsDefaultNameServer) { NameServerHost = appSettings.Server; } NameServerPortOverride = (ushort)((!appSettings.IsDefaultPort) ? appSettings.Port : 0); return ConnectIntern(); } [Obsolete("Use ConnectUsingSettings, which is more feature complete.")] public bool Connect(string appId, string appVersion, AuthenticationValues authValues) { if (authValues != null) { AuthValues = authValues; } AppSettings.AppIdChat = appId; AppSettings.AppVersion = appVersion; return ConnectIntern(); } private bool ConnectIntern() { Peer.PingInterval = 3000; Peer.QuickResendAttempts = 2; Peer.MaxResends = 7; PublicChannels.Clear(); PrivateChannels.Clear(); PublicChannelsUnsubscribing.Clear(); DisconnectedCause = ChatDisconnectCause.None; didAuthenticate = false; bool flag = Peer.Connect(NameServerAddress, AppSettings.AppIdChat, (object)null, (object)null, AppSettings.ProxyServer); if (flag) { State = ChatState.ConnectingToNameServer; } if (UseBackgroundWorkerForSending) { stateTimer = new Timer(SendOutgoingInBackground, null, msDeltaForServiceCalls, msDeltaForServiceCalls); } return flag; } public void Service() { while (Peer.DispatchIncomingCommands()) { } if (!UseBackgroundWorkerForSending && (Environment.TickCount - msTimestampOfLastServiceCall > msDeltaForServiceCalls || msTimestampOfLastServiceCall == 0)) { msTimestampOfLastServiceCall = Environment.TickCount; while (Peer.SendOutgoingCommands()) { } } } private void SendOutgoingInBackground(object state = null) { bool flag = true; while (State != ChatState.Disconnected && flag) { flag = Peer.SendOutgoingCommands(); } } public void Disconnect(ChatDisconnectCause cause = ChatDisconnectCause.DisconnectByClientLogic) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 if (State == ChatState.Disconnecting || State == ChatState.Uninitialized) { listener.DebugReturn((LogLevel)3, "Disconnect() call gets skipped due to State " + State.ToString() + ". DisconnectedCause: " + DisconnectedCause.ToString() + " Parameter cause: " + cause); } else { if (DisconnectedCause == ChatDisconnectCause.None) { DisconnectedCause = cause; } if ((int)Peer.PeerState > 0) { State = ChatState.Disconnecting; Peer.Disconnect(); } } } public bool Subscribe(string[] channels, int[] lastMsgIds) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Invalid comparison between Unknown and I4 if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Subscribe called while not connected to front end server."); } return false; } if (channels == null || channels.Length == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "Subscribe can't be called for empty or null channels-list."); } return false; } for (int i = 0; i < channels.Length; i++) { if (string.IsNullOrEmpty(channels[i])) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"Subscribe can't be called with a null or empty channel name at index {i}."); } return false; } } if (lastMsgIds == null || lastMsgIds.Length != channels.Length) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Subscribe can't be called when \"lastMsgIds\" array is null or does not have the same length as \"channels\" array."); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)0, (object)channels); val.Add((byte)9, (object)lastMsgIds); val.Add((byte)14, -1); ParameterDictionary val2 = val; return Peer.SendOperation((byte)0, val2, SendOptions.SendReliable); } public bool Subscribe(string[] channels, int messagesFromHistory = 0) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Subscribe called while not connected to front end server."); } return false; } if (channels == null || channels.Length == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "Subscribe can't be called for empty or null channels-list."); } return false; } return SendChannelOperation(channels, 0, messagesFromHistory); } public bool Subscribe(string channel, int lastMsgId = 0, int messagesFromHistory = -1, ChannelCreationOptions creationOptions = null) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Invalid comparison between Unknown and I4 //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Invalid comparison between Unknown and I4 //IL_0226: Unknown result type (might be due to invalid IL or missing references) if (creationOptions == null) { creationOptions = ChannelCreationOptions.Default; } int maxSubscribers = creationOptions.MaxSubscribers; bool publishSubscribers = creationOptions.PublishSubscribers; if (maxSubscribers < 0) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Cannot set MaxSubscribers < 0."); } return false; } if (lastMsgId < 0) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "lastMsgId cannot be < 0."); } return false; } if (messagesFromHistory < -1) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "messagesFromHistory < -1, setting it to -1"); } messagesFromHistory = -1; } if (lastMsgId > 0 && messagesFromHistory == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "lastMsgId will be ignored because messagesFromHistory == 0"); } lastMsgId = 0; } Dictionary dictionary = null; if (publishSubscribers) { if (maxSubscribers > 100) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"Cannot set MaxSubscribers > {100} when PublishSubscribers == true."); } return false; } dictionary = new Dictionary(); dictionary[(byte)254] = true; } if (maxSubscribers > 0) { if (dictionary == null) { dictionary = new Dictionary(); } dictionary[byte.MaxValue] = maxSubscribers; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)0, (object)new string[1] { channel }); ParameterDictionary val2 = val; if (messagesFromHistory != 0) { val2.Add((byte)14, messagesFromHistory); } if (lastMsgId > 0) { val2.Add((byte)9, (object)new int[1] { lastMsgId }); } if (dictionary != null && dictionary.Count > 0) { val2.Add((byte)22, (object)dictionary); } return Peer.SendOperation((byte)0, val2, SendOptions.SendReliable); } public bool Unsubscribe(string[] channels) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Unsubscribe called while not connected to front end server."); } return false; } if (channels == null || channels.Length == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "Unsubscribe can't be called for empty or null channels-list."); } return false; } foreach (string item in channels) { PublicChannelsUnsubscribing.Add(item); } return SendChannelOperation(channels, 1, 0); } public bool PublishMessage(string channelName, object message, bool forwardAsWebhook = false) { return publishMessage(channelName, message, reliable: true, forwardAsWebhook); } internal bool PublishMessageUnreliable(string channelName, object message, bool forwardAsWebhook = false) { return publishMessage(channelName, message, reliable: false, forwardAsWebhook); } private bool publishMessage(string channelName, object message, bool reliable, bool forwardAsWebhook = false) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "PublishMessage called while not connected to front end server."); } return false; } if (string.IsNullOrEmpty(channelName) || message == null) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "PublishMessage parameters must be non-null and not empty."); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)1, channelName); val.Add((byte)3, message); ParameterDictionary val2 = val; if (forwardAsWebhook) { val2.Add((byte)21, (byte)1); } PhotonPeer peer = Peer; SendOptions val3 = default(SendOptions); ((SendOptions)(ref val3)).Reliability = reliable; return peer.SendOperation((byte)2, val2, val3); } public bool SendPrivateMessage(string target, object message, bool forwardAsWebhook = false) { return SendPrivateMessage(target, message, encrypt: false, forwardAsWebhook); } public bool SendPrivateMessage(string target, object message, bool encrypt, bool forwardAsWebhook) { return sendPrivateMessage(target, message, encrypt, reliable: true, forwardAsWebhook); } internal bool SendPrivateMessageUnreliable(string target, object message, bool encrypt, bool forwardAsWebhook = false) { return sendPrivateMessage(target, message, encrypt, reliable: false, forwardAsWebhook); } private bool sendPrivateMessage(string target, object message, bool encrypt, bool reliable, bool forwardAsWebhook = false) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "SendPrivateMessage called while not connected to front end server."); } return false; } if (string.IsNullOrEmpty(target) || message == null) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "SendPrivateMessage parameters must be non-null and not empty."); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)225, target); val.Add((byte)3, message); ParameterDictionary val2 = val; if (forwardAsWebhook) { val2.Add((byte)21, (byte)1); } PhotonPeer peer = Peer; SendOptions val3 = default(SendOptions); ((SendOptions)(ref val3)).Reliability = reliable; val3.Encrypt = encrypt; return peer.SendOperation((byte)3, val2, val3); } public bool SetOnlineStatus(int status, object message = null, bool skipMessage = false) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "SetOnlineStatus called while not connected to front end server."); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)10, status); ParameterDictionary val2 = val; if (skipMessage) { val2[(byte)12] = true; } else { val2[(byte)3] = message; } return Peer.SendOperation((byte)5, val2, SendOptions.SendReliable); } public bool AddFriends(string[] friends) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "AddFriends called while not connected to front end server."); } return false; } if (friends == null || friends.Length == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "AddFriends can't be called for empty or null list."); } return false; } if (friends.Length > 1024) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "AddFriends max list size exceeded: " + friends.Length + " > " + 1024); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)11, (object)friends); ParameterDictionary val2 = val; return Peer.SendOperation((byte)6, val2, SendOptions.SendReliable); } public bool RemoveFriends(string[] friends) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 if (!CanChat) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "RemoveFriends called while not connected to front end server."); } return false; } if (friends == null || friends.Length == 0) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "RemoveFriends can't be called for empty or null list."); } return false; } if (friends.Length > 1024) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "RemoveFriends max list size exceeded: " + friends.Length + " > " + 1024); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)11, (object)friends); ParameterDictionary val2 = val; return Peer.SendOperation((byte)7, val2, SendOptions.SendReliable); } public string GetPrivateChannelNameByUser(string userName) { return $"{UserId}:{userName}"; } public bool TryGetChannel(string channelName, bool isPrivate, out ChatChannel channel) { if (!isPrivate) { return PublicChannels.TryGetValue(channelName, out channel); } return PrivateChannels.TryGetValue(channelName, out channel); } public bool TryGetChannel(string channelName, out ChatChannel channel) { bool flag = false; if (PublicChannels.TryGetValue(channelName, out channel)) { return true; } return PrivateChannels.TryGetValue(channelName, out channel); } public bool TryGetPrivateChannelByUser(string userId, out ChatChannel channel) { channel = null; if (string.IsNullOrEmpty(userId)) { return false; } string privateChannelNameByUser = GetPrivateChannelNameByUser(userId); return TryGetChannel(privateChannelNameByUser, isPrivate: true, out channel); } void IPhotonPeerListener.DebugReturn(LogLevel level, string message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) listener.DebugReturn(level, message); } void IPhotonPeerListener.OnEvent(EventData eventData) { switch (eventData.Code) { case 0: HandleChatMessagesEvent(eventData); break; case 2: HandlePrivateMessageEvent(eventData); break; case 4: HandleStatusUpdate(eventData); break; case 5: HandleSubscribeEvent(eventData); break; case 6: HandleUnsubscribeEvent(eventData); break; case 8: HandleUserSubscribedEvent(eventData); break; case 9: HandleUserUnsubscribedEvent(eventData); break; case 1: case 3: case 7: break; } } void IPhotonPeerListener.OnOperationResponse(OperationResponse operationResponse) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 if (operationResponse.ReturnCode == 32743) { Disconnect(ChatDisconnectCause.DisconnectByOperationLimit); } byte operationCode = operationResponse.OperationCode; byte b = operationCode; if ((uint)b > 3u && (uint)(b - 230) <= 1u) { HandleAuthResponse(operationResponse); } else if (operationResponse.ReturnCode != 0 && (int)LogLevelClient >= 1) { if (operationResponse.ReturnCode == -2) { listener.DebugReturn((LogLevel)1, $"Chat Operation {operationResponse.OperationCode} failed on server. Message by server: {operationResponse.DebugMessage}"); } else { listener.DebugReturn((LogLevel)1, $"Chat Operation {operationResponse.OperationCode} failed (Code: {operationResponse.ReturnCode}). Debug Message: {operationResponse.DebugMessage}"); } } } void IPhotonPeerListener.OnStatusChanged(StatusCode statusCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //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_0025: Expected I4, but got Unknown //IL_0027: 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_0067: Expected I4, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Invalid comparison between Unknown and I4 switch (statusCode - 1022) { default: switch (statusCode - 1039) { default: return; case 9: TryAuthenticateOnNameServer(); return; case 3: listener.DebugReturn((LogLevel)1, "This connection was rejected due to the apps CCU limit."); Disconnect(ChatDisconnectCause.MaxCcuReached); return; case 12: Disconnect(ChatDisconnectCause.DnsExceptionOnConnect); return; case 11: Disconnect(ChatDisconnectCause.ServerAddressInvalid); return; case 10: break; case 0: goto IL_0331; case 2: Disconnect(ChatDisconnectCause.ServerTimeout); return; case 4: Disconnect(ChatDisconnectCause.DisconnectByServerLogic); return; case 5: Disconnect(ChatDisconnectCause.DisconnectByServerReasonUnknown); return; case 1: goto IL_0359; case 6: case 7: case 8: return; } goto case 0; case 2: if (!IsProtocolSecure) { if (!Peer.EstablishEncryption() && (int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Error establishing encryption"); } } else { TryAuthenticateOnNameServer(); } if (State == ChatState.ConnectingToNameServer) { State = ChatState.ConnectedToNameServer; listener.OnChatStateChange(State); } else if (State == ChatState.ConnectingToFrontEnd && !AuthenticateOnFrontEnd() && (int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"Error authenticating on frontend! Check log output, AuthValues and if you're connected. State: {State}"); } break; case 3: switch (State) { case ChatState.ConnectWithFallbackProtocol: AppSettings.EnableProtocolFallback = false; NameServerPortOverride = 0; Peer.TransportProtocol = (ConnectionProtocol)((int)Peer.TransportProtocol != 1); ConnectIntern(); return; case ChatState.Authenticated: ConnectToFrontEnd(); return; case ChatState.Disconnecting: if (stateTimer != null) { stateTimer.Dispose(); stateTimer = null; } break; default: { string empty = string.Empty; empty = new StackTrace(fNeedFileInfo: true).ToString(); listener.DebugReturn((LogLevel)2, $"Got an unexpected Disconnect in ChatState: {State}. DisconnectedCause: {DisconnectedCause}. Server: {Peer.ServerAddress} Trace: {empty}"); if (stateTimer != null) { stateTimer.Dispose(); stateTimer = null; } break; } } if (AuthValues != null) { AuthValues.Token = null; } State = ChatState.Disconnected; listener.OnChatStateChange(ChatState.Disconnected); listener.OnDisconnected(); break; case 0: case 1: DisconnectedCause = ChatDisconnectCause.ExceptionOnConnect; if (AppSettings.EnableProtocolFallback && State == ChatState.ConnectingToNameServer) { State = ChatState.ConnectWithFallbackProtocol; } else { Disconnect(ChatDisconnectCause.ExceptionOnConnect); } break; case 4: goto IL_0331; IL_0359: DisconnectedCause = ChatDisconnectCause.ClientTimeout; if (AppSettings.EnableProtocolFallback && State == ChatState.ConnectingToNameServer) { State = ChatState.ConnectWithFallbackProtocol; } else { Disconnect(ChatDisconnectCause.ClientTimeout); } break; IL_0331: Disconnect(ChatDisconnectCause.Exception); break; } } void IPhotonPeerListener.OnMessage(bool isRawMessage, object msg) { } public void OnDisconnectMessage(DisconnectMessage obj) { listener.DebugReturn((LogLevel)1, $"OnDisconnectMessage. Code: {obj.Code} Msg: \"{obj.DebugMessage}\"."); Disconnect(ChatDisconnectCause.DisconnectByDisconnectMessage); } private void TryAuthenticateOnNameServer() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 if (!didAuthenticate) { didAuthenticate = AuthenticateOnNameServer(AppSettings.AppIdChat, AppSettings.AppVersion, FixedRegionOrDefault, AuthValues); if (!didAuthenticate && (int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"Error calling OpAuthenticate! Did not work on NameServer. Check log output, AuthValues and if you're connected. State: {State}"); } } } private bool SendChannelOperation(string[] channels, byte operation, int historyLength) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) ParameterDictionary val = new ParameterDictionary(); val.Add((byte)0, (object)channels); ParameterDictionary val2 = val; if (historyLength != 0) { val2.Add((byte)14, historyLength); } return Peer.SendOperation(operation, val2, SendOptions.SendReliable); } private void HandlePrivateMessageEvent(EventData eventData) { object message = eventData.Parameters[(byte)3]; string text = (string)eventData.Parameters[(byte)5]; int msgId = (int)eventData.Parameters[(byte)8]; string privateChannelNameByUser; if (UserId != null && UserId.Equals(text)) { string userName = (string)eventData.Parameters[(byte)225]; privateChannelNameByUser = GetPrivateChannelNameByUser(userName); } else { privateChannelNameByUser = GetPrivateChannelNameByUser(text); } if (!PrivateChannels.TryGetValue(privateChannelNameByUser, out var value)) { value = new ChatChannel(privateChannelNameByUser); value.IsPrivate = true; value.MessageLimit = MessageLimit; PrivateChannels.Add(value.Name, value); } value.Add(text, message, msgId); listener.OnPrivateMessage(text, message, privateChannelNameByUser); } private void HandleChatMessagesEvent(EventData eventData) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 object[] messages = (object[])eventData.Parameters[(byte)2]; string[] senders = (string[])eventData.Parameters[(byte)4]; string text = (string)eventData.Parameters[(byte)1]; int lastMsgId = (int)eventData.Parameters[(byte)8]; if (!PublicChannels.TryGetValue(text, out var value)) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, "Channel " + text + " for incoming message event not found."); } } else { value.Add(senders, messages, lastMsgId); listener.OnGetMessages(text, senders, messages); } } private void HandleSubscribeEvent(EventData eventData) { string[] array = (string[])eventData.Parameters[(byte)0]; bool[] array2 = (bool[])eventData.Parameters[(byte)15]; object obj = default(object); for (int i = 0; i < array.Length; i++) { if (array2[i]) { string text = array[i]; if (!PublicChannels.TryGetValue(text, out var value)) { value = new ChatChannel(text); value.MessageLimit = MessageLimit; PublicChannels.Add(value.Name, value); } if (eventData.Parameters.TryGetValue((byte)22, ref obj)) { Dictionary newProperties = obj as Dictionary; value.ReadChannelProperties(newProperties); } if (value.PublishSubscribers) { value.AddSubscriber(UserId); } if (eventData.Parameters.TryGetValue((byte)23, ref obj)) { string[] users = obj as string[]; value.AddSubscribers(users); } } } listener.OnSubscribed(array, array2); } private void HandleUnsubscribeEvent(EventData eventData) { string[] array = (string[])eventData[(byte)0]; foreach (string text in array) { PublicChannels.Remove(text); PublicChannelsUnsubscribing.Remove(text); } listener.OnUnsubscribed(array); } private void HandleAuthResponse(OperationResponse operationResponse) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Invalid comparison between Unknown and I4 if ((int)LogLevelClient >= 3) { listener.DebugReturn((LogLevel)3, operationResponse.ToStringFull() + " on: " + CurrentServerAddress); } if (operationResponse.ReturnCode == 0) { if (State == ChatState.ConnectedToNameServer) { State = ChatState.Authenticated; listener.OnChatStateChange(State); if (operationResponse.Parameters.ContainsKey((byte)221)) { if (AuthValues == null) { AuthValues = new AuthenticationValues(); } AuthValues.Token = operationResponse[(byte)221]; FrontendAddress = (string)operationResponse[(byte)230]; Peer.Disconnect(); } else if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "No secret in authentication response."); } if (operationResponse.Parameters.ContainsKey((byte)225)) { string text = operationResponse.Parameters[(byte)225] as string; if (!string.IsNullOrEmpty(text)) { UserId = text; listener.DebugReturn((LogLevel)3, $"Received your UserID from server. Updating local value to: {UserId}"); } } } else if (State == ChatState.ConnectingToFrontEnd) { State = ChatState.ConnectedToFrontEnd; listener.OnChatStateChange(State); listener.OnConnected(); } Dictionary dictionary = (Dictionary)operationResponse[(byte)245]; if (dictionary != null) { listener.OnCustomAuthenticationResponse(dictionary); } } else { switch (operationResponse.ReturnCode) { case short.MaxValue: DisconnectedCause = ChatDisconnectCause.InvalidAuthentication; break; case 32755: DisconnectedCause = ChatDisconnectCause.CustomAuthenticationFailed; listener.OnCustomAuthenticationFailed(operationResponse.DebugMessage); break; case 32756: DisconnectedCause = ChatDisconnectCause.InvalidRegion; break; case 32757: DisconnectedCause = ChatDisconnectCause.MaxCcuReached; break; case -3: DisconnectedCause = ChatDisconnectCause.OperationNotAllowedInCurrentState; break; case 32753: DisconnectedCause = ChatDisconnectCause.AuthenticationTicketExpired; break; } if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"{operationResponse.ToStringFull()} ClientState: {State} ServerAddress: {Peer.ServerAddress}"); } Disconnect(DisconnectedCause); } } private void HandleStatusUpdate(EventData eventData) { string user = (string)eventData.Parameters[(byte)5]; int status = (int)eventData.Parameters[(byte)10]; object message = null; bool flag = eventData.Parameters.ContainsKey((byte)3); if (flag) { message = eventData.Parameters[(byte)3]; } listener.OnStatusUpdate(user, status, flag, message); } private bool ConnectToFrontEnd() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 State = ChatState.ConnectingToFrontEnd; if ((int)LogLevelClient >= 3) { listener.DebugReturn((LogLevel)3, "Connecting to frontend " + FrontendAddress); } if (!Peer.Connect(FrontendAddress, AppSettings.AppIdChat, AuthValues.Token, (object)null, AppSettings.ProxyServer)) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, $"Connecting to frontend {FrontendAddress} failed."); } return false; } return true; } private bool AuthenticateOnFrontEnd() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (AuthValues != null) { if (AuthValues.Token == null) { if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Can't authenticate on front end server. Secret (AuthValues.Token) is not set"); } return false; } ParameterDictionary val = new ParameterDictionary(); val.Add((byte)221, AuthValues.Token); ParameterDictionary val2 = val; if (PrivateChatHistoryLength > -1) { val2[(byte)14] = PrivateChatHistoryLength; } return Peer.SendOperation((byte)230, val2, SendOptions.SendReliable); } if ((int)LogLevelClient >= 1) { listener.DebugReturn((LogLevel)1, "Can't authenticate on front end server. Authentication Values are not set"); } return false; } private void HandleUserUnsubscribedEvent(EventData eventData) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 string text = eventData.Parameters[(byte)1] as string; string text2 = eventData.Parameters[(byte)225] as string; if (PublicChannels.TryGetValue(text, out var value)) { if (!value.PublishSubscribers && (int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" for incoming UserUnsubscribed (\"{text2}\") event does not have PublishSubscribers enabled."); } if (!value.RemoveSubscriber(text2) && (int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" does not contain unsubscribed user \"{text2}\"."); } } else if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" not found for incoming UserUnsubscribed (\"{text2}\") event."); } listener.OnUserUnsubscribed(text, text2); } private void HandleUserSubscribedEvent(EventData eventData) { //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Invalid comparison between Unknown and I4 string text = eventData.Parameters[(byte)1] as string; string text2 = eventData.Parameters[(byte)225] as string; if (PublicChannels.TryGetValue(text, out var value)) { if (!value.PublishSubscribers && (int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" for incoming UserSubscribed (\"{text2}\") event does not have PublishSubscribers enabled."); } if (!value.AddSubscriber(text2)) { if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" already contains newly subscribed user \"{text2}\"."); } } else if (value.MaxSubscribers > 0 && value.Subscribers.Count > value.MaxSubscribers && (int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\"'s MaxSubscribers exceeded. count={value.Subscribers.Count} > MaxSubscribers={value.MaxSubscribers}."); } } else if ((int)LogLevelClient >= 2) { listener.DebugReturn((LogLevel)2, $"Channel \"{text}\" not found for incoming UserSubscribed (\"{text2}\") event."); } listener.OnUserSubscribed(text, text2); } [Conditional("SUPPORTED_UNITY")] private void ConfigUnitySockets() { Type type = null; type = Type.GetType("Photon.Client.SocketWebTcp, PhotonWebSocket", throwOnError: false); if (type == null) { type = Type.GetType("Photon.Client.SocketWebTcp, Assembly-CSharp-firstpass", throwOnError: false); } if (type == null) { type = Type.GetType("Photon.Client.SocketWebTcp, Assembly-CSharp", throwOnError: false); } if (type != null) { SocketImplementationConfig[(ConnectionProtocol)4] = type; SocketImplementationConfig[(ConnectionProtocol)5] = type; } } private string GetNameServerAddress() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected I4, but got Unknown int value = 0; ProtocolToNameServerPort.TryGetValue(TransportProtocol, out value); if (NameServerPortOverride != 0) { listener.DebugReturn((LogLevel)3, $"Using NameServerPortInAppSettings as port for Name Server: {NameServerPortOverride}"); value = NameServerPortOverride; } ConnectionProtocol transportProtocol = TransportProtocol; ConnectionProtocol val = transportProtocol; switch ((int)val) { case 0: case 1: return $"{NameServerHost}:{value}"; case 4: return $"ws://{NameServerHost}:{value}"; case 5: return $"wss://{NameServerHost}:{value}"; default: throw new ArgumentOutOfRangeException(); } } protected internal bool AuthenticateOnNameServer(string appId, string appVersion, string region, AuthenticationValues authValues) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) if ((int)LogLevelClient >= 3) { listener.DebugReturn((LogLevel)3, "OpAuthenticate()"); } ParameterDictionary val = new ParameterDictionary(); val[(byte)220] = appVersion; val[(byte)224] = appId; val[(byte)210] = region; if (authValues != null) { if (!string.IsNullOrEmpty(authValues.UserId)) { val[(byte)225] = authValues.UserId; } if (authValues.AuthType != CustomAuthenticationType.None) { val[(byte)217] = (byte)authValues.AuthType; if (authValues.Token != null) { val[(byte)221] = authValues.Token; } else { if (!string.IsNullOrEmpty(authValues.AuthGetParameters)) { val[(byte)216] = authValues.AuthGetParameters; } if (authValues.AuthPostData != null) { val[(byte)214] = authValues.AuthPostData; } } } } PhotonPeer peer = Peer; SendOptions val2 = default(SendOptions); ((SendOptions)(ref val2)).Reliability = true; val2.Encrypt = true; return peer.SendOperation((byte)230, val, val2); } } public enum ChatDisconnectCause { None, ExceptionOnConnect, DnsExceptionOnConnect, ServerAddressInvalid, Exception, ServerTimeout, ClientTimeout, DisconnectByServerLogic, DisconnectByServerReasonUnknown, InvalidAuthentication, CustomAuthenticationFailed, AuthenticationTicketExpired, MaxCcuReached, InvalidRegion, OperationNotAllowedInCurrentState, DisconnectByClientLogic, DisconnectByOperationLimit, DisconnectByDisconnectMessage } public class ChatEventCode { public const byte ChatMessages = 0; public const byte Users = 1; public const byte PrivateMessage = 2; public const byte FriendsList = 3; public const byte StatusUpdate = 4; public const byte Subscribe = 5; public const byte Unsubscribe = 6; public const byte PropertiesChanged = 7; public const byte UserSubscribed = 8; public const byte UserUnsubscribed = 9; public const byte ErrorInfo = 10; } public class ChatOperationCode { public const byte Authenticate = 230; public const byte AuthenticateOnce = 231; public const byte Subscribe = 0; public const byte Unsubscribe = 1; public const byte Publish = 2; public const byte SendPrivate = 3; public const byte ChannelHistory = 4; public const byte UpdateStatus = 5; public const byte AddFriends = 6; public const byte RemoveFriends = 7; public const byte SetProperties = 8; } public class ChatParameterCode { public const byte ApplicationId = 224; public const byte Secret = 221; public const byte AppVersion = 220; public const byte ClientAuthenticationType = 217; public const byte ClientAuthenticationParams = 216; public const byte ClientAuthenticationData = 214; public const byte Region = 210; public const byte Address = 230; public const byte UserId = 225; public const byte Data = 245; public const byte Channels = 0; public const byte Channel = 1; public const byte Messages = 2; public const byte Message = 3; public const byte Senders = 4; public const byte Sender = 5; public const byte ChannelUserCount = 6; public const byte MsgId = 8; public const byte MsgIds = 9; public const byte SubscribeResults = 15; public const byte Status = 10; public const byte Friends = 11; public const byte SkipMessage = 12; public const byte HistoryLength = 14; public const byte DebugMessage = 17; public const byte WebFlags = 21; public const byte Properties = 22; public const byte ChannelSubscribers = 23; public const byte DebugData = 24; public const byte ExpectedValues = 25; public const byte Broadcast = 26; public const byte UserProperties = 28; public const byte UniqueRoomId = 29; } public enum CustomAuthenticationType : byte { Custom = 0, Steam = 1, Facebook = 2, Oculus = 3, PlayStation4 = 4, Xbox = 5, Viveport = 10, NintendoSwitch = 11, PlayStation5 = 12, Epic = 13, FacebookGaming = 15, None = byte.MaxValue } public class AuthenticationValues { private CustomAuthenticationType authType = CustomAuthenticationType.None; public CustomAuthenticationType AuthType { get { return authType; } set { authType = value; } } public string AuthGetParameters { get; set; } public object AuthPostData { get; private set; } public object Token { get; protected internal set; } public string UserId { get; set; } public AuthenticationValues() { } public AuthenticationValues(string userId) { UserId = userId; } public virtual void SetAuthPostData(string stringData) { AuthPostData = (string.IsNullOrEmpty(stringData) ? null : stringData); } public virtual void SetAuthPostData(byte[] byteData) { AuthPostData = byteData; } public virtual void SetAuthPostData(Dictionary dictData) { AuthPostData = dictData; } public virtual void AddAuthParameter(string key, string value) { string text = (string.IsNullOrEmpty(AuthGetParameters) ? "" : "&"); AuthGetParameters = $"{AuthGetParameters}{text}{Uri.EscapeDataString(key)}={Uri.EscapeDataString(value)}"; } public override string ToString() { return string.Format("AuthenticationValues Type: {3} UserId: {0}, GetParameters: {1} Token available: {2}", UserId, AuthGetParameters, Token != null, AuthType); } public AuthenticationValues CopyTo(AuthenticationValues copy) { copy.AuthType = AuthType; copy.AuthGetParameters = AuthGetParameters; copy.AuthPostData = AuthPostData; copy.UserId = UserId; return copy; } } public class ErrorCode { public const int Ok = 0; public const int OperationNotAllowedInCurrentState = -3; public const int InvalidOperationCode = -2; public const int InternalServerError = -1; public const int InvalidAuthentication = 32767; public const int GameIdAlreadyExists = 32766; public const int GameFull = 32765; public const int GameClosed = 32764; public const int ServerFull = 32762; public const int UserBlocked = 32761; public const int NoRandomMatchFound = 32760; public const int GameDoesNotExist = 32758; public const int MaxCcuReached = 32757; public const int InvalidRegion = 32756; public const int CustomAuthenticationFailed = 32755; public const int AuthenticationTicketExpired = 32753; public const int OperationLimitReached = 32743; } public enum ChatState { Uninitialized, ConnectingToNameServer, ConnectedToNameServer, Authenticating, Authenticated, DisconnectingFromNameServer, ConnectingToFrontEnd, ConnectedToFrontEnd, DisconnectingFromFrontEnd, QueuedComingFromFrontEnd, Disconnecting, Disconnected, ConnectWithFallbackProtocol } public static class ChatUserStatus { public const int Offline = 0; public const int Invisible = 1; public const int Online = 2; public const int Away = 3; public const int DND = 4; public const int LFG = 5; public const int Playing = 6; } public interface IChatClientListener { void DebugReturn(LogLevel level, string message); void OnDisconnected(); void OnConnected(); void OnCustomAuthenticationResponse(Dictionary data); void OnCustomAuthenticationFailed(string debugMessage); void OnChatStateChange(ChatState state); void OnGetMessages(string channelName, string[] senders, object[] messages); void OnPrivateMessage(string sender, object message, string channelName); void OnSubscribed(string[] channels, bool[] results); void OnUnsubscribed(string[] channels); void OnStatusUpdate(string user, int status, bool gotMessage, object message); void OnUserSubscribed(string channel, string user); void OnUserUnsubscribed(string channel, string user); }