public NetworkMessage GetMessage(int id, Connection <T> connection) { if (finished) { return(null); } int checkedThisRound = 0; //Always assume at least 10ms lag long latency = connection.latency; if (latency < 10 * TimeSpan.TicksPerMillisecond) { latency = 10 * TimeSpan.TicksPerMillisecond; } //Resend message if it has been 2 RTT's long checkTime = DateTime.UtcNow.Ticks - (latency * 2); bool found = false; while (!found) { if (sendParts[nextSendPart] >= 0 && checkTime > sendParts[nextSendPart]) { found = true; } else { nextSendPart++; if (nextSendPart == sendPartsLength) { nextSendPart = 0; } checkedThisRound++; if (checkedThisRound == sendPartsLength) { //We checked to see if we could send any chunks and didn't find any. break; } } } if (found) { int totalSize = 4; if (networkMessage.data != null) { totalSize += networkMessage.data.Length; } int thisSendSize = 500; if (nextSendPart == (sendPartsLength - 1)) { thisSendSize = totalSize % 500; } //This is a retransmit, count the lost data if (sendParts[nextSendPart] != 0) { connection.dataLoss += thisSendSize; } connection.dataSent += thisSendSize; NetworkMessage sendMessage = NetworkMessage.Create(-4, 12 + thisSendSize, NetworkMessageType.UNORDERED_UNRELIABLE); DarkUtils.WriteInt32ToByteArray(id, sendMessage.data.data, 0); DarkUtils.WriteInt32ToByteArray(nextSendPart, sendMessage.data.data, 4); //Don't include the header in the message length, we know it's there DarkUtils.WriteInt32ToByteArray(totalSize - 4, sendMessage.data.data, 8); if (nextSendPart == 0) { DarkUtils.WriteInt32ToByteArray(networkMessage.type, sendMessage.data.data, 12); if (networkMessage.data != null && networkMessage.data.Length > 0) { Array.Copy(networkMessage.data.data, 0, sendMessage.data.data, 16, thisSendSize - 4); } } else { Array.Copy(networkMessage.data.data, (nextSendPart * 500) - 4, sendMessage.data.data, 12, thisSendSize); } sendParts[nextSendPart] = -2; nextSendPart++; if (nextSendPart == sendPartsLength) { nextSendPart = 0; } return(sendMessage); } return(null); }