예제 #1
0
        public void SendChangedWorldState(GameObjectState[] worldState)
        {
            List <byte> data = new List <byte>();

            foreach (var state in worldState)
            {
                data.AddRange(GameObjectState.Serialize(state));
            }
            byte[] bytes = data.ToArray();

            //Console.WriteLine($"Send {bytes.Length} bytes");
            if (bytes.Length == 0)
            {
                return;
            }

            lock (clientsLocker) {
                foreach (var c in clients)
                {
                    lock (c.locker)
                        if (c.isRunning)
                        {
                            c.Send(PacketType.WorldState, bytes);
                        }
                }
            }
        }
예제 #2
0
        void ProcessClient(object _client)
        {
            if (!(_client is TcpClient))
            {
                return;
            }

            ClientInfo clientInfo = new ClientInfo {
                isRunning = true,
                thread    = Thread.CurrentThread,
                client    = _client as TcpClient
            };

            clientInfo.stream = clientInfo.client.GetStream();

            lock (clientsLocker) {
                clients.Add(clientInfo);
            }

            byte[] data = new byte[ClientConnect.OneObjectSize];

            {
                ClientConnect         clientConnect;
                ClientConnectResponce responce;

                lock (clientInfo.locker) {
                    while (!clientInfo.stream.DataAvailable)
                    {
                        Thread.Sleep(1);
                    }

                    PacketType type = Protocol.BaseRecieve(clientInfo.stream, out data);
                    if (type == PacketType.ClientConnect)
                    {
                        clientConnect = ClientConnect.Deserialize(data);

                        responce            = ClientConnected(clientConnect);
                        clientInfo.playerId = responce.playerId;
                        clientInfo.Send(PacketType.ClientConnectResponce, ClientConnectResponce.Serialize(responce));

                        List <byte> listWorldState = new List <byte>();
                        foreach (var state in responce.initialWorldState)
                        {
                            listWorldState.AddRange(GameObjectState.Serialize(state));
                        }
                        //Console.WriteLine($"Send {listWorldState.Count} bytes to player {responce.playerId}");
                        clientInfo.Send(PacketType.WorldState, listWorldState.ToArray());
                    }
                    else
                    {
                        throw new Exception("Recieve smth wrong in Server.ProcessClient()");
                    }
                }
            }

            data = new byte[BasePlayerAction.OneObjectSize];
            BasePlayerAction action;

            while (clientInfo.isRunning)
            {
                lock (clientInfo.locker) {
                    if (!clientInfo.stream.DataAvailable)
                    {
                        System.Threading.Thread.Sleep(1);
                        continue;
                    }

                    PacketType type = Protocol.BaseRecieve(clientInfo.stream, out data);
                    if (type == PacketType.PlayerAction)
                    {
                        action          = BasePlayerAction.Deserialize(data);
                        action.playerId = clientInfo.playerId;
                        playerActions.Enqueue(action);
                    }
                    else if (type == PacketType.ClientDisconnect)
                    {
                        clientInfo.isRunning = false;

                        //Console.WriteLine("Client going to disconnect");
                        ClientDisconnect disconnectInfo = ClientDisconnect.Deserialize(data);
                        //Console.WriteLine("Deserialize disconnect data");
                        clientInfo.Send(PacketType.ClientDisconnectResponce, ClientDisconnectResponce.Serialize(
                                            new ClientDisconnectResponce()
                        {
                        }
                                            ));
                        //Console.WriteLine("Send ClientDisconnectResponce");
                    }
                }
            }

            lock (clientsLocker) {
                //Console.WriteLine("Close client streams");
                lock (clientInfo.locker) {
                    clientInfo.stream.Close();
                    clientInfo.client.Close();
                }

                //Console.WriteLine("Try to remove from clients");
                clients.Remove(clientInfo);
            }

            //Console.WriteLine("Close client");
        }