private NetworkMessage ConvertOrderedUnreliableMessage(NetworkMessage input, Connection <T> connection) { if (input.sendType != NetworkMessageType.ORDERED_UNRELIABLE) { return(input); } int newSize = 12; if (input.data != null) { newSize += input.data.Length; } NetworkMessage converted = NetworkMessage.Create(-3, newSize, NetworkMessageType.UNORDERED_UNRELIABLE); DarkUtils.WriteInt32ToByteArray(connection.sendOrderID++, converted.data.data, 0); if (connection.sendOrderID == Int32.MaxValue) { connection.sendOrderID = 0; } DarkUtils.WriteInt32ToByteArray(input.type, converted.data.data, 4); DarkUtils.WriteInt32ToByteArray(newSize - 8, converted.data.data, 8); if (input.data != null) { Array.Copy(input.data.data, 0, converted.data.data, 12, input.data.Length); } input.Destroy(); return(input); }
public Connection <T> GetConnection(IPEndPoint endPoint) { Guid storeKey = DarkUtils.GuidFromIPEndpoint(endPoint); if (connections.ContainsKey(storeKey)) { return(connections[storeKey]); } return(null); }
internal void HandleRaw(byte[] data, int length, IPEndPoint endPoint) { if (length < 12) { return; } //Magic header, DARK if (data[0] != 68 || data[1] != 65 || data[2] != 82 || data[3] != 75) { return; } Connection <T> connection = null; Guid messageOwner = DarkUtils.GuidFromIPEndpoint(endPoint); if (!connections.ContainsKey(messageOwner)) { if (connection == null) { connection = new Connection <T>(); connection.handler = this; connection.reliableMessageHandler = new ReliableMessageHandler <T>(connection, this); if (network.clientMode && serverConnection == null) { serverConnection = connection; } } connection.lastReceiveTime = DateTime.UtcNow.Ticks; connection.remoteEndpoint = endPoint; lock (connections) { connections.Add(messageOwner, connection); } if (connectCallback != null) { connection.state = connectCallback(connection); } } connection = connections[messageOwner]; int messageType = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4)); int messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 8)); if (length < messageLength + 12) { //Malformed message return; } NetworkMessage nm = NetworkMessage.Create(messageType, messageLength, NetworkMessageType.UNORDERED_UNRELIABLE); if (nm.data != null && nm.data.Length > 0) { Array.Copy(data, 12, nm.data.data, 0, nm.data.Length); } Handle(nm, connection); }
private void SendInitialHeartbeat(IPEndPoint endPoint) { DarkUtils.WriteMagicHeader(initialHeartBeat, 0); DarkUtils.WriteInt32ToByteArray(-1, initialHeartBeat, 4); DarkUtils.WriteInt32ToByteArray(8, initialHeartBeat, 8); DarkUtils.WriteInt64ToByteArray(DateTime.UtcNow.Ticks, initialHeartBeat, 12); //Send 4 times. for (int i = 0; i < 4; i++) { socket.SendTo(initialHeartBeat, endPoint); } }
private int WriteRawMessageToBuffer(NetworkMessage nm) { DarkUtils.WriteMagicHeader(sendBuffer, 0); DarkUtils.WriteInt32ToByteArray(nm.type, sendBuffer, 4); if (nm.data == null || nm.data.Length == 0) { DarkUtils.WriteInt32ToByteArray(0, sendBuffer, 8); return(12); } DarkUtils.WriteInt32ToByteArray(nm.data.Length, sendBuffer, 8); Array.Copy(nm.data.data, 0, sendBuffer, 12, nm.data.Length); return(12 + nm.data.Length); }
internal void SendHeartbeat() { lock (connections) { long currentTime = DateTime.UtcNow.Ticks; foreach (KeyValuePair <Guid, Connection <T> > c in connections) { if (currentTime > c.Value.lastReceiveTime + TimeSpan.TicksPerSecond * 20) { disconnectList.Add(c.Key); } if (currentTime > (c.Value.lastHeartbeatTime + TimeSpan.TicksPerSecond)) { c.Value.lastHeartbeatTime = currentTime; NetworkMessage nm = NetworkMessage.Create(-1, 8, NetworkMessageType.UNORDERED_UNRELIABLE); DarkUtils.WriteInt64ToByteArray(DateTime.UtcNow.Ticks, nm.data.data, 0); SendMessageWithHighPriority(nm, c.Value); } RateControl <T> .Update(c.Value); c.Value.reliableMessageHandler.Send(); } foreach (Guid disconnectConnectionGuid in disconnectList) { Connection <T> disconnectConnection = connections[disconnectConnectionGuid]; if (disconnectCallback != null) { disconnectCallback(disconnectConnection); } disconnectConnection.reliableMessageHandler.ReleaseAllObjects(); network.ReleaseAllObjects(disconnectConnection); connections.Remove(disconnectConnectionGuid); } disconnectList.Clear(); } }
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); }