public ClientModule(System.Net.IPAddress host, int port, ClientGame parentGame) { netSession = new Network.ClientSession(0, new System.Net.IPEndPoint(host, port), parentGame.Main.ScriptConsole.Write); netSession.onDatagramReceived += (data) => { var gram = new Network.ReadOnlyDatagram(data); while (gram.More) { uint messageCode = 0; gram.ReadUInt(out messageCode, 8); switch (messageCode) { case 0: if (simulation != null) throw new InvalidProgramException(); { String episodeName; uint version; gram.ReadString(out episodeName); gram.ReadUInt(out version, 32); parentGame.StartSimulation(episodeName, version); } break; case 1: { UInt32 entityID; UInt32 syncID; UInt32 dataLength; gram.ReadUInt(out entityID, 32); gram.ReadUInt(out syncID, 8); gram.ReadUInt(out dataLength, 32); var bytes = new byte[dataLength]; gram.ReadBytes(bytes, dataLength); if (syncables.ContainsKey(entityID)) foreach (var syncable in syncables[entityID]) //if (syncable.SyncID == syncID) syncable.ReadFullSync(new ReadOnlyDatagram(bytes)); } break; case 2: { UInt32 length; gram.ReadUInt(out length, 32); byte[] message = new byte[length]; gram.ReadBytes(message, length); string messageID = null; MISP.ScriptList messageData = null; ScriptMessage.DecodeMessage(message, out messageID, out messageData); simulation.EnqueueEvent(messageID, messageData); } break; } } }; parentGame.Main.Write("Connected to server " + host + " on port " + port + "\n"); }
private static MISP.ScriptList DecodeList(ReadOnlyDatagram datagram) { var r = new MISP.ScriptList(); uint count = 0; datagram.ReadUInt(out count, 8); byte[] temp = new byte[4]; for (int i = 0; i < count; ++i) { uint typeCode = 0; datagram.ReadUInt(out typeCode, 8); switch ((ScriptTypes)typeCode) { case ScriptTypes.List: r.Add(DecodeList(datagram)); break; case ScriptTypes.String: { String s; datagram.ReadString(out s); r.Add(s); } break; case ScriptTypes.Int32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToInt32(temp, 0)); break; case ScriptTypes.UInt32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToUInt32(temp, 0)); break; case ScriptTypes.Single: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToSingle(temp, 0)); break; case ScriptTypes.Bool: { uint b = 0; datagram.ReadUInt(out b, 8); if (b == 0) r.Add(null); else r.Add(true); } break; default: throw new MISP.ScriptError("Error decoding message", null); } } return r; }
private static Common.ObjectList DecodeList(ReadOnlyDatagram datagram) { var r = new Common.ObjectList(); uint count = 0; datagram.ReadUInt(out count, 8); byte[] temp = new byte[4]; for (int i = 0; i < count; ++i) { uint typeCode = 0; datagram.ReadUInt(out typeCode, 8); switch ((ScriptTypes)typeCode) { case ScriptTypes.List: r.Add(DecodeList(datagram)); break; case ScriptTypes.String: { String s; datagram.ReadString(out s); r.Add(s); } break; case ScriptTypes.Int32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToInt32(temp, 0)); break; case ScriptTypes.UInt32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToUInt32(temp, 0)); break; case ScriptTypes.Single: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToSingle(temp, 0)); break; case ScriptTypes.Bool: { uint b = 0; datagram.ReadUInt(out b, 8); if (b == 0) { r.Add(null); } else { r.Add(true); } } break; default: throw new InvalidProgramException("Error decoding message", null); } } return(r); }
public void update() { try { while (socket.Available > 0) { IPEndPoint observedEndpoint = new IPEndPoint(IPAddress.Any, 0); byte[] bytes = null; try { bytes = socket.Receive(ref observedEndpoint); } catch (System.Net.Sockets.SocketException except) { _debug(0, "[SS] Receive threw an exception. Socket Error : " + except.SocketErrorCode); continue; } _debug(1, "[SS] Incoming message of length " + bytes.Length.ToString() + " : " + BitConverter.ToString(bytes)); _debug(1, "[SS] It appears to have come from " + observedEndpoint.ToString()); var datagram = new ReadOnlyDatagram(bytes); uint messageType = 0; uint ackID = 0; if (!datagram.ReadUInt(out messageType, 8)) { goto OnBadMessage; } if (!datagram.ReadUInt(out ackID, 32)) { goto OnBadMessage; } var sendingClient = clients.FirstOrDefault((client) => { return(client.observedAddress.Equals(observedEndpoint)); }); switch ((ClientToServerMessage)messageType) { case ClientToServerMessage.Join: { if (sendingClient != null) //Client has already joined - assume the ack was dropped. { _sendAckMessage(sendingClient, ackID); break; } try { var newClient = new Client(); newClient.observedAddress = observedEndpoint; newClient.Guid = Guid.NewGuid(); newClient.lastCommunication = DateTime.Now; _debug(0, "[SS] A client with observed address " + observedEndpoint.ToString() + " has joined the session."); foreach (var existingClient in clients) { _sendPeerJoinedMessage(existingClient, newClient); _sendPeerJoinedMessage(newClient, existingClient); } clients.Add(newClient); if (onClientJoined != null) { onClientJoined(newClient); } _sendAckMessage(newClient, ackID); } catch (Exception e) { _debug(0, "[SS] Accepting new client threw exception: " + e.Message); } } break; case ClientToServerMessage.Acknowledge: { var criticalDatagram = criticalDatagrams.FirstOrDefault((crit) => { return(crit.ackID == ackID); }); if (criticalDatagram != null) { if (!criticalDatagram.to.observedAddress.Equals(observedEndpoint)) { _debug(1, "[SS] The observed endpoint of the ack reply does not match the known observed endpoint of the peer the datagram was sent to."); break; } if (criticalDatagram.onSuccess != null) { try { criticalDatagram.onSuccess(); } catch (Exception) { } } criticalDatagrams.Remove(criticalDatagram); } } break; case ClientToServerMessage.Datagram: { if (sendingClient == null) { //_debug("[SS] I received a datagram from an unknown client with address " + observedEndpoint.ToString() +"."); break; } if (ackID != 0) { _sendAckMessage(sendingClient, ackID); if (sendingClient.newDatagramReceived(ackID) == RemotePeer.DatagramResponse.Ignore) { break; } } _debug(2, "[SS] I received a datagram from client " + sendingClient.Guid.ToString() + ". It was " + (bytes.Length - 5).ToString() + " bytes long."); if (bytes.Length - 5 <= 0) { goto OnBadMessage; } byte[] data = new byte[bytes.Length - 5]; if (!datagram.ReadBytes(data, (uint)(bytes.Length - 5))) { goto OnBadMessage; } if (onDatagramReceived != null) { onDatagramReceived(sendingClient, data); } } break; } continue; OnBadMessage: { _debug(1, "[SS] I received a bad message."); } } var now = DateTime.Now; for (int i = 0; i < criticalDatagrams.Count;) { var criticalDatagram = criticalDatagrams[i]; var timeDelta = now - criticalDatagram.lastSendAttempt; if (timeDelta.TotalMilliseconds > millisecondsBeforeRetry) { if (criticalDatagram.sendAttempts >= retryAttempts) { _debug(0, "[SS] I was not able to deliver critical packet " + criticalDatagram.ackID + "."); criticalDatagrams.RemoveAt(i); _onLostClient(criticalDatagram.to); continue; } criticalDatagram.sendAttempts += 1; _debug(2, "[SS] I am trying to send critical packet " + criticalDatagram.ackID + ". [" + criticalDatagram.sendAttempts + " attempts]"); criticalDatagram.lastSendAttempt = now; _send(criticalDatagram.data, criticalDatagram.to); } ++i; } foreach (var client in clients) { var timeDelta = now - client.lastCommunication; if (timeDelta.TotalMilliseconds > keepaliveRate) { _sendKeepalive(client); } } } catch (Exception e) { _debug(0, e.Message + "\n" + e.StackTrace); } }
public void update() { try { while (socket.Available > 0) { IPEndPoint observedEndpoint = new IPEndPoint(IPAddress.Any, 0); byte[] bytes = null; try { bytes = socket.Receive(ref observedEndpoint); } catch (System.Net.Sockets.SocketException except) { _debug("[CS] Receive threw an exception. Socket Error : " + except.SocketErrorCode); onLostConnection(); continue; } //_debug("[CS] Incoming message of length " + bytes.Length.ToString() + " : " + BitConverter.ToString(bytes)); //_debug("[CS] It appears to have come from " + observedEndpoint.ToString()); if (!observedEndpoint.Equals(serverAddress)) { _debug("[CS] I don't know who this message is from."); continue; } var datagram = new ReadOnlyDatagram(bytes); uint messageType = 0; uint ackID = 0; if (!datagram.ReadUInt(out messageType, 8)) { goto OnBadMessage; } if (!datagram.ReadUInt(out ackID, 32)) { goto OnBadMessage; } if (ackID != 0) { _sendAckMessage(ackID); } if (messageType != (uint)ServerToClientMessage.Acknowledge && ackID != 0 && duplicateDatagramDetector.newDatagramReceived(ackID) == RemotePeer.DatagramResponse.Ignore) { continue; } switch ((ServerToClientMessage)messageType) { case ServerToClientMessage.Acknowledge: _removeCriticalDatagram(ackID); //if (ackID == 1) _debug("Received ACK for join"); break; case ServerToClientMessage.Keepalive: { //Ack response already handled } break; case ServerToClientMessage.PeerJoined: { var guidBytes = new byte[16]; if (!datagram.ReadBytes(guidBytes, 16)) { goto OnBadMessage; } var peerGuid = new Guid(guidBytes); var newPeer = new Peer { Guid = peerGuid }; if (onPeerJoined != null) { onPeerJoined(newPeer); } peers.Add(newPeer); } break; case ServerToClientMessage.PeerLeft: { var guidBytes = new byte[16]; if (!datagram.ReadBytes(guidBytes, 16)) { goto OnBadMessage; } var peerGuid = new Guid(guidBytes); var peer = findPeer(peerGuid); if (onPeerLeft != null) { onPeerLeft(peer); } peers.Remove(peer); } break; case ServerToClientMessage.Datagram: { //_debug("[CS] I received a datagram from the server. It was " + (bytes.Length - 5).ToString() + " bytes long."); if (bytes.Length - 5 <= 0) { goto OnBadMessage; } byte[] data = new byte[bytes.Length - 5]; if (!datagram.ReadBytes(data, (uint)(bytes.Length - 5))) { goto OnBadMessage; } if (onDatagramReceived != null) { try { onDatagramReceived(data); } catch (Exception) { } } break; } } continue; OnBadMessage: { _debug("[CS] I received a bad message."); } } var now = DateTime.Now; for (int i = 0; i < criticalDatagrams.Count;) { var criticalDatagram = criticalDatagrams[i]; var timeDelta = now - criticalDatagram.lastSendAttempt; if (timeDelta.TotalMilliseconds > millisecondsBeforeRetry) { if (criticalDatagram.sendAttempts >= retryAttempts) { _debug("[CS] I was not able to deliver critical packet " + criticalDatagram.ackID + "."); criticalDatagrams.RemoveAt(i); _onLostConnection(); continue; } criticalDatagram.sendAttempts += 1; //_debug("[CS] I am trying to send critical packet " + criticalDatagram.ackID + ". [" // + criticalDatagram.sendAttempts + " attempts]"); criticalDatagram.lastSendAttempt = now; _send(criticalDatagram.data); } ++i; } } catch (Exception e) { _debug("[CS] " + e.Message + "\n" + e.StackTrace); } }
void IModule.BeginSimulation(Simulation sim) { this.sim = sim; sim.sendMessageHandler += (bytes) => { pendingMessages.Add(bytes); }; try { netSession = new Network.ServerSession(port, sim.debug); netSession.onClientJoined += (client) => { var welcomeDatagram = new Network.WriteOnlyDatagram(); welcomeDatagram.WriteUInt(0, 8); welcomeDatagram.WriteString(sim.Content.Module.Name); welcomeDatagram.WriteUInt((uint)sim.Content.Module.Version, 32); netSession.sendCriticalDatagram(client, welcomeDatagram.BufferAsArray, () => { sim.EnqueueEvent("on-new-client", new MISP.ScriptList(client)); }); }; netSession.onDatagramReceived += (client, bytes) => { var gram = new Network.ReadOnlyDatagram(bytes); while (gram.More) { uint messageCode = 0; gram.ReadUInt(out messageCode, 8); switch (messageCode) { case 0: //Should never receive this message. break; case 1: //Should never receive this message. break; case 2: { UInt32 length; gram.ReadUInt(out length, 32); byte[] message = new byte[length]; gram.ReadBytes(message, length); string messageID = null; MISP.ScriptList messageData = null; ScriptMessage.DecodeMessage(message, out messageID, out messageData); sim.EnqueueEvent(messageID, messageData); } break; } } }; } catch (Exception e) { System.Console.WriteLine("While trying to create a server module, " + e.Message); throw e; } }
public void update() { try { while (socket.Available > 0) { IPEndPoint observedEndpoint = new IPEndPoint(IPAddress.Any, 0); byte[] bytes = null; try { bytes = socket.Receive(ref observedEndpoint); } catch (System.Net.Sockets.SocketException except) { _debug("[SS] Receive threw an exception. Socket Error : " + except.SocketErrorCode); continue; } _debug("[SS] Incoming message of length " + bytes.Length.ToString() + " : " + BitConverter.ToString(bytes)); _debug("[SS] It appears to have come from " + observedEndpoint.ToString()); var datagram = new ReadOnlyDatagram(bytes); uint messageType = 0; uint ackID = 0; if (!datagram.ReadUInt(out messageType, 8)) goto OnBadMessage; if (!datagram.ReadUInt(out ackID, 32)) goto OnBadMessage; var sendingClient = clients.FirstOrDefault((client) => { return client.observedAddress.Equals(observedEndpoint); }); switch ((ClientToServerMessage)messageType) { case ClientToServerMessage.Join: { if (sendingClient != null) { _sendAckMessage(sendingClient, ackID); break; } var newClient = new Client(); newClient.observedAddress = observedEndpoint; newClient.Guid = Guid.NewGuid(); newClient.lastCommunication = DateTime.Now; _sendAckMessage(newClient, ackID); _debug("[SS] A client with observed address " + observedEndpoint.ToString() + " has joined the session."); foreach (var existingClient in clients) { _sendPeerJoinedMessage(existingClient, newClient); _sendPeerJoinedMessage(newClient, existingClient); } clients.Add(newClient); if (onClientJoined != null) onClientJoined(newClient); } break; case ClientToServerMessage.Acknowledge: { var criticalDatagram = criticalDatagrams.FirstOrDefault((crit) => { return crit.ackID == ackID; }); if (criticalDatagram != null) { if (!criticalDatagram.to.observedAddress.Equals(observedEndpoint)) { _debug("[SS] The observed endpoint of the ack reply does not match the known observed endpoint of the peer the datagram was sent to."); break; } if (criticalDatagram.onSuccess != null) { try { criticalDatagram.onSuccess(); } catch (Exception) { } } criticalDatagrams.Remove(criticalDatagram); } } break; case ClientToServerMessage.Datagram: { if (sendingClient == null) { _debug("[SS] I received a datagram from an unknown client with address " + observedEndpoint.ToString() +"."); break; } if (ackID != 0) { _sendAckMessage(sendingClient, ackID); if (sendingClient.newDatagramReceived(ackID) == RemotePeer.DatagramResponse.Ignore) break; } _debug("[SS] I received a datagram from client " + sendingClient.Guid.ToString() + ". It was " + (bytes.Length - 5).ToString() + " bytes long."); if (bytes.Length - 5 <= 0) goto OnBadMessage; byte[] data = new byte[bytes.Length - 5]; if (!datagram.ReadBytes(data, (uint)(bytes.Length - 5))) goto OnBadMessage; if (onDatagramReceived != null) onDatagramReceived(sendingClient, data); } break; } continue; OnBadMessage: { _debug("[SS] I received a bad message."); } } var now = DateTime.Now; for (int i = 0; i < criticalDatagrams.Count; ) { var criticalDatagram = criticalDatagrams[i]; var timeDelta = now - criticalDatagram.lastSendAttempt; if (timeDelta.TotalMilliseconds > millisecondsBeforeRetry) { if (criticalDatagram.sendAttempts >= retryAttempts) { _debug("[SS] I was not able to deliver critical packet " + criticalDatagram.ackID + "."); criticalDatagrams.RemoveAt(i); _onLostClient(criticalDatagram.to); continue; } criticalDatagram.sendAttempts += 1; _debug("[SS] I am trying to send critical packet " + criticalDatagram.ackID + ". [" + criticalDatagram.sendAttempts + " attempts]"); criticalDatagram.lastSendAttempt = now; _send(criticalDatagram.data, criticalDatagram.to); } ++i; } foreach (var client in clients) { var timeDelta = now - client.lastCommunication; if (timeDelta.TotalMilliseconds > keepaliveRate) _sendKeepalive(client); } } catch (Exception e) { _debug(e.Message + "\n" + e.StackTrace); } }
public void update() { try { while (socket.Available > 0) { IPEndPoint observedEndpoint = new IPEndPoint(IPAddress.Any, 0); byte[] bytes = null; try { bytes = socket.Receive(ref observedEndpoint); } catch (System.Net.Sockets.SocketException except) { _debug("[CS] Receive threw an exception. Socket Error : " + except.SocketErrorCode); onLostConnection(); continue; } _debug("[CS] Incoming message of length " + bytes.Length.ToString() + " : " + BitConverter.ToString(bytes)); _debug("[CS] It appears to have come from " + observedEndpoint.ToString()); if (!observedEndpoint.Equals(serverAddress)) { _debug("[CS] I don't know who this message is from."); continue; } var datagram = new ReadOnlyDatagram(bytes); uint messageType = 0; uint ackID = 0; if (!datagram.ReadUInt(out messageType, 8)) goto OnBadMessage; if (!datagram.ReadUInt(out ackID, 32)) goto OnBadMessage; if (ackID != 0) _sendAckMessage(ackID); if (messageType != (uint)ServerToClientMessage.Acknowledge && ackID != 0 && duplicateDatagramDetector.newDatagramReceived(ackID) == RemotePeer.DatagramResponse.Ignore) continue; switch ((ServerToClientMessage)messageType) { case ServerToClientMessage.Acknowledge: _removeCriticalDatagram(ackID); break; case ServerToClientMessage.Keepalive: { //Ack response already handled } break; case ServerToClientMessage.PeerJoined: { var guidBytes = new byte[16]; if (!datagram.ReadBytes(guidBytes, 16)) goto OnBadMessage; var peerGuid = new Guid(guidBytes); var newPeer = new Peer { Guid = peerGuid }; if (onPeerJoined != null) onPeerJoined(newPeer); peers.Add(newPeer); } break; case ServerToClientMessage.PeerLeft: { var guidBytes = new byte[16]; if (!datagram.ReadBytes(guidBytes, 16)) goto OnBadMessage; var peerGuid = new Guid(guidBytes); var peer = findPeer(peerGuid); if (onPeerLeft != null) onPeerLeft(peer); peers.Remove(peer); } break; case ServerToClientMessage.Datagram: { _debug("[CS] I received a datagram from the server. It was " + (bytes.Length - 5).ToString() + " bytes long."); if (bytes.Length - 5 <= 0) goto OnBadMessage; byte[] data = new byte[bytes.Length - 5]; if (!datagram.ReadBytes(data, (uint)(bytes.Length - 5))) goto OnBadMessage; if (onDatagramReceived != null) { try { onDatagramReceived(data); } catch (Exception) { } } break; } } continue; OnBadMessage: { _debug("[CS] I received a bad message."); } } var now = DateTime.Now; for (int i = 0; i < criticalDatagrams.Count; ) { var criticalDatagram = criticalDatagrams[i]; var timeDelta = now - criticalDatagram.lastSendAttempt; if (timeDelta.TotalMilliseconds > millisecondsBeforeRetry) { if (criticalDatagram.sendAttempts >= retryAttempts) { _debug("[CS] I was not able to deliver critical packet " + criticalDatagram.ackID + "."); criticalDatagrams.RemoveAt(i); _onLostConnection(); continue; } criticalDatagram.sendAttempts += 1; _debug("[CS] I am trying to send critical packet " + criticalDatagram.ackID + ". [" + criticalDatagram.sendAttempts + " attempts]"); criticalDatagram.lastSendAttempt = now; _send(criticalDatagram.data); } ++i; } } catch (Exception e) { _debug("[CS] " + e.Message + "\n" + e.StackTrace); } }