1756 lines
53 KiB
C#
1756 lines
53 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using ExitGames.Client.Photon.EncryptorManaged;
|
|
|
|
namespace ExitGames.Client.Photon
|
|
{
|
|
// Token: 0x02000017 RID: 23
|
|
internal class EnetPeer : PeerBase
|
|
{
|
|
// Token: 0x1700005C RID: 92
|
|
// (get) Token: 0x0600014A RID: 330 RVA: 0x0000A930 File Offset: 0x00008B30
|
|
internal override int QueuedIncomingCommandsCount
|
|
{
|
|
get
|
|
{
|
|
int num = 0;
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
for (int i = 0; i < this.channelArray.Length; i++)
|
|
{
|
|
EnetChannel enetChannel = this.channelArray[i];
|
|
num += enetChannel.incomingReliableCommandsList.Count;
|
|
num += enetChannel.incomingUnreliableCommandsList.Count;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700005D RID: 93
|
|
// (get) Token: 0x0600014B RID: 331 RVA: 0x0000A9B4 File Offset: 0x00008BB4
|
|
internal override int QueuedOutgoingCommandsCount
|
|
{
|
|
get
|
|
{
|
|
int num = 0;
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
for (int i = 0; i < this.channelArray.Length; i++)
|
|
{
|
|
EnetChannel enetChannel = this.channelArray[i];
|
|
num += enetChannel.outgoingReliableCommandsList.Count;
|
|
num += enetChannel.outgoingUnreliableCommandsList.Count;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700005E RID: 94
|
|
// (get) Token: 0x0600014C RID: 332 RVA: 0x0000AA38 File Offset: 0x00008C38
|
|
private Encryptor encryptor
|
|
{
|
|
get
|
|
{
|
|
return this.ppeer.encryptor;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700005F RID: 95
|
|
// (get) Token: 0x0600014D RID: 333 RVA: 0x0000AA58 File Offset: 0x00008C58
|
|
private Decryptor decryptor
|
|
{
|
|
get
|
|
{
|
|
return this.ppeer.decryptor;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600014E RID: 334 RVA: 0x0000AA78 File Offset: 0x00008C78
|
|
internal EnetPeer()
|
|
{
|
|
PeerBase.peerCount += 1;
|
|
base.InitOnce();
|
|
this.TrafficPackageHeaderSize = 12;
|
|
}
|
|
|
|
// Token: 0x0600014F RID: 335 RVA: 0x0000AAE4 File Offset: 0x00008CE4
|
|
internal override void InitPeerBase()
|
|
{
|
|
base.InitPeerBase();
|
|
bool flag = this.ppeer.PayloadEncryptionSecret != null && this.usedProtocol == ConnectionProtocol.Udp;
|
|
if (flag)
|
|
{
|
|
this.InitEncryption(this.ppeer.PayloadEncryptionSecret);
|
|
}
|
|
bool flag2 = this.encryptor != null && this.decryptor != null;
|
|
if (flag2)
|
|
{
|
|
this.isEncryptionAvailable = true;
|
|
}
|
|
this.peerID = (this.ppeer.EnableServerTracing ? -2 : -1);
|
|
this.challenge = SupportClass.ThreadSafeRandom.Next();
|
|
bool flag3 = this.udpBuffer == null || this.udpBuffer.Length != base.mtu;
|
|
if (flag3)
|
|
{
|
|
this.udpBuffer = new byte[base.mtu];
|
|
}
|
|
this.reliableCommandsSent = 0;
|
|
this.reliableCommandsRepeated = 0;
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
EnetChannel[] array2 = this.channelArray;
|
|
bool flag4 = array2.Length != (int)(base.ChannelCount + 1);
|
|
if (flag4)
|
|
{
|
|
array2 = new EnetChannel[(int)(base.ChannelCount + 1)];
|
|
}
|
|
for (byte b = 0; b < base.ChannelCount; b += 1)
|
|
{
|
|
array2[(int)b] = new EnetChannel(b, this.commandBufferSize);
|
|
}
|
|
array2[(int)base.ChannelCount] = new EnetChannel(byte.MaxValue, this.commandBufferSize);
|
|
this.channelArray = array2;
|
|
}
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
this.sentReliableCommands = new List<NCommand>(this.commandBufferSize);
|
|
}
|
|
this.outgoingAcknowledgementsPool = new StreamBuffer(0);
|
|
base.CommandLogInit();
|
|
}
|
|
|
|
// Token: 0x06000150 RID: 336 RVA: 0x0000ACAC File Offset: 0x00008EAC
|
|
internal override bool Connect(string ipport, string appID, object custom = 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. peerConnectionState: " + this.peerConnectionState);
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
bool flag3 = base.debugOut >= DebugLevel.ALL;
|
|
if (flag3)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ALL, "Connect()");
|
|
}
|
|
base.ServerAddress = ipport;
|
|
this.InitPeerBase();
|
|
bool flag4 = base.SocketImplementation != null;
|
|
if (flag4)
|
|
{
|
|
this.rt = (IPhotonSocket)Activator.CreateInstance(base.SocketImplementation, new object[] { this });
|
|
}
|
|
else
|
|
{
|
|
this.rt = new SocketUdp(this);
|
|
}
|
|
bool flag5 = this.rt == null;
|
|
if (flag5)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ERROR, "Connect() failed, because SocketImplementation or socket was null. Set PhotonPeer.SocketImplementation before Connect().");
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
bool flag6 = this.rt.Connect();
|
|
if (flag6)
|
|
{
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
base.TrafficStatsOutgoing.ControlCommandBytes += 44;
|
|
base.TrafficStatsOutgoing.ControlCommandCount++;
|
|
}
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Connecting;
|
|
flag2 = true;
|
|
}
|
|
else
|
|
{
|
|
flag2 = false;
|
|
}
|
|
}
|
|
}
|
|
return flag2;
|
|
}
|
|
|
|
// Token: 0x06000151 RID: 337 RVA: 0x0000ADE2 File Offset: 0x00008FE2
|
|
public override void OnConnect()
|
|
{
|
|
this.QueueOutgoingReliableCommand(new NCommand(this, 2, null, byte.MaxValue));
|
|
}
|
|
|
|
// Token: 0x06000152 RID: 338 RVA: 0x0000ADFC File Offset: 0x00008FFC
|
|
internal override void Disconnect()
|
|
{
|
|
bool flag = this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnected || this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnecting;
|
|
if (!flag)
|
|
{
|
|
bool flag2 = this.sentReliableCommands != null;
|
|
if (flag2)
|
|
{
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
this.sentReliableCommands.Clear();
|
|
}
|
|
}
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
foreach (EnetChannel enetChannel in this.channelArray)
|
|
{
|
|
enetChannel.clearAll();
|
|
}
|
|
}
|
|
bool isSimulationEnabled = base.NetworkSimulationSettings.IsSimulationEnabled;
|
|
base.NetworkSimulationSettings.IsSimulationEnabled = false;
|
|
NCommand ncommand = new NCommand(this, 4, null, byte.MaxValue);
|
|
this.QueueOutgoingReliableCommand(ncommand);
|
|
this.SendOutgoingCommands();
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
base.TrafficStatsOutgoing.CountControlCommand(ncommand.Size);
|
|
}
|
|
base.NetworkSimulationSettings.IsSimulationEnabled = isSimulationEnabled;
|
|
this.rt.Disconnect();
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnected;
|
|
base.EnqueueStatusCallback(StatusCode.Disconnect);
|
|
this.datagramEncryptedConnection = false;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000153 RID: 339 RVA: 0x0000AF50 File Offset: 0x00009150
|
|
internal override void StopConnection()
|
|
{
|
|
bool flag = this.rt != null;
|
|
if (flag)
|
|
{
|
|
this.rt.Disconnect();
|
|
}
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnected;
|
|
bool flag2 = base.Listener != null;
|
|
if (flag2)
|
|
{
|
|
base.Listener.OnStatusChanged(StatusCode.Disconnect);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000154 RID: 340 RVA: 0x0000AFA0 File Offset: 0x000091A0
|
|
internal override void FetchServerTimestamp()
|
|
{
|
|
bool flag = this.peerConnectionState != PeerBase.ConnectionStateValue.Connected || !this.ApplicationIsInitialized;
|
|
if (flag)
|
|
{
|
|
bool flag2 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag2)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.INFO, "FetchServerTimestamp() was skipped, as the client is not connected. Current ConnectionState: " + this.peerConnectionState);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.CreateAndEnqueueCommand(12, new byte[0], byte.MaxValue);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000155 RID: 341 RVA: 0x0000B010 File Offset: 0x00009210
|
|
internal override bool DispatchIncomingCommands()
|
|
{
|
|
for (;;)
|
|
{
|
|
Queue<PeerBase.MyAction> actionQueue = this.ActionQueue;
|
|
PeerBase.MyAction myAction;
|
|
lock (actionQueue)
|
|
{
|
|
bool flag = this.ActionQueue.Count <= 0;
|
|
if (flag)
|
|
{
|
|
break;
|
|
}
|
|
myAction = this.ActionQueue.Dequeue();
|
|
}
|
|
myAction();
|
|
}
|
|
NCommand ncommand = null;
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
for (int i = 0; i < this.channelArray.Length; i++)
|
|
{
|
|
EnetChannel enetChannel = this.channelArray[i];
|
|
bool flag2 = enetChannel.incomingUnreliableCommandsList.Count > 0;
|
|
if (flag2)
|
|
{
|
|
int num = int.MaxValue;
|
|
foreach (int num2 in enetChannel.incomingUnreliableCommandsList.Keys)
|
|
{
|
|
NCommand ncommand2 = enetChannel.incomingUnreliableCommandsList[num2];
|
|
bool flag3 = num2 < enetChannel.incomingUnreliableSequenceNumber || ncommand2.reliableSequenceNumber < enetChannel.incomingReliableSequenceNumber;
|
|
if (flag3)
|
|
{
|
|
this.commandsToRemove.Enqueue(num2);
|
|
}
|
|
else
|
|
{
|
|
bool flag4 = base.limitOfUnreliableCommands > 0 && enetChannel.incomingUnreliableCommandsList.Count > base.limitOfUnreliableCommands;
|
|
if (flag4)
|
|
{
|
|
this.commandsToRemove.Enqueue(num2);
|
|
}
|
|
else
|
|
{
|
|
bool flag5 = num2 < num;
|
|
if (flag5)
|
|
{
|
|
bool flag6 = ncommand2.reliableSequenceNumber > enetChannel.incomingReliableSequenceNumber;
|
|
if (!flag6)
|
|
{
|
|
num = num2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while (this.commandsToRemove.Count > 0)
|
|
{
|
|
enetChannel.incomingUnreliableCommandsList.Remove(this.commandsToRemove.Dequeue());
|
|
}
|
|
bool flag7 = num < int.MaxValue;
|
|
if (flag7)
|
|
{
|
|
ncommand = enetChannel.incomingUnreliableCommandsList[num];
|
|
}
|
|
bool flag8 = ncommand != null;
|
|
if (flag8)
|
|
{
|
|
enetChannel.incomingUnreliableCommandsList.Remove(ncommand.unreliableSequenceNumber);
|
|
enetChannel.incomingUnreliableSequenceNumber = ncommand.unreliableSequenceNumber;
|
|
break;
|
|
}
|
|
}
|
|
bool flag9 = ncommand == null && enetChannel.incomingReliableCommandsList.Count > 0;
|
|
if (flag9)
|
|
{
|
|
enetChannel.incomingReliableCommandsList.TryGetValue(enetChannel.incomingReliableSequenceNumber + 1, out ncommand);
|
|
bool flag10 = ncommand == null;
|
|
if (!flag10)
|
|
{
|
|
bool flag11 = ncommand.commandType != 8;
|
|
if (flag11)
|
|
{
|
|
enetChannel.incomingReliableSequenceNumber = ncommand.reliableSequenceNumber;
|
|
enetChannel.incomingReliableCommandsList.Remove(ncommand.reliableSequenceNumber);
|
|
break;
|
|
}
|
|
bool flag12 = ncommand.fragmentsRemaining > 0;
|
|
if (flag12)
|
|
{
|
|
ncommand = null;
|
|
}
|
|
else
|
|
{
|
|
byte[] array2 = new byte[ncommand.totalLength];
|
|
for (int j = ncommand.startSequenceNumber; j < ncommand.startSequenceNumber + ncommand.fragmentCount; j++)
|
|
{
|
|
bool flag13 = enetChannel.ContainsReliableSequenceNumber(j);
|
|
if (!flag13)
|
|
{
|
|
throw new Exception("command.fragmentsRemaining was 0, but not all fragments are found to be combined!");
|
|
}
|
|
NCommand ncommand3 = enetChannel.FetchReliableSequenceNumber(j);
|
|
Buffer.BlockCopy(ncommand3.Payload, 0, array2, ncommand3.fragmentOffset, ncommand3.Payload.Length);
|
|
enetChannel.incomingReliableCommandsList.Remove(ncommand3.reliableSequenceNumber);
|
|
}
|
|
bool flag14 = base.debugOut >= DebugLevel.ALL;
|
|
if (flag14)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ALL, "assembled fragmented payload from " + ncommand.fragmentCount + " parts. Dispatching now.");
|
|
}
|
|
ncommand.Payload = array2;
|
|
ncommand.Size = 12 * ncommand.fragmentCount + ncommand.totalLength;
|
|
enetChannel.incomingReliableSequenceNumber = ncommand.reliableSequenceNumber + ncommand.fragmentCount - 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool flag15 = ncommand != null && ncommand.Payload != null;
|
|
if (flag15)
|
|
{
|
|
this.ByteCountCurrentDispatch = ncommand.Size;
|
|
this.CommandInCurrentDispatch = ncommand;
|
|
bool flag16 = this.DeserializeMessageAndCallback(ncommand.Payload);
|
|
if (flag16)
|
|
{
|
|
this.CommandInCurrentDispatch = null;
|
|
return true;
|
|
}
|
|
this.CommandInCurrentDispatch = null;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x06000156 RID: 342 RVA: 0x0000B488 File Offset: 0x00009688
|
|
private int GetFragmentLength()
|
|
{
|
|
int num = base.mtu;
|
|
bool flag = this.datagramEncryptedConnection;
|
|
int num2;
|
|
if (flag)
|
|
{
|
|
num = num - 7 - EnetPeer.HMAC_SIZE - EnetPeer.IV_SIZE;
|
|
num = num / EnetPeer.BLOCK_SIZE * EnetPeer.BLOCK_SIZE;
|
|
num = num - 5 - 36;
|
|
num2 = num;
|
|
}
|
|
else
|
|
{
|
|
num2 = num - 12 - 36;
|
|
}
|
|
return num2;
|
|
}
|
|
|
|
// Token: 0x06000157 RID: 343 RVA: 0x0000B4DC File Offset: 0x000096DC
|
|
private int CalculateBufferLen()
|
|
{
|
|
int num = base.mtu;
|
|
bool flag = this.datagramEncryptedConnection;
|
|
int num2;
|
|
if (flag)
|
|
{
|
|
num = num - 7 - EnetPeer.HMAC_SIZE - EnetPeer.IV_SIZE;
|
|
num = num / EnetPeer.BLOCK_SIZE * EnetPeer.BLOCK_SIZE;
|
|
num--;
|
|
num2 = num;
|
|
}
|
|
else
|
|
{
|
|
num2 = num;
|
|
}
|
|
return num2;
|
|
}
|
|
|
|
// Token: 0x06000158 RID: 344 RVA: 0x0000B528 File Offset: 0x00009728
|
|
private int CalculateInitialOffset()
|
|
{
|
|
bool flag = this.datagramEncryptedConnection;
|
|
int num;
|
|
if (flag)
|
|
{
|
|
num = 5;
|
|
}
|
|
else
|
|
{
|
|
int num2 = 12;
|
|
bool crcEnabled = base.crcEnabled;
|
|
if (crcEnabled)
|
|
{
|
|
num2 += 4;
|
|
}
|
|
num = num2;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x06000159 RID: 345 RVA: 0x0000B560 File Offset: 0x00009760
|
|
internal override bool SendAcksOnly()
|
|
{
|
|
bool flag = this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnected;
|
|
bool flag2;
|
|
if (flag)
|
|
{
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
bool flag3 = this.rt == null || !this.rt.Connected;
|
|
if (flag3)
|
|
{
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
byte[] array = this.udpBuffer;
|
|
lock (array)
|
|
{
|
|
int num = 0;
|
|
this.udpBufferIndex = this.CalculateInitialOffset();
|
|
this.udpBufferLength = this.CalculateBufferLen();
|
|
this.udpCommandCount = 0;
|
|
this.timeInt = SupportClass.GetTickCount() - this.timeBase;
|
|
StreamBuffer streamBuffer = this.outgoingAcknowledgementsPool;
|
|
lock (streamBuffer)
|
|
{
|
|
num = this.SerializeAckToBuffer();
|
|
this.timeLastSendAck = this.timeInt;
|
|
}
|
|
bool flag4 = this.timeInt > this.timeoutInt && this.sentReliableCommands.Count > 0;
|
|
if (flag4)
|
|
{
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
foreach (NCommand ncommand in this.sentReliableCommands)
|
|
{
|
|
bool flag5 = ncommand != null && ncommand.roundTripTimeout != 0 && this.timeInt - ncommand.commandSentTime > ncommand.roundTripTimeout;
|
|
if (flag5)
|
|
{
|
|
ncommand.commandSentCount = 1;
|
|
ncommand.roundTripTimeout = 0;
|
|
ncommand.timeoutTime = int.MaxValue;
|
|
ncommand.commandSentTime = this.timeInt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool flag6 = this.udpCommandCount <= 0;
|
|
if (flag6)
|
|
{
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
TrafficStats trafficStatsOutgoing = base.TrafficStatsOutgoing;
|
|
int totalPacketCount = trafficStatsOutgoing.TotalPacketCount;
|
|
trafficStatsOutgoing.TotalPacketCount = totalPacketCount + 1;
|
|
base.TrafficStatsOutgoing.TotalCommandsInPackets += (int)this.udpCommandCount;
|
|
}
|
|
this.SendData(this.udpBuffer, this.udpBufferIndex);
|
|
flag2 = num > 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return flag2;
|
|
}
|
|
|
|
// Token: 0x0600015A RID: 346 RVA: 0x0000B7D0 File Offset: 0x000099D0
|
|
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
|
|
{
|
|
byte[] array = this.udpBuffer;
|
|
lock (array)
|
|
{
|
|
int num = 0;
|
|
this.udpBufferIndex = this.CalculateInitialOffset();
|
|
this.udpBufferLength = this.CalculateBufferLen();
|
|
this.udpCommandCount = 0;
|
|
this.timeInt = SupportClass.GetTickCount() - this.timeBase;
|
|
this.timeLastSendOutgoing = this.timeInt;
|
|
StreamBuffer streamBuffer = this.outgoingAcknowledgementsPool;
|
|
lock (streamBuffer)
|
|
{
|
|
bool flag4 = this.outgoingAcknowledgementsPool.Length > 0L;
|
|
if (flag4)
|
|
{
|
|
num = this.SerializeAckToBuffer();
|
|
this.timeLastSendAck = this.timeInt;
|
|
}
|
|
}
|
|
bool flag5 = !base.IsSendingOnlyAcks && this.timeInt > this.timeoutInt && this.sentReliableCommands.Count > 0;
|
|
if (flag5)
|
|
{
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
this.commandsToResend.Clear();
|
|
foreach (NCommand ncommand in this.sentReliableCommands)
|
|
{
|
|
bool flag6 = ncommand != null && this.timeInt - ncommand.commandSentTime > ncommand.roundTripTimeout;
|
|
if (flag6)
|
|
{
|
|
bool flag7 = (int)ncommand.commandSentCount > base.sentCountAllowance || this.timeInt > ncommand.timeoutTime;
|
|
if (flag7)
|
|
{
|
|
bool flag8 = base.debugOut >= DebugLevel.WARNING;
|
|
if (flag8)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.WARNING, string.Concat(new object[]
|
|
{
|
|
"Timeout-disconnect! Command: ",
|
|
ncommand,
|
|
" now: ",
|
|
this.timeInt,
|
|
" challenge: ",
|
|
Convert.ToString(this.challenge, 16)
|
|
}));
|
|
}
|
|
bool flag9 = this.CommandLog != null;
|
|
if (flag9)
|
|
{
|
|
this.CommandLog.Enqueue(new CmdLogSentReliable(ncommand, this.timeInt, this.roundTripTime, this.roundTripTimeVariance, true));
|
|
base.CommandLogResize();
|
|
}
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Zombie;
|
|
base.Listener.OnStatusChanged(StatusCode.TimeoutDisconnect);
|
|
this.Disconnect();
|
|
return false;
|
|
}
|
|
this.commandsToResend.Enqueue(ncommand);
|
|
}
|
|
}
|
|
while (this.commandsToResend.Count > 0)
|
|
{
|
|
NCommand ncommand2 = this.commandsToResend.Dequeue();
|
|
this.QueueOutgoingReliableCommand(ncommand2);
|
|
this.sentReliableCommands.Remove(ncommand2);
|
|
this.reliableCommandsRepeated++;
|
|
bool flag10 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag10)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Format("Resending: {0}. times out after: {1} sent: {3} now: {2} rtt/var: {4}/{5} last recv: {6}", new object[]
|
|
{
|
|
ncommand2,
|
|
ncommand2.roundTripTimeout,
|
|
this.timeInt,
|
|
ncommand2.commandSentTime,
|
|
this.roundTripTime,
|
|
this.roundTripTimeVariance,
|
|
SupportClass.GetTickCount() - this.timestampOfLastReceive
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool flag11 = !base.IsSendingOnlyAcks && this.peerConnectionState == PeerBase.ConnectionStateValue.Connected && base.timePingInterval > 0 && this.sentReliableCommands.Count == 0 && this.timeInt - this.timeLastAckReceive > base.timePingInterval && !this.AreReliableCommandsInTransit() && this.udpBufferIndex + 12 < this.udpBufferLength;
|
|
if (flag11)
|
|
{
|
|
NCommand ncommand3 = new NCommand(this, 5, null, byte.MaxValue);
|
|
this.QueueOutgoingReliableCommand(ncommand3);
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
base.TrafficStatsOutgoing.CountControlCommand(ncommand3.Size);
|
|
}
|
|
}
|
|
bool flag12 = !base.IsSendingOnlyAcks;
|
|
if (flag12)
|
|
{
|
|
EnetChannel[] array2 = this.channelArray;
|
|
lock (array2)
|
|
{
|
|
for (int i = 0; i < this.channelArray.Length; i++)
|
|
{
|
|
EnetChannel enetChannel = this.channelArray[i];
|
|
num += this.SerializeToBuffer(enetChannel.outgoingReliableCommandsList);
|
|
num += this.SerializeToBuffer(enetChannel.outgoingUnreliableCommandsList);
|
|
}
|
|
}
|
|
}
|
|
bool flag13 = this.udpCommandCount <= 0;
|
|
if (flag13)
|
|
{
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
bool trafficStatsEnabled2 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled2)
|
|
{
|
|
TrafficStats trafficStatsOutgoing = base.TrafficStatsOutgoing;
|
|
int totalPacketCount = trafficStatsOutgoing.TotalPacketCount;
|
|
trafficStatsOutgoing.TotalPacketCount = totalPacketCount + 1;
|
|
base.TrafficStatsOutgoing.TotalCommandsInPackets += (int)this.udpCommandCount;
|
|
}
|
|
this.SendData(this.udpBuffer, this.udpBufferIndex);
|
|
flag2 = num > 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return flag2;
|
|
}
|
|
|
|
// Token: 0x0600015B RID: 347 RVA: 0x0000BD58 File Offset: 0x00009F58
|
|
private bool AreReliableCommandsInTransit()
|
|
{
|
|
EnetChannel[] array = this.channelArray;
|
|
lock (array)
|
|
{
|
|
for (int i = 0; i < this.channelArray.Length; i++)
|
|
{
|
|
EnetChannel enetChannel = this.channelArray[i];
|
|
bool flag = enetChannel.outgoingReliableCommandsList.Count > 0;
|
|
if (flag)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x0600015C RID: 348 RVA: 0x0000BDD4 File Offset: 0x00009FD4
|
|
internal override bool EnqueueOperation(Dictionary<byte, object> 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.CreateAndEnqueueCommand(sendReliable ? 6 : 7, array, channelId);
|
|
}
|
|
}
|
|
return flag3;
|
|
}
|
|
|
|
// Token: 0x0600015D RID: 349 RVA: 0x0000BF04 File Offset: 0x0000A104
|
|
private EnetChannel GetChannel(byte channelNumber)
|
|
{
|
|
return (channelNumber == byte.MaxValue) ? this.channelArray[this.channelArray.Length - 1] : this.channelArray[(int)channelNumber];
|
|
}
|
|
|
|
// Token: 0x0600015E RID: 350 RVA: 0x0000BF3C File Offset: 0x0000A13C
|
|
internal bool CreateAndEnqueueCommand(byte commandType, byte[] payload, byte channelNumber)
|
|
{
|
|
bool flag = payload == null;
|
|
bool flag2;
|
|
if (flag)
|
|
{
|
|
flag2 = false;
|
|
}
|
|
else
|
|
{
|
|
EnetChannel channel = this.GetChannel(channelNumber);
|
|
this.ByteCountLastOperation = 0;
|
|
int num = this.GetFragmentLength();
|
|
bool flag3 = payload.Length > num;
|
|
if (flag3)
|
|
{
|
|
int num2 = (payload.Length + num - 1) / num;
|
|
int num3 = channel.outgoingReliableSequenceNumber + 1;
|
|
int num4 = 0;
|
|
for (int i = 0; i < payload.Length; i += num)
|
|
{
|
|
bool flag4 = payload.Length - i < num;
|
|
if (flag4)
|
|
{
|
|
num = payload.Length - i;
|
|
}
|
|
byte[] array = new byte[num];
|
|
Buffer.BlockCopy(payload, i, array, 0, num);
|
|
NCommand ncommand = new NCommand(this, 8, array, channel.ChannelNumber);
|
|
ncommand.fragmentNumber = num4;
|
|
ncommand.startSequenceNumber = num3;
|
|
ncommand.fragmentCount = num2;
|
|
ncommand.totalLength = payload.Length;
|
|
ncommand.fragmentOffset = i;
|
|
this.QueueOutgoingReliableCommand(ncommand);
|
|
this.ByteCountLastOperation += ncommand.Size;
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
base.TrafficStatsOutgoing.CountFragmentOpCommand(ncommand.Size);
|
|
base.TrafficStatsGameLevel.CountOperation(ncommand.Size);
|
|
}
|
|
num4++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NCommand ncommand2 = new NCommand(this, commandType, payload, channel.ChannelNumber);
|
|
bool flag5 = ncommand2.commandFlags == 1;
|
|
if (flag5)
|
|
{
|
|
this.QueueOutgoingReliableCommand(ncommand2);
|
|
this.ByteCountLastOperation = ncommand2.Size;
|
|
bool trafficStatsEnabled2 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled2)
|
|
{
|
|
base.TrafficStatsOutgoing.CountReliableOpCommand(ncommand2.Size);
|
|
base.TrafficStatsGameLevel.CountOperation(ncommand2.Size);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.QueueOutgoingUnreliableCommand(ncommand2);
|
|
this.ByteCountLastOperation = ncommand2.Size;
|
|
bool trafficStatsEnabled3 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled3)
|
|
{
|
|
base.TrafficStatsOutgoing.CountUnreliableOpCommand(ncommand2.Size);
|
|
base.TrafficStatsGameLevel.CountOperation(ncommand2.Size);
|
|
}
|
|
}
|
|
}
|
|
flag2 = true;
|
|
}
|
|
return flag2;
|
|
}
|
|
|
|
// Token: 0x0600015F RID: 351 RVA: 0x0000C144 File Offset: 0x0000A344
|
|
internal override byte[] SerializeOperationToMessage(byte opCode, Dictionary<byte, object> parameters, PeerBase.EgMessageType messageType, bool encrypt)
|
|
{
|
|
encrypt = encrypt && !this.datagramEncryptedConnection;
|
|
StreamBuffer serializeMemStream = this.SerializeMemStream;
|
|
byte[] array2;
|
|
lock (serializeMemStream)
|
|
{
|
|
this.SerializeMemStream.SetLength(0L);
|
|
bool flag = !encrypt;
|
|
if (flag)
|
|
{
|
|
this.SerializeMemStream.Write(EnetPeer.messageHeader, 0, EnetPeer.messageHeader.Length);
|
|
}
|
|
this.protocol.SerializeOperationRequest(this.SerializeMemStream, opCode, parameters, false);
|
|
bool flag2 = encrypt;
|
|
if (flag2)
|
|
{
|
|
byte[] array = this.CryptoProvider.Encrypt(this.SerializeMemStream.GetBuffer(), 0, (int)this.SerializeMemStream.Length);
|
|
this.SerializeMemStream.SetLength(0L);
|
|
this.SerializeMemStream.Write(EnetPeer.messageHeader, 0, EnetPeer.messageHeader.Length);
|
|
this.SerializeMemStream.Write(array, 0, array.Length);
|
|
}
|
|
array2 = this.SerializeMemStream.ToArray();
|
|
}
|
|
bool flag3 = messageType != PeerBase.EgMessageType.Operation;
|
|
if (flag3)
|
|
{
|
|
array2[EnetPeer.messageHeader.Length - 1] = (byte)messageType;
|
|
}
|
|
bool flag4 = encrypt;
|
|
if (flag4)
|
|
{
|
|
array2[EnetPeer.messageHeader.Length - 1] = array2[EnetPeer.messageHeader.Length - 1] | 128;
|
|
}
|
|
return array2;
|
|
}
|
|
|
|
// Token: 0x06000160 RID: 352 RVA: 0x0000C294 File Offset: 0x0000A494
|
|
internal int SerializeAckToBuffer()
|
|
{
|
|
this.outgoingAcknowledgementsPool.Seek(0L, SeekOrigin.Begin);
|
|
while (this.outgoingAcknowledgementsPool.Position + 20L <= this.outgoingAcknowledgementsPool.Length)
|
|
{
|
|
bool flag = this.udpBufferIndex + 20 > this.udpBufferLength;
|
|
if (flag)
|
|
{
|
|
bool flag2 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag2)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[]
|
|
{
|
|
"UDP package is full. Commands in Package: ",
|
|
this.udpCommandCount,
|
|
". bytes left in queue: ",
|
|
this.outgoingAcknowledgementsPool.Position
|
|
}));
|
|
}
|
|
break;
|
|
}
|
|
int num;
|
|
byte[] bufferAndAdvance = this.outgoingAcknowledgementsPool.GetBufferAndAdvance(20, out num);
|
|
Buffer.BlockCopy(bufferAndAdvance, num, this.udpBuffer, this.udpBufferIndex, 20);
|
|
this.udpBufferIndex += 20;
|
|
this.udpCommandCount += 1;
|
|
}
|
|
this.outgoingAcknowledgementsPool.Compact();
|
|
this.outgoingAcknowledgementsPool.Position = this.outgoingAcknowledgementsPool.Length;
|
|
return (int)this.outgoingAcknowledgementsPool.Length / 20;
|
|
}
|
|
|
|
// Token: 0x06000161 RID: 353 RVA: 0x0000C3D0 File Offset: 0x0000A5D0
|
|
internal int SerializeToBuffer(Queue<NCommand> commandList)
|
|
{
|
|
while (commandList.Count > 0)
|
|
{
|
|
NCommand ncommand = commandList.Peek();
|
|
bool flag = ncommand == null;
|
|
if (flag)
|
|
{
|
|
commandList.Dequeue();
|
|
}
|
|
else
|
|
{
|
|
bool flag2 = this.udpBufferIndex + ncommand.Size > this.udpBufferLength;
|
|
if (flag2)
|
|
{
|
|
bool flag3 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag3)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[] { "UDP package is full. Commands in Package: ", this.udpCommandCount, ". Commands left in queue: ", commandList.Count }));
|
|
}
|
|
break;
|
|
}
|
|
ncommand.SerializeHeader(this.udpBuffer, ref this.udpBufferIndex);
|
|
bool flag4 = ncommand.SizeOfPayload > 0;
|
|
if (flag4)
|
|
{
|
|
Buffer.BlockCopy(ncommand.Serialize(), 0, this.udpBuffer, this.udpBufferIndex, ncommand.SizeOfPayload);
|
|
this.udpBufferIndex += ncommand.SizeOfPayload;
|
|
}
|
|
this.udpCommandCount += 1;
|
|
bool flag5 = (ncommand.commandFlags & 1) > 0;
|
|
if (flag5)
|
|
{
|
|
this.QueueSentCommand(ncommand);
|
|
bool flag6 = this.CommandLog != null;
|
|
if (flag6)
|
|
{
|
|
this.CommandLog.Enqueue(new CmdLogSentReliable(ncommand, this.timeInt, this.roundTripTime, this.roundTripTimeVariance, false));
|
|
base.CommandLogResize();
|
|
}
|
|
}
|
|
commandList.Dequeue();
|
|
}
|
|
}
|
|
return commandList.Count;
|
|
}
|
|
|
|
// Token: 0x06000162 RID: 354 RVA: 0x0000C558 File Offset: 0x0000A758
|
|
internal void SendData(byte[] data, int length)
|
|
{
|
|
try
|
|
{
|
|
bool flag = this.datagramEncryptedConnection;
|
|
if (flag)
|
|
{
|
|
this.SendDataEncrypted(data, length);
|
|
}
|
|
else
|
|
{
|
|
int num = 0;
|
|
Protocol.Serialize(this.peerID, data, ref num);
|
|
data[2] = (base.crcEnabled ? 204 : 0);
|
|
data[3] = this.udpCommandCount;
|
|
num = 4;
|
|
Protocol.Serialize(this.timeInt, data, ref num);
|
|
Protocol.Serialize(this.challenge, data, ref num);
|
|
bool crcEnabled = base.crcEnabled;
|
|
if (crcEnabled)
|
|
{
|
|
Protocol.Serialize(0, data, ref num);
|
|
uint num2 = SupportClass.CalculateCrc(data, length);
|
|
num -= 4;
|
|
Protocol.Serialize((int)num2, data, ref num);
|
|
}
|
|
this.bytesOut += (long)length;
|
|
this.SendToSocket(data, length);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bool flag2 = base.debugOut >= DebugLevel.ERROR;
|
|
if (flag2)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ERROR, ex.ToString());
|
|
}
|
|
SupportClass.WriteStackTrace(ex);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000163 RID: 355 RVA: 0x0000C65C File Offset: 0x0000A85C
|
|
private void SendToSocket(byte[] data, int length)
|
|
{
|
|
bool isSimulationEnabled = base.NetworkSimulationSettings.IsSimulationEnabled;
|
|
if (isSimulationEnabled)
|
|
{
|
|
byte[] array = new byte[length];
|
|
Buffer.BlockCopy(data, 0, array, 0, length);
|
|
base.SendNetworkSimulated(array);
|
|
}
|
|
else
|
|
{
|
|
this.rt.Send(data, length);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000164 RID: 356 RVA: 0x0000C6A8 File Offset: 0x0000A8A8
|
|
private void SendDataEncrypted(byte[] data, int length)
|
|
{
|
|
bool flag = this.bufferForEncryption == null || this.bufferForEncryption.Length != base.mtu;
|
|
if (flag)
|
|
{
|
|
this.bufferForEncryption = new byte[base.mtu];
|
|
}
|
|
byte[] array = this.bufferForEncryption;
|
|
int num = 0;
|
|
Protocol.Serialize(this.peerID, array, ref num);
|
|
array[2] = 1;
|
|
num++;
|
|
Protocol.Serialize(this.challenge, array, ref num);
|
|
data[0] = this.udpCommandCount;
|
|
int num2 = 1;
|
|
Protocol.Serialize(this.timeInt, data, ref num2);
|
|
this.encryptor.Encrypt(data, length, array, ref num);
|
|
Buffer.BlockCopy(this.encryptor.FinishHMAC(array, 0, num), 0, array, num, EnetPeer.HMAC_SIZE);
|
|
this.SendToSocket(array, num + EnetPeer.HMAC_SIZE);
|
|
}
|
|
|
|
// Token: 0x06000165 RID: 357 RVA: 0x0000C770 File Offset: 0x0000A970
|
|
internal void QueueSentCommand(NCommand command)
|
|
{
|
|
command.commandSentTime = this.timeInt;
|
|
command.commandSentCount += 1;
|
|
bool flag = command.roundTripTimeout == 0;
|
|
if (flag)
|
|
{
|
|
command.roundTripTimeout = this.roundTripTime + 4 * this.roundTripTimeVariance;
|
|
command.timeoutTime = this.timeInt + base.DisconnectTimeout;
|
|
}
|
|
else
|
|
{
|
|
bool flag2 = command.commandSentCount <= base.QuickResendAttempts + 1;
|
|
if (!flag2)
|
|
{
|
|
command.roundTripTimeout *= 2;
|
|
}
|
|
}
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
bool flag3 = this.sentReliableCommands.Count == 0;
|
|
if (flag3)
|
|
{
|
|
int num = command.commandSentTime + command.roundTripTimeout;
|
|
bool flag4 = num < this.timeoutInt;
|
|
if (flag4)
|
|
{
|
|
this.timeoutInt = num;
|
|
}
|
|
}
|
|
this.reliableCommandsSent++;
|
|
this.sentReliableCommands.Add(command);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000166 RID: 358 RVA: 0x0000C884 File Offset: 0x0000AA84
|
|
internal void QueueOutgoingReliableCommand(NCommand command)
|
|
{
|
|
EnetChannel channel = this.GetChannel(command.commandChannelID);
|
|
EnetChannel enetChannel = channel;
|
|
lock (enetChannel)
|
|
{
|
|
bool flag = command.reliableSequenceNumber == 0;
|
|
if (flag)
|
|
{
|
|
EnetChannel enetChannel2 = channel;
|
|
int num = enetChannel2.outgoingReliableSequenceNumber + 1;
|
|
enetChannel2.outgoingReliableSequenceNumber = num;
|
|
command.reliableSequenceNumber = num;
|
|
}
|
|
channel.outgoingReliableCommandsList.Enqueue(command);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000167 RID: 359 RVA: 0x0000C8F8 File Offset: 0x0000AAF8
|
|
internal void QueueOutgoingUnreliableCommand(NCommand command)
|
|
{
|
|
EnetChannel channel = this.GetChannel(command.commandChannelID);
|
|
EnetChannel enetChannel = channel;
|
|
lock (enetChannel)
|
|
{
|
|
command.reliableSequenceNumber = channel.outgoingReliableSequenceNumber;
|
|
EnetChannel enetChannel2 = channel;
|
|
int num = enetChannel2.outgoingUnreliableSequenceNumber + 1;
|
|
enetChannel2.outgoingUnreliableSequenceNumber = num;
|
|
command.unreliableSequenceNumber = num;
|
|
channel.outgoingUnreliableCommandsList.Enqueue(command);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000168 RID: 360 RVA: 0x0000C968 File Offset: 0x0000AB68
|
|
internal void QueueOutgoingAcknowledgement(NCommand readCommand, int sendTime)
|
|
{
|
|
StreamBuffer streamBuffer = this.outgoingAcknowledgementsPool;
|
|
lock (streamBuffer)
|
|
{
|
|
int num;
|
|
byte[] bufferAndAdvance = this.outgoingAcknowledgementsPool.GetBufferAndAdvance(20, out num);
|
|
NCommand.CreateAck(bufferAndAdvance, num, readCommand, sendTime);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000169 RID: 361 RVA: 0x0000C9BC File Offset: 0x0000ABBC
|
|
internal override void ReceiveIncomingCommands(byte[] inBuff, int dataLength)
|
|
{
|
|
this.timestampOfLastReceive = SupportClass.GetTickCount();
|
|
try
|
|
{
|
|
int num = 0;
|
|
short num2;
|
|
Protocol.Deserialize(out num2, inBuff, ref num);
|
|
byte b = inBuff[num++];
|
|
bool flag = b == 1;
|
|
int num3;
|
|
byte b2;
|
|
if (flag)
|
|
{
|
|
bool flag2 = this.decryptor == null;
|
|
if (flag2)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.ERROR, "Got encrypted packet, but encryption is not set up. Packet ignored");
|
|
return;
|
|
}
|
|
this.datagramEncryptedConnection = true;
|
|
bool flag3 = !this.decryptor.CheckHMAC(inBuff, dataLength);
|
|
if (flag3)
|
|
{
|
|
this.packetLossByCrc++;
|
|
bool flag4 = this.peerConnectionState != PeerBase.ConnectionStateValue.Disconnected && base.debugOut >= DebugLevel.INFO;
|
|
if (flag4)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.INFO, "Ignored package due to wrong HMAC.");
|
|
}
|
|
return;
|
|
}
|
|
Protocol.Deserialize(out num3, inBuff, ref num);
|
|
inBuff = this.decryptor.DecryptBufferWithIV(inBuff, num, dataLength - num - EnetPeer.HMAC_SIZE, out dataLength);
|
|
dataLength = inBuff.Length;
|
|
num = 0;
|
|
b2 = inBuff[num++];
|
|
Protocol.Deserialize(out this.serverSentTime, inBuff, ref num);
|
|
this.bytesIn += (long)(12 + EnetPeer.IV_SIZE + EnetPeer.HMAC_SIZE + dataLength + (EnetPeer.BLOCK_SIZE - dataLength % EnetPeer.BLOCK_SIZE));
|
|
}
|
|
else
|
|
{
|
|
bool flag5 = this.datagramEncryptedConnection;
|
|
if (flag5)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.WARNING, "Got not encrypted packet, but expected only encrypted. Packet ignored");
|
|
return;
|
|
}
|
|
b2 = inBuff[num++];
|
|
Protocol.Deserialize(out this.serverSentTime, inBuff, ref num);
|
|
Protocol.Deserialize(out num3, inBuff, ref num);
|
|
bool flag6 = b == 204;
|
|
if (flag6)
|
|
{
|
|
int num4;
|
|
Protocol.Deserialize(out num4, inBuff, ref num);
|
|
this.bytesIn += 4L;
|
|
num -= 4;
|
|
Protocol.Serialize(0, inBuff, ref num);
|
|
uint num5 = SupportClass.CalculateCrc(inBuff, dataLength);
|
|
bool flag7 = num4 != (int)num5;
|
|
if (flag7)
|
|
{
|
|
this.packetLossByCrc++;
|
|
bool flag8 = this.peerConnectionState != PeerBase.ConnectionStateValue.Disconnected && base.debugOut >= DebugLevel.INFO;
|
|
if (flag8)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.INFO, string.Format("Ignored package due to wrong CRC. Incoming: {0:X} Local: {1:X}", (uint)num4, num5));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
this.bytesIn += 12L;
|
|
}
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
TrafficStats trafficStatsIncoming = base.TrafficStatsIncoming;
|
|
int totalPacketCount = trafficStatsIncoming.TotalPacketCount;
|
|
trafficStatsIncoming.TotalPacketCount = totalPacketCount + 1;
|
|
base.TrafficStatsIncoming.TotalCommandsInPackets += (int)b2;
|
|
}
|
|
bool flag9 = (int)b2 > this.commandBufferSize || b2 <= 0;
|
|
if (flag9)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.ERROR, string.Concat(new object[] { "too many/few incoming commands in package: ", b2, " > ", this.commandBufferSize }));
|
|
}
|
|
bool flag10 = num3 != this.challenge;
|
|
if (flag10)
|
|
{
|
|
this.packetLossByChallenge++;
|
|
bool flag11 = this.peerConnectionState != PeerBase.ConnectionStateValue.Disconnected && base.debugOut >= DebugLevel.ALL;
|
|
if (flag11)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.ALL, string.Concat(new object[] { "Info: Ignoring received package due to wrong challenge. Challenge in-package!=local:", num3, "!=", this.challenge, " Commands in it: ", b2 }));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.timeInt = SupportClass.GetTickCount() - this.timeBase;
|
|
for (int i = 0; i < (int)b2; i++)
|
|
{
|
|
NCommand readCommand = new NCommand(this, inBuff, ref num);
|
|
bool flag12 = readCommand.commandType != 1;
|
|
if (flag12)
|
|
{
|
|
base.EnqueueActionForDispatch(delegate
|
|
{
|
|
this.ExecuteCommand(readCommand);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this.ExecuteCommand(readCommand);
|
|
}
|
|
bool flag13 = (readCommand.commandFlags & 1) > 0;
|
|
if (flag13)
|
|
{
|
|
bool flag14 = this.InReliableLog != null;
|
|
if (flag14)
|
|
{
|
|
this.InReliableLog.Enqueue(new CmdLogReceivedReliable(readCommand, this.timeInt, this.roundTripTime, this.roundTripTimeVariance, this.timeInt - this.timeLastSendOutgoing, this.timeInt - this.timeLastSendAck));
|
|
base.CommandLogResize();
|
|
}
|
|
this.QueueOutgoingAcknowledgement(readCommand, this.serverSentTime);
|
|
bool trafficStatsEnabled2 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled2)
|
|
{
|
|
base.TrafficStatsIncoming.TimestampOfLastReliableCommand = SupportClass.GetTickCount();
|
|
base.TrafficStatsOutgoing.CountControlCommand(20);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
bool flag15 = base.debugOut >= DebugLevel.ERROR;
|
|
if (flag15)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.ERROR, string.Format("Exception while reading commands from incoming data: {0}", ex));
|
|
}
|
|
SupportClass.WriteStackTrace(ex);
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600016A RID: 362 RVA: 0x0000CEA8 File Offset: 0x0000B0A8
|
|
internal bool ExecuteCommand(NCommand command)
|
|
{
|
|
bool flag = true;
|
|
switch (command.commandType)
|
|
{
|
|
case 1:
|
|
{
|
|
bool trafficStatsEnabled = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled)
|
|
{
|
|
base.TrafficStatsIncoming.TimestampOfLastAck = SupportClass.GetTickCount();
|
|
base.TrafficStatsIncoming.CountControlCommand(command.Size);
|
|
}
|
|
this.timeLastAckReceive = this.timeInt;
|
|
this.lastRoundTripTime = this.timeInt - command.ackReceivedSentTime;
|
|
NCommand ncommand = this.RemoveSentReliableCommand(command.ackReceivedReliableSequenceNumber, (int)command.commandChannelID);
|
|
bool flag2 = this.CommandLog != null;
|
|
if (flag2)
|
|
{
|
|
this.CommandLog.Enqueue(new CmdLogReceivedAck(command, this.timeInt, this.roundTripTime, this.roundTripTimeVariance));
|
|
base.CommandLogResize();
|
|
}
|
|
bool flag3 = ncommand != null;
|
|
if (flag3)
|
|
{
|
|
bool flag4 = ncommand.commandType == 12;
|
|
if (flag4)
|
|
{
|
|
bool flag5 = this.lastRoundTripTime <= this.roundTripTime;
|
|
if (flag5)
|
|
{
|
|
this.serverTimeOffset = this.serverSentTime + (this.lastRoundTripTime >> 1) - SupportClass.GetTickCount();
|
|
this.serverTimeOffsetIsAvailable = true;
|
|
}
|
|
else
|
|
{
|
|
this.FetchServerTimestamp();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
base.UpdateRoundTripTimeAndVariance(this.lastRoundTripTime);
|
|
bool flag6 = ncommand.commandType == 4 && this.peerConnectionState == PeerBase.ConnectionStateValue.Disconnecting;
|
|
if (flag6)
|
|
{
|
|
bool flag7 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag7)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.INFO, "Received disconnect ACK by server");
|
|
}
|
|
base.EnqueueActionForDispatch(delegate
|
|
{
|
|
this.rt.Disconnect();
|
|
});
|
|
}
|
|
else
|
|
{
|
|
bool flag8 = ncommand.commandType == 2;
|
|
if (flag8)
|
|
{
|
|
this.roundTripTime = this.lastRoundTripTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 2:
|
|
case 5:
|
|
{
|
|
bool trafficStatsEnabled2 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled2)
|
|
{
|
|
base.TrafficStatsIncoming.CountControlCommand(command.Size);
|
|
}
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
bool trafficStatsEnabled3 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled3)
|
|
{
|
|
base.TrafficStatsIncoming.CountControlCommand(command.Size);
|
|
}
|
|
bool flag9 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connecting;
|
|
if (flag9)
|
|
{
|
|
byte[] array = base.PrepareConnectData(base.ServerAddress, this.AppId, this.CustomInitData);
|
|
this.CreateAndEnqueueCommand(6, array, 0);
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Connected;
|
|
}
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
bool trafficStatsEnabled4 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled4)
|
|
{
|
|
base.TrafficStatsIncoming.CountControlCommand(command.Size);
|
|
}
|
|
StatusCode statusCode = StatusCode.DisconnectByServer;
|
|
bool flag10 = command.reservedByte == 1;
|
|
if (flag10)
|
|
{
|
|
statusCode = StatusCode.DisconnectByServerLogic;
|
|
}
|
|
else
|
|
{
|
|
bool flag11 = command.reservedByte == 3;
|
|
if (flag11)
|
|
{
|
|
statusCode = StatusCode.DisconnectByServerUserLimit;
|
|
}
|
|
}
|
|
bool flag12 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag12)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[]
|
|
{
|
|
"Server ",
|
|
base.ServerAddress,
|
|
" sent disconnect. PeerId: ",
|
|
(ushort)this.peerID,
|
|
" RTT/Variance:",
|
|
this.roundTripTime,
|
|
"/",
|
|
this.roundTripTimeVariance,
|
|
" reason byte: ",
|
|
command.reservedByte
|
|
}));
|
|
}
|
|
PeerBase.ConnectionStateValue peerConnectionState = this.peerConnectionState;
|
|
this.peerConnectionState = PeerBase.ConnectionStateValue.Disconnecting;
|
|
base.Listener.OnStatusChanged(statusCode);
|
|
this.peerConnectionState = peerConnectionState;
|
|
this.Disconnect();
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
bool trafficStatsEnabled5 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled5)
|
|
{
|
|
base.TrafficStatsIncoming.CountReliableOpCommand(command.Size);
|
|
}
|
|
bool flag13 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connected;
|
|
if (flag13)
|
|
{
|
|
flag = this.QueueIncomingCommand(command);
|
|
}
|
|
break;
|
|
}
|
|
case 7:
|
|
{
|
|
bool trafficStatsEnabled6 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled6)
|
|
{
|
|
base.TrafficStatsIncoming.CountUnreliableOpCommand(command.Size);
|
|
}
|
|
bool flag14 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connected;
|
|
if (flag14)
|
|
{
|
|
flag = this.QueueIncomingCommand(command);
|
|
}
|
|
break;
|
|
}
|
|
case 8:
|
|
{
|
|
bool trafficStatsEnabled7 = base.TrafficStatsEnabled;
|
|
if (trafficStatsEnabled7)
|
|
{
|
|
base.TrafficStatsIncoming.CountFragmentOpCommand(command.Size);
|
|
}
|
|
bool flag15 = this.peerConnectionState == PeerBase.ConnectionStateValue.Connected;
|
|
if (flag15)
|
|
{
|
|
bool flag16 = command.fragmentNumber > command.fragmentCount || command.fragmentOffset >= command.totalLength || command.fragmentOffset + command.Payload.Length > command.totalLength;
|
|
if (flag16)
|
|
{
|
|
bool flag17 = base.debugOut >= DebugLevel.ERROR;
|
|
if (flag17)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ERROR, "Received fragment has bad size: " + command);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
flag = this.QueueIncomingCommand(command);
|
|
bool flag18 = flag;
|
|
if (flag18)
|
|
{
|
|
EnetChannel channel = this.GetChannel(command.commandChannelID);
|
|
bool flag19 = command.reliableSequenceNumber == command.startSequenceNumber;
|
|
if (flag19)
|
|
{
|
|
command.fragmentsRemaining--;
|
|
int num = command.startSequenceNumber + 1;
|
|
while (command.fragmentsRemaining > 0 && num < command.startSequenceNumber + command.fragmentCount)
|
|
{
|
|
bool flag20 = channel.ContainsReliableSequenceNumber(num++);
|
|
if (flag20)
|
|
{
|
|
command.fragmentsRemaining--;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool flag21 = channel.ContainsReliableSequenceNumber(command.startSequenceNumber);
|
|
if (flag21)
|
|
{
|
|
NCommand ncommand2 = channel.FetchReliableSequenceNumber(command.startSequenceNumber);
|
|
ncommand2.fragmentsRemaining--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
// Token: 0x0600016B RID: 363 RVA: 0x0000D41C File Offset: 0x0000B61C
|
|
internal bool QueueIncomingCommand(NCommand command)
|
|
{
|
|
EnetChannel channel = this.GetChannel(command.commandChannelID);
|
|
bool flag = channel == null;
|
|
bool flag3;
|
|
if (flag)
|
|
{
|
|
bool flag2 = base.debugOut >= DebugLevel.ERROR;
|
|
if (flag2)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ERROR, "Received command for non-existing channel: " + command.commandChannelID);
|
|
}
|
|
flag3 = false;
|
|
}
|
|
else
|
|
{
|
|
bool flag4 = base.debugOut >= DebugLevel.ALL;
|
|
if (flag4)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.ALL, string.Concat(new object[] { "queueIncomingCommand() ", command, " channel seq# r/u: ", channel.incomingReliableSequenceNumber, "/", channel.incomingUnreliableSequenceNumber }));
|
|
}
|
|
bool flag5 = command.commandFlags == 1;
|
|
if (flag5)
|
|
{
|
|
bool flag6 = command.reliableSequenceNumber <= channel.incomingReliableSequenceNumber;
|
|
if (flag6)
|
|
{
|
|
bool flag7 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag7)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[] { "incoming command ", command, " is old (not saving it). Dispatched incomingReliableSequenceNumber: ", channel.incomingReliableSequenceNumber }));
|
|
}
|
|
flag3 = false;
|
|
}
|
|
else
|
|
{
|
|
bool flag8 = channel.ContainsReliableSequenceNumber(command.reliableSequenceNumber);
|
|
if (flag8)
|
|
{
|
|
bool flag9 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag9)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[]
|
|
{
|
|
"Info: command was received before! Old/New: ",
|
|
channel.FetchReliableSequenceNumber(command.reliableSequenceNumber),
|
|
"/",
|
|
command,
|
|
" inReliableSeq#: ",
|
|
channel.incomingReliableSequenceNumber
|
|
}));
|
|
}
|
|
flag3 = false;
|
|
}
|
|
else
|
|
{
|
|
channel.incomingReliableCommandsList.Add(command.reliableSequenceNumber, command);
|
|
flag3 = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool flag10 = command.commandFlags == 0;
|
|
if (flag10)
|
|
{
|
|
bool flag11 = command.reliableSequenceNumber < channel.incomingReliableSequenceNumber;
|
|
if (flag11)
|
|
{
|
|
bool flag12 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag12)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, "incoming reliable-seq# < Dispatched-rel-seq#. not saved.");
|
|
}
|
|
flag3 = true;
|
|
}
|
|
else
|
|
{
|
|
bool flag13 = command.unreliableSequenceNumber <= channel.incomingUnreliableSequenceNumber;
|
|
if (flag13)
|
|
{
|
|
bool flag14 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag14)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, "incoming unreliable-seq# < Dispatched-unrel-seq#. not saved.");
|
|
}
|
|
flag3 = true;
|
|
}
|
|
else
|
|
{
|
|
bool flag15 = channel.ContainsUnreliableSequenceNumber(command.unreliableSequenceNumber);
|
|
if (flag15)
|
|
{
|
|
bool flag16 = base.debugOut >= DebugLevel.INFO;
|
|
if (flag16)
|
|
{
|
|
base.Listener.DebugReturn(DebugLevel.INFO, string.Concat(new object[]
|
|
{
|
|
"command was received before! Old/New: ",
|
|
channel.incomingUnreliableCommandsList[command.unreliableSequenceNumber],
|
|
"/",
|
|
command
|
|
}));
|
|
}
|
|
flag3 = false;
|
|
}
|
|
else
|
|
{
|
|
channel.incomingUnreliableCommandsList.Add(command.unreliableSequenceNumber, command);
|
|
flag3 = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
flag3 = false;
|
|
}
|
|
}
|
|
}
|
|
return flag3;
|
|
}
|
|
|
|
// Token: 0x0600016C RID: 364 RVA: 0x0000D71C File Offset: 0x0000B91C
|
|
internal NCommand RemoveSentReliableCommand(int ackReceivedReliableSequenceNumber, int ackReceivedChannel)
|
|
{
|
|
NCommand ncommand = null;
|
|
List<NCommand> list = this.sentReliableCommands;
|
|
lock (list)
|
|
{
|
|
foreach (NCommand ncommand2 in this.sentReliableCommands)
|
|
{
|
|
bool flag = ncommand2 != null && ncommand2.reliableSequenceNumber == ackReceivedReliableSequenceNumber && (int)ncommand2.commandChannelID == ackReceivedChannel;
|
|
if (flag)
|
|
{
|
|
ncommand = ncommand2;
|
|
break;
|
|
}
|
|
}
|
|
bool flag2 = ncommand != null;
|
|
if (flag2)
|
|
{
|
|
this.sentReliableCommands.Remove(ncommand);
|
|
bool flag3 = this.sentReliableCommands.Count > 0;
|
|
if (flag3)
|
|
{
|
|
this.timeoutInt = this.timeInt + 25;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool flag4 = base.debugOut >= DebugLevel.ALL && this.peerConnectionState != PeerBase.ConnectionStateValue.Connected && this.peerConnectionState != PeerBase.ConnectionStateValue.Disconnecting;
|
|
if (flag4)
|
|
{
|
|
base.EnqueueDebugReturn(DebugLevel.ALL, string.Format("No sent command for ACK (Ch: {0} Sq#: {1}). PeerState: {2}.", ackReceivedReliableSequenceNumber, ackReceivedChannel, this.peerConnectionState));
|
|
}
|
|
}
|
|
}
|
|
return ncommand;
|
|
}
|
|
|
|
// Token: 0x0600016D RID: 365 RVA: 0x0000D854 File Offset: 0x0000BA54
|
|
internal string CommandListToString(NCommand[] list)
|
|
{
|
|
bool flag = base.debugOut < DebugLevel.ALL;
|
|
string text;
|
|
if (flag)
|
|
{
|
|
text = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
for (int i = 0; i < list.Length; i++)
|
|
{
|
|
stringBuilder.Append(i + "=");
|
|
stringBuilder.Append(list[i]);
|
|
stringBuilder.Append(" # ");
|
|
}
|
|
text = stringBuilder.ToString();
|
|
}
|
|
return text;
|
|
}
|
|
|
|
// Token: 0x040000A9 RID: 169
|
|
private const int CRC_LENGTH = 4;
|
|
|
|
// Token: 0x040000AA RID: 170
|
|
private static readonly int HMAC_SIZE = 32;
|
|
|
|
// Token: 0x040000AB RID: 171
|
|
private static readonly int BLOCK_SIZE = 16;
|
|
|
|
// Token: 0x040000AC RID: 172
|
|
private static readonly int IV_SIZE = 16;
|
|
|
|
// Token: 0x040000AD RID: 173
|
|
private const int EncryptedDataGramHeaderSize = 7;
|
|
|
|
// Token: 0x040000AE RID: 174
|
|
private const int EncryptedHeaderSize = 5;
|
|
|
|
// Token: 0x040000AF RID: 175
|
|
private List<NCommand> sentReliableCommands = new List<NCommand>();
|
|
|
|
// Token: 0x040000B0 RID: 176
|
|
private StreamBuffer outgoingAcknowledgementsPool;
|
|
|
|
// Token: 0x040000B1 RID: 177
|
|
internal readonly int windowSize = 128;
|
|
|
|
// Token: 0x040000B2 RID: 178
|
|
private byte udpCommandCount;
|
|
|
|
// Token: 0x040000B3 RID: 179
|
|
private byte[] udpBuffer;
|
|
|
|
// Token: 0x040000B4 RID: 180
|
|
private int udpBufferIndex;
|
|
|
|
// Token: 0x040000B5 RID: 181
|
|
private int udpBufferLength;
|
|
|
|
// Token: 0x040000B6 RID: 182
|
|
private byte[] bufferForEncryption;
|
|
|
|
// Token: 0x040000B7 RID: 183
|
|
internal int challenge;
|
|
|
|
// Token: 0x040000B8 RID: 184
|
|
internal int reliableCommandsRepeated;
|
|
|
|
// Token: 0x040000B9 RID: 185
|
|
internal int reliableCommandsSent;
|
|
|
|
// Token: 0x040000BA RID: 186
|
|
internal int serverSentTime;
|
|
|
|
// Token: 0x040000BB RID: 187
|
|
internal static readonly byte[] udpHeader0xF3 = new byte[] { 243, 2 };
|
|
|
|
// Token: 0x040000BC RID: 188
|
|
internal static readonly byte[] messageHeader = EnetPeer.udpHeader0xF3;
|
|
|
|
// Token: 0x040000BD RID: 189
|
|
protected bool datagramEncryptedConnection;
|
|
|
|
// Token: 0x040000BE RID: 190
|
|
private EnetChannel[] channelArray = new EnetChannel[0];
|
|
|
|
// Token: 0x040000BF RID: 191
|
|
private const byte ControlChannelNumber = 255;
|
|
|
|
// Token: 0x040000C0 RID: 192
|
|
protected internal const short PeerIdForConnect = -1;
|
|
|
|
// Token: 0x040000C1 RID: 193
|
|
protected internal const short PeerIdForConnectTrace = -2;
|
|
|
|
// Token: 0x040000C2 RID: 194
|
|
private Queue<int> commandsToRemove = new Queue<int>();
|
|
|
|
// Token: 0x040000C3 RID: 195
|
|
private Queue<NCommand> commandsToResend = new Queue<NCommand>();
|
|
}
|
|
}
|