using System; using System.Collections.Generic; using System.IO; namespace ExitGames.Client.Photon { // Token: 0x0200001A RID: 26 internal class TPeer : PeerBase { // Token: 0x17000061 RID: 97 // (get) Token: 0x0600017E RID: 382 RVA: 0x0000E0D8 File Offset: 0x0000C2D8 internal override int QueuedIncomingCommandsCount { get { return this.incomingList.Count; } } // Token: 0x17000062 RID: 98 // (get) Token: 0x0600017F RID: 383 RVA: 0x0000E0F8 File Offset: 0x0000C2F8 internal override int QueuedOutgoingCommandsCount { get { return this.outgoingCommandsInStream; } } // Token: 0x06000180 RID: 384 RVA: 0x0000E110 File Offset: 0x0000C310 internal TPeer() { byte[] array = new byte[5]; array[0] = 240; this.pingRequest = array; this.DoFraming = true; base..ctor(); PeerBase.peerCount += 1; base.InitOnce(); this.TrafficPackageHeaderSize = 0; } // Token: 0x06000181 RID: 385 RVA: 0x0000E168 File Offset: 0x0000C368 internal override void InitPeerBase() { base.InitPeerBase(); this.incomingList = new Queue(32); } // Token: 0x06000182 RID: 386 RVA: 0x0000E180 File Offset: 0x0000C380 internal override bool Connect(string serverAddress, string appID, object customData = null) { bool flag = this.peerConnectionState > PeerBase.ConnectionStateValue.Disconnected; bool flag2; if (flag) { base.Listener.DebugReturn(DebugLevel.WARNING, "Connect() can't be called if peer is not Disconnected. Not connecting."); flag2 = false; } else { bool flag3 = base.debugOut >= DebugLevel.ALL; if (flag3) { base.Listener.DebugReturn(DebugLevel.ALL, "Connect()"); } base.ServerAddress = serverAddress; this.InitPeerBase(); this.outgoingStream = new List(); bool flag4 = this.usedProtocol == ConnectionProtocol.WebSocket || this.usedProtocol == ConnectionProtocol.WebSocketSecure; if (flag4) { serverAddress = base.PepareWebSocketUrl(serverAddress, appID, customData); } bool flag5 = base.SocketImplementation != null; if (flag5) { this.rt = (IPhotonSocket)Activator.CreateInstance(base.SocketImplementation, new object[] { this }); } else { this.rt = new SocketTcp(this); } bool flag6 = this.rt == null; if (flag6) { base.Listener.DebugReturn(DebugLevel.ERROR, "Connect() failed, because SocketImplementation or socket was null. Set PhotonPeer.SocketImplementation before Connect(). SocketImplementation: " + base.SocketImplementation); flag2 = false; } else { this.messageHeader = (this.DoFraming ? TPeer.tcpFramedMessageHead : TPeer.tcpMsgHead); bool flag7 = this.rt.Connect(); if (flag7) { this.peerConnectionState = PeerBase.ConnectionStateValue.Connecting; flag2 = true; } else { this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnected; flag2 = false; } } } return flag2; } // Token: 0x06000183 RID: 387 RVA: 0x0000E2D0 File Offset: 0x0000C4D0 public override void OnConnect() { byte[] array = base.PrepareConnectData(base.ServerAddress, this.AppId, this.CustomInitData); this.EnqueueInit(array); this.SendOutgoingCommands(); } // Token: 0x06000184 RID: 388 RVA: 0x0000E308 File Offset: 0x0000C508 internal override void Disconnect() { bool flag = this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnected || this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnecting; if (!flag) { bool flag2 = base.debugOut >= DebugLevel.ALL; if (flag2) { base.Listener.DebugReturn(DebugLevel.ALL, "TPeer.Disconnect()"); } this.StopConnection(); } } // Token: 0x06000185 RID: 389 RVA: 0x0000E35C File Offset: 0x0000C55C internal override void StopConnection() { this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnecting; bool flag = this.rt != null; if (flag) { this.rt.Disconnect(); } Queue queue = this.incomingList; lock (queue) { this.incomingList.Clear(); } this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnected; base.EnqueueStatusCallback(StatusCode.Disconnect); } // Token: 0x06000186 RID: 390 RVA: 0x0000E3D8 File Offset: 0x0000C5D8 internal override void FetchServerTimestamp() { bool flag = this.peerConnectionState != PeerBase.ConnectionStateValue.Connected; if (flag) { bool flag2 = base.debugOut >= DebugLevel.INFO; if (flag2) { base.Listener.DebugReturn(DebugLevel.INFO, "FetchServerTimestamp() was skipped, as the client is not connected. Current ConnectionState: " + this.peerConnectionState); } base.Listener.OnStatusChanged(StatusCode.SendError); } else { this.SendPing(); this.serverTimeOffsetIsAvailable = false; } } // Token: 0x06000187 RID: 391 RVA: 0x0000E44C File Offset: 0x0000C64C private void EnqueueInit(byte[] data) { bool flag = !this.DoFraming; if (!flag) { StreamBuffer streamBuffer = new StreamBuffer(data.Length + 32); BinaryWriter binaryWriter = new BinaryWriter(streamBuffer); byte[] array = new byte[] { 251, 0, 0, 0, 0, 0, 1 }; int num = 1; Protocol.Serialize(data.Length + array.Length, array, ref num); binaryWriter.Write(array); binaryWriter.Write(data); byte[] array2 = streamBuffer.ToArray(); bool trafficStatsEnabled = base.TrafficStatsEnabled; if (trafficStatsEnabled) { TrafficStats trafficStatsOutgoing = base.TrafficStatsOutgoing; int num2 = trafficStatsOutgoing.TotalPacketCount; trafficStatsOutgoing.TotalPacketCount = num2 + 1; TrafficStats trafficStatsOutgoing2 = base.TrafficStatsOutgoing; num2 = trafficStatsOutgoing2.TotalCommandsInPackets; trafficStatsOutgoing2.TotalCommandsInPackets = num2 + 1; base.TrafficStatsOutgoing.CountControlCommand(array2.Length); } this.EnqueueMessageAsPayload(true, array2, 0); } } // Token: 0x06000188 RID: 392 RVA: 0x0000E518 File Offset: 0x0000C718 internal override bool DispatchIncomingCommands() { for (;;) { Queue actionQueue = this.ActionQueue; PeerBase.MyAction myAction; lock (actionQueue) { bool flag = this.ActionQueue.Count <= 0; if (flag) { break; } myAction = this.ActionQueue.Dequeue(); } myAction(); } Queue queue = this.incomingList; byte[] array; lock (queue) { bool flag2 = this.incomingList.Count <= 0; if (flag2) { return false; } array = this.incomingList.Dequeue(); } this.ByteCountCurrentDispatch = array.Length + 3; return this.DeserializeMessageAndCallback(array); } // Token: 0x06000189 RID: 393 RVA: 0x0000E5F0 File Offset: 0x0000C7F0 internal override bool SendOutgoingCommands() { bool flag = this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnected; bool flag2; if (flag) { flag2 = false; } else { bool flag3 = !this.rt.Connected; if (flag3) { flag2 = false; } else { this.timeInt = SupportClass.GetTickCount() - this.timeBase; this.timeLastSendOutgoing = this.timeInt; bool flag4 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connected && Math.Abs(SupportClass.GetTickCount() - this.lastPingResult) > base.timePingInterval; if (flag4) { this.SendPing(); } List list = this.outgoingStream; lock (list) { foreach (byte[] array in this.outgoingStream) { this.SendData(array); } this.outgoingStream.Clear(); this.outgoingCommandsInStream = 0; } flag2 = false; } } return flag2; } // Token: 0x0600018A RID: 394 RVA: 0x0000E70C File Offset: 0x0000C90C internal override bool SendAcksOnly() { bool flag = this.rt == null || !this.rt.Connected; bool flag2; if (flag) { flag2 = false; } else { this.timeInt = SupportClass.GetTickCount() - this.timeBase; bool flag3 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connected && SupportClass.GetTickCount() - this.lastPingResult > base.timePingInterval; if (flag3) { this.SendPing(); } flag2 = false; } return flag2; } // Token: 0x0600018B RID: 395 RVA: 0x0000E780 File Offset: 0x0000C980 internal override bool EnqueueOperation(Dictionary parameters, byte opCode, bool sendReliable, byte channelId, bool encrypt, PeerBase.EgMessageType messageType) { bool flag = this.peerConnectionState != PeerBase.ConnectionStateValue.Connected; bool flag3; if (flag) { bool flag2 = base.debugOut >= DebugLevel.ERROR; if (flag2) { base.Listener.DebugReturn(DebugLevel.ERROR, string.Concat(new object[] { "Cannot send op: ", opCode, "! Not connected. PeerState: ", this.peerConnectionState })); } base.Listener.OnStatusChanged(StatusCode.SendError); flag3 = false; } else { bool flag4 = channelId >= base.ChannelCount; if (flag4) { bool flag5 = base.debugOut >= DebugLevel.ERROR; if (flag5) { base.Listener.DebugReturn(DebugLevel.ERROR, string.Concat(new object[] { "Cannot send op: Selected channel (", channelId, ")>= channelCount (", base.ChannelCount, ")." })); } base.Listener.OnStatusChanged(StatusCode.SendError); flag3 = false; } else { byte[] array = this.SerializeOperationToMessage(opCode, parameters, messageType, encrypt); flag3 = this.EnqueueMessageAsPayload(sendReliable, array, channelId); } } return flag3; } // Token: 0x0600018C RID: 396 RVA: 0x0000E8A8 File Offset: 0x0000CAA8 internal override byte[] SerializeOperationToMessage(byte opc, Dictionary parameters, PeerBase.EgMessageType messageType, bool encrypt) { StreamBuffer serializeMemStream = this.SerializeMemStream; byte[] array2; lock (serializeMemStream) { this.SerializeMemStream.SetLength(0L); bool flag = !encrypt; if (flag) { this.SerializeMemStream.Write(this.messageHeader, 0, this.messageHeader.Length); } this.protocol.SerializeOperationRequest(this.SerializeMemStream, opc, parameters, false); if (encrypt) { byte[] array = this.CryptoProvider.Encrypt(this.SerializeMemStream.GetBuffer(), 0, (int)this.SerializeMemStream.Length); this.SerializeMemStream.SetLength(0L); this.SerializeMemStream.Write(this.messageHeader, 0, this.messageHeader.Length); this.SerializeMemStream.Write(array, 0, array.Length); } array2 = this.SerializeMemStream.ToArray(); } bool flag2 = messageType != PeerBase.EgMessageType.Operation; if (flag2) { array2[this.messageHeader.Length - 1] = (byte)messageType; } if (encrypt) { array2[this.messageHeader.Length - 1] = array2[this.messageHeader.Length - 1] | 128; } bool doFraming = this.DoFraming; if (doFraming) { int num = 1; Protocol.Serialize(array2.Length, array2, ref num); } return array2; } // Token: 0x0600018D RID: 397 RVA: 0x0000EA08 File Offset: 0x0000CC08 internal bool EnqueueMessageAsPayload(bool sendReliable, byte[] opMessage, byte channelId) { bool flag = opMessage == null; bool flag2; if (flag) { flag2 = false; } else { bool doFraming = this.DoFraming; if (doFraming) { opMessage[5] = channelId; opMessage[6] = (sendReliable ? 1 : 0); } List list = this.outgoingStream; lock (list) { this.outgoingStream.Add(opMessage); this.outgoingCommandsInStream++; } int num = opMessage.Length; this.ByteCountLastOperation = num; bool trafficStatsEnabled = base.TrafficStatsEnabled; if (trafficStatsEnabled) { if (sendReliable) { base.TrafficStatsOutgoing.CountReliableOpCommand(num); } else { base.TrafficStatsOutgoing.CountUnreliableOpCommand(num); } base.TrafficStatsGameLevel.CountOperation(num); } flag2 = true; } return flag2; } // Token: 0x0600018E RID: 398 RVA: 0x0000EADC File Offset: 0x0000CCDC internal void SendPing() { this.lastPingResult = SupportClass.GetTickCount(); bool flag = !this.DoFraming; if (flag) { int tickCount = SupportClass.GetTickCount(); this.EnqueueOperation(new Dictionary { { 1, tickCount } }, PhotonCodes.Ping, true, 0, false, PeerBase.EgMessageType.InternalOperationRequest); } else { int num = 1; Protocol.Serialize(SupportClass.GetTickCount(), this.pingRequest, ref num); bool trafficStatsEnabled = base.TrafficStatsEnabled; if (trafficStatsEnabled) { base.TrafficStatsOutgoing.CountControlCommand(this.pingRequest.Length); } this.SendData(this.pingRequest); } } // Token: 0x0600018F RID: 399 RVA: 0x0000EB74 File Offset: 0x0000CD74 internal void SendData(byte[] data) { try { this.bytesOut += (long)data.Length; bool trafficStatsEnabled = base.TrafficStatsEnabled; if (trafficStatsEnabled) { TrafficStats trafficStatsOutgoing = base.TrafficStatsOutgoing; int totalPacketCount = trafficStatsOutgoing.TotalPacketCount; trafficStatsOutgoing.TotalPacketCount = totalPacketCount + 1; base.TrafficStatsOutgoing.TotalCommandsInPackets += this.outgoingCommandsInStream; } bool isSimulationEnabled = base.NetworkSimulationSettings.IsSimulationEnabled; if (isSimulationEnabled) { base.SendNetworkSimulated(data); } else { this.rt.Send(data, data.Length); } } catch (Exception ex) { bool flag = base.debugOut >= DebugLevel.ERROR; if (flag) { base.Listener.DebugReturn(DebugLevel.ERROR, ex.ToString()); } SupportClass.WriteStackTrace(ex); } } // Token: 0x06000190 RID: 400 RVA: 0x0000EC44 File Offset: 0x0000CE44 internal override void ReceiveIncomingCommands(byte[] inbuff, int dataLength) { bool flag = inbuff == null; if (flag) { bool flag2 = base.debugOut >= DebugLevel.ERROR; if (flag2) { base.EnqueueDebugReturn(DebugLevel.ERROR, "checkAndQueueIncomingCommands() inBuff: null"); } } else { this.timestampOfLastReceive = SupportClass.GetTickCount(); this.timeInt = SupportClass.GetTickCount() - this.timeBase; this.bytesIn += (long)(inbuff.Length + 7); bool trafficStatsEnabled = base.TrafficStatsEnabled; if (trafficStatsEnabled) { TrafficStats trafficStatsIncoming = base.TrafficStatsIncoming; int num = trafficStatsIncoming.TotalPacketCount; trafficStatsIncoming.TotalPacketCount = num + 1; TrafficStats trafficStatsIncoming2 = base.TrafficStatsIncoming; num = trafficStatsIncoming2.TotalCommandsInPackets; trafficStatsIncoming2.TotalCommandsInPackets = num + 1; } bool flag3 = inbuff[0] == 243 || inbuff[0] == 244; if (flag3) { Queue queue = this.incomingList; lock (queue) { this.incomingList.Enqueue(inbuff); } } else { bool flag4 = inbuff[0] == 240; if (flag4) { base.TrafficStatsIncoming.CountControlCommand(inbuff.Length); this.ReadPingResult(inbuff); } else { bool flag5 = base.debugOut >= DebugLevel.ERROR; if (flag5) { base.EnqueueDebugReturn(DebugLevel.ERROR, "receiveIncomingCommands() MagicNumber should be 0xF0, 0xF3 or 0xF4. Is: " + inbuff[0]); } } } } } // Token: 0x06000191 RID: 401 RVA: 0x0000ED9C File Offset: 0x0000CF9C private void ReadPingResult(byte[] inbuff) { int num = 0; int num2 = 0; int num3 = 1; Protocol.Deserialize(out num, inbuff, ref num3); Protocol.Deserialize(out num2, inbuff, ref num3); this.lastRoundTripTime = SupportClass.GetTickCount() - num2; bool flag = !this.serverTimeOffsetIsAvailable; if (flag) { this.roundTripTime = this.lastRoundTripTime; } base.UpdateRoundTripTimeAndVariance(this.lastRoundTripTime); bool flag2 = !this.serverTimeOffsetIsAvailable; if (flag2) { this.serverTimeOffset = num + (this.lastRoundTripTime >> 1) - SupportClass.GetTickCount(); this.serverTimeOffsetIsAvailable = true; } } // Token: 0x06000192 RID: 402 RVA: 0x0000EE2C File Offset: 0x0000D02C protected internal void ReadPingResult(OperationResponse operationResponse) { int num = (int)operationResponse.Parameters[2]; int num2 = (int)operationResponse.Parameters[1]; this.lastRoundTripTime = SupportClass.GetTickCount() - num2; bool flag = !this.serverTimeOffsetIsAvailable; if (flag) { this.roundTripTime = this.lastRoundTripTime; } base.UpdateRoundTripTimeAndVariance(this.lastRoundTripTime); bool flag2 = !this.serverTimeOffsetIsAvailable; if (flag2) { this.serverTimeOffset = num + (this.lastRoundTripTime >> 1) - SupportClass.GetTickCount(); this.serverTimeOffsetIsAvailable = true; } } // Token: 0x040000FE RID: 254 internal const int TCP_HEADER_BYTES = 7; // Token: 0x040000FF RID: 255 internal const int MSG_HEADER_BYTES = 2; // Token: 0x04000100 RID: 256 public const int ALL_HEADER_BYTES = 9; // Token: 0x04000101 RID: 257 private Queue incomingList = new Queue(32); // Token: 0x04000102 RID: 258 internal List outgoingStream; // Token: 0x04000103 RID: 259 private int lastPingResult; // Token: 0x04000104 RID: 260 private byte[] pingRequest; // Token: 0x04000105 RID: 261 internal static readonly byte[] tcpFramedMessageHead = new byte[] { 251, 0, 0, 0, 0, 0, 0, 243, 2 }; // Token: 0x04000106 RID: 262 internal static readonly byte[] tcpMsgHead = new byte[] { 243, 2 }; // Token: 0x04000107 RID: 263 internal byte[] messageHeader; // Token: 0x04000108 RID: 264 protected internal bool DoFraming; } }