protected override void StateAwake() { ClientListUpdate = new ClientListUpdateEvent(); m_awaitedInitMessage = null; ClientSyncState.m_lobbyState = this; m_serverSentSignal = false; LoadPercentage = 0; m_clientCharacters = new Dictionary <int, CharacterData>(); }
public void AcceptConnection(Socket handler) { string clientID = null; byte[] bytes = new byte[1024]; Message clientIDMessage = new Message(); Message clientListMessage = new Message(); Message clientDisconnectedListMessage = new Message(); MessageParser parser = new MessageParser(); //thread-specific anonymous function to handle a change in clientList //storing it in a variable so we can unsubscribe from it later ClientListUpdate ClientListUpdateEventHandler = () => { clientListMessage.ReceiverClientID = currentClient.ToString(); clientListMessage.MessageType = MessageType.ClientList; clientListMessage.MessageBody = string.Join(",", connectedClients.Keys.ToArray()); SendPacket(clientListMessage, handler); };; while (true && handler.Connected) { try { int bytesReceived = handler.Receive(bytes); Queue <byte[]> incoming = parser.ReceiverParser(bytes, bytesReceived); foreach (byte[] data in incoming) { if (data != null) { Message im = Serializer <Message> .Deserialize(data); if (im.MessageType == MessageType.ClientJoin) { clientID = im.SenderClientID; lock (_messsageQueuesLocker) { connectedClients.Add(clientID, handler); if (disconnectedClients.Contains(clientID.ToString())) { disconnectedClients.Remove(clientID.ToString()); } } //subscribing the client to the server for update in clientList ClientListUpdateEvent += ClientListUpdateEventHandler; Log.Information("[Client] Client {0} connected. IP: {1};", clientID, handler.RemoteEndPoint.ToString()); clientIDMessage.ReceiverClientID = clientID; clientIDMessage.MessageType = MessageType.ClientID; clientIDMessage.MessageBody = clientID; SendPacket(clientIDMessage, handler); //sending a list of previously connected (currently disconnected) clients clientDisconnectedListMessage.ReceiverClientID = clientID; clientDisconnectedListMessage.MessageType = MessageType.ClientDisconnectedList; clientDisconnectedListMessage.MessageBody = string.Join(",", disconnectedClients.ToArray()); SendPacket(clientDisconnectedListMessage, handler); //raising ClientListUpdateEvent since clientList has changed ClientListUpdateEvent?.Invoke(); Message joinUpdateMessage = new Message { SenderClientID = null, ReceiverClientID = null, MessageType = MessageType.ClientJoinUpdate, MessageBody = clientID.ToString(), Broadcast = false }; //lets all the clients know that another client has joined the server foreach (Socket s in connectedClients.Values) { if (!s.Equals(handler)) { SendPacket(joinUpdateMessage, s); } } currentClient++; } else if (im.MessageType == MessageType.ClientQuit) { Log.Information("[ClientDisconnected] Client {0} has disconnected (gracefully).", clientID); OnClientDisconnect(clientID, handler, ClientListUpdateEventHandler); break; } else if (im.MessageType == MessageType.ClientMessage) { if (im.Broadcast == true) { Log.Information("[Broadcast] Client: {0} -> All clients, Message: {1}", im.SenderClientID, im.MessageBody); foreach (Socket s in connectedClients.Values) { if (!s.Equals(handler)) { SendPacket(im, s); } } } else if (connectedClients.ContainsKey(im.ReceiverClientID)) { Log.Information("[ClientMessage] Client: {0} -> Client: {1}, Message: {2}", im.SenderClientID, im.ReceiverClientID, im.MessageBody); Socket receiver = connectedClients[im.ReceiverClientID]; SendPacket(im, receiver); } else if (disconnectedClients.Contains(im.ReceiverClientID)) { Log.Information("[ClientMessageFailure] Client: {0} -> Client: {1}, Message: {2}", im.SenderClientID, im.ReceiverClientID, im.MessageBody); lock (_messsageQueuesLocker) { //adding message to queue for clients if (!messageQueues.ContainsKey(im.ReceiverClientID)) { messageQueues.Add(im.ReceiverClientID, new Queue <TimestampedMessage>()); } messageQueues[im.ReceiverClientID].Enqueue(new TimestampedMessage { receivedAt = DateTime.Now, message = new Message(im) }); } Log.Information("Message queue for client: {0}, length: {1}", im.ReceiverClientID, messageQueues[im.ReceiverClientID].Count); im.MessageType = MessageType.ClientMessageFailure; im.MessageBody = messageFailureErrorCodes[2]; SendPacket(im, handler); } else { Log.Information("[ClientMessageIncorrectID] Client: {0} -> Client: {1}, Message: {2}", im.SenderClientID, im.ReceiverClientID, im.MessageBody); im.MessageType = MessageType.ClientMessageFailure; im.MessageBody = messageFailureErrorCodes[1]; SendPacket(im, handler); } } } } } catch (SerializationException se) { Log.Error("SerializationException (Client probably went down or disconnected): {0}", se.ToString()); } catch (SocketException) { Log.Information("[ClientDisconnected] Client {0} has disconnected (forcibly closed).", clientID); OnClientDisconnect(clientID, handler, ClientListUpdateEventHandler); break; } } }