Esempio n. 1
0
 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>();
 }
Esempio n. 2
0
        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;
                }
            }
        }