Пример #1
0
        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                Socket clientSocket = (Socket)ar.AsyncState;
                clientSocket.EndReceive(ar);

                //Transform the array of bytes received from the user into an
                //intelligent form of object Data
                Data msgReceived = new Data(byteData);

                //We will send this object in response the users request
                Data msgToSend = new Data();

                lock (globalLocker)
                {
                    int clientId = findClient(clientList, clientSocket);
                    byte[] message;

                    if (clientId == -1) writeToLog2("Получено " + msgReceived.cmdCommand.ToString() + " от " + clientSocket.LocalEndPoint.ToString(), true);
                    else if (clientList[clientId].roomId == -1) writeToLog2("Получено " + msgReceived.cmdCommand.ToString() + " от "
                         + clientList[clientId].login, true);

                    else writeToLog2("Получено " + msgReceived.cmdCommand.ToString() + "\t от " + clientList[clientId].login + " в \""
                        + rooms[clientList[clientId].roomId].roomName + "\"", true);

                    switch (msgReceived.cmdCommand)
                    {
                        case Command.Connect:
                            /////////проверка разрешения пользователя на доступ к игре
                            //если разрешено

                            ClientInfo clientInfo = new ClientInfo();
                            clientInfo.socket = clientSocket;
                            clientInfo.ip = clientInfo.socket.RemoteEndPoint.ToString();
                            clientInfo.login = msgReceived.login;
                            clientInfo.roomId = -1;

                            if (msgReceived.cardID != VERSION)
                            {
                                writeToLog("Попытка подключиться (старый клиент): " + clientInfo.login);
                                msgToSend.cmdCommand = Command.OldVersion;
                                message = msgToSend.ToByte();
                                //writeToLog2("Отправлено к " + clientInfo.login + " " + msgToSend.cmdCommand.ToString(), true);
                                clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendOne),
                                    new PacketInfo(clientInfo.socket, Command.OldVersion, -1));
                                return;
                            }

                            if (isLoginOK(clientList, msgReceived.login))
                            {
                                writeToLog("Подключился новый игрок: " + clientInfo.login);
                                clientList.Add(clientInfo);

                                msgToSend.cmdCommand = Command.Success;
                                message = msgToSend.ToByte();
                                //writeToLog2("Отправлено к " + clientInfo.login + " " + msgToSend.cmdCommand.ToString(), true);
                                clientInfo.acceptEvent.Reset();
                                clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendOne),
                                    new PacketInfo(clientInfo.socket, Command.Success, -1));
                                clientInfo.acceptEvent.WaitOne();
                                if (playersChanged != null)
                                    playersChanged(false, null);
                            }
                            else
                            {
                                writeToLog("Попытка подключиться: " + clientInfo.login);
                                msgToSend.cmdCommand = Command.Failed;
                                message = msgToSend.ToByte();
                                //writeToLog2("Отправлено к " + clientInfo.login + " " + msgToSend.cmdCommand.ToString(), true);
                                clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendOne),
                                    new PacketInfo(clientInfo.socket, Command.Failed, -1));
                            }
                            break;

                        case Command.connectToGame:
                            //найти и добавить в игру клиента
                            if (clientId != -1)
                            {
                                clientList[clientId].roomId = findRoom(msgReceived.gameToConnectRoomName);
                                rooms[clientList[clientId].roomId].gamersSend += clientList[clientId].login + " ";
                                rooms[clientList[clientId].roomId].gamers += "; " + clientList[clientId].login;
                                rooms[clientList[clientId].roomId].clientsInRoom.Add(clientList[clientId]);

                                msgToSend.UsersInRoom = rooms[clientList[clientId].roomId].gamersSend;
                                Send4All(clientId, Command.ListUsers, msgToSend);

                                if (roomsChanged != null)
                                    roomsChanged(null, null);
                                playersChanged(true, null);

                                writeToLog(clientList[clientId].login + " присоединился в комнату " + rooms[clientList[clientId].roomId].roomName);
                            }
                            break;

                        case Command.newGame:
                            //создать новый стол
                            if (clientId != -1 && clientList[clientId].roomId == -1)
                            {
                                Room r = new Room();
                                r.phase = 0;
                                r.id = rooms.Count;
                                r.roomName = msgReceived.gameToConnectRoomName;
                                r.maxScores = msgReceived.cardID;
                                r.gamers = clientList[clientId].login;
                                r.password = msgReceived.login;
                                r.gamersSend = r.gamers + " ";
                                r.clientsInRoom = new List<ClientInfo>();
                                r.clientsInRoom.Add(clientList[clientId]);
                                r.deckSize = Convert.ToInt32(msgReceived.UsersInRoom);
                                r.Cards = new List<int>();
                                for (int i = 0; i < r.deckSize; i++)
                                    r.Cards.Add(i + 1);
                                clientList[clientId].isAdmin = true; //первый создавший - админ, может запустить игру
                                rooms.Add(r);
                                clientList[clientId].roomId = r.id;
                                writeToLog(clientList[clientId].login + " создал комнату: " + (r.roomName));

                                if (roomsChanged != null)
                                    roomsChanged(null, null);
                                playersChanged(true, null);
                            }
                            break;

                        #region GameLogic

                        case Command.startGame:
                            if (clientId != -1 && clientList[clientId].roomId != -1)
                            {
                                var r = rooms[clientList[clientId].roomId]; //активная комната
                                r.status = 1; //идет игра
                                r.phase = 1;
                                if (roomsChanged != null)
                                    roomsChanged(null, null);
                                r.gamersSend = r.gamersSend.Replace("# ", " ");
                                r.gamersSend = r.gamersSend.Replace("? ", " ");
                                r.gamersSend = r.gamersSend.Replace("* ", " ");
                                writeToLog("В комнате " + r.roomName + " началась игра!");
                                //msgToSend.UsersInRoom = r.gamersSend;
                                //Send4All(clientId, Command.ListUsers, msgToSend);
                                //начинаем игру раздаем карты
                                Random rnd = new Random();

                                r.sendCount = 0;
                                r.acceptAllEvent.Reset();
                                for (int i = 0; i < r.clientsInRoom.Count; i++)
                                {
                                    r.clientsInRoom[i].scores = 0; //очки в текущей партии
                                    r.clientsInRoom[i].voated = 0;
                                    r.clientsInRoom[i].discarded = 0;
                                    for (int j = 0; j < 5; j++)
                                        msgToSend.userCards[j] = NextCard(rnd, clientId);
                                    msgToSend.cardID = r.maxScores;
                                    msgToSend.cmdCommand = Command.startGame;
                                    message = msgToSend.ToByte();
                                    if (r.clientsInRoom[i].socket.Connected)
                                        r.clientsInRoom[i].socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendRoom),
                                            new PacketInfo(r.clientsInRoom[i].socket, Command.startGame, -2));
                                    else connectionLost("Socket disconnected", r.clientsInRoom[i].socket);
                                    //r.clientsInRoom[i].acceptEvent.WaitOne();
                                    //writeToLog2("Отправлено к " + r.clientsInRoom[i].login + " " + msgToSend.cmdCommand.ToString());
                                }

                                r.acceptAllEvent.WaitOne();

                                roundBegin(r, clientId, rnd, true);

                            }
                            break;

                        case Command.LeaderTurn:
                            if (clientId != -1 && clientList[clientId].roomId != -1)
                            {
                                var r = rooms[clientList[clientId].roomId]; //активная комната
                                int clientRoomId = findClient(r.clientsInRoom, clientSocket);

                                r.clientsInRoom[clientRoomId].discarded = msgReceived.cardID; //занесли в память что скинул
                                msgToSend.cmdCommand = Command.GamersTurn; //передает словесное задание
                                msgToSend.gameToConnectRoomName = msgReceived.gameToConnectRoomName;
                                message = msgToSend.ToByte();

                                if (r.clientsInRoom.Count > 1)
                                {
                                    r.acceptAllEvent.Reset();
                                    r.sendCount = 1;
                                    for (int i = 0; i < r.clientsInRoom.Count; i++)
                                    {
                                        if (i == findLeaderID(clientId)) continue;
                                        if (r.clientsInRoom[i].socket.Connected)
                                            r.clientsInRoom[i].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                                new AsyncCallback(OnSendRoom), new PacketInfo(r.clientsInRoom[i].socket, Command.GamersTurn, -2));
                                        else connectionLost("Socket disconnected", r.clientsInRoom[i].socket);
                                        //writeToLog2("Отправлено к " + r.clientsInRoom[i].login + " " + msgToSend.cmdCommand.ToString());
                                    }

                                    r.acceptAllEvent.WaitOne();
                                }
                                //отчет в список
                                r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "*");
                                msgToSend.UsersInRoom = rooms[clientList[clientId].roomId].gamersSend;
                                Send4All(clientId, Command.ListUsers, msgToSend);
                                r.phase = 4; //ассоциация пришла - отправили команду игрокам для сброса карт
                            }
                            break;

                        case Command.GamersTurn:
                            if (clientId != -1 && clientList[clientId].roomId != -1)
                            {
                                var r = rooms[clientList[clientId].roomId]; //активная комната
                                int clientRoomId = findClient(r.clientsInRoom, clientSocket);
                                r.clientsInRoom[clientRoomId].discarded = msgReceived.cardID; //занесли в память что скинул
                                r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "#");
                                bool isReady = true;
                                foreach (ClientInfo cl in r.clientsInRoom)
                                    if (cl.discarded <= 0) { isReady = false; break; }
                                if (isReady)
                                {
                                    Data msgToSendV = new Data(rooms[clientList[clientId].roomId].clientsInRoom.Count);
                                    msgToSendV.cmdCommand = Command.VoatingTurn;
                                    msgToSendV.userCards = ShuffleDiscarded(clientId);
                                    Send4All(clientId, Command.VoatingTurn, msgToSendV);
                                    r.phase = 5; //все сбросили карты - время для голосования!
                                    r.gamersSend = rooms[clientList[clientId].roomId].gamersSend.Replace("# ", " ");
                                }
                                msgToSend.UsersInRoom = rooms[clientList[clientId].roomId].gamersSend;
                                Send4All(clientId, Command.ListUsers, msgToSend);
                            }
                            break;

                        case Command.VoatingTurn:
                            if (clientId != -1 && clientList[clientId].roomId != -1)
                            {
                                var r = rooms[clientList[clientId].roomId]; //активная комната
                                int clientRoomId = findClient(r.clientsInRoom, clientSocket);
                                r.clientsInRoom[clientRoomId].voated = msgReceived.cardID; //занесли в память что ответил

                                r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "#");
                                bool isReady = true;
                                foreach (ClientInfo cl in r.clientsInRoom)
                                {
                                    if (cl.login == r.clientsInRoom[findLeaderID(clientId)].login) continue;
                                    if (cl.voated <= 0 && cl.ip != "LoggedOut") { isReady = false; break; }
                                }

                                if (isReady) calcResult(r, clientId, msgToSend);

                                msgToSend.UsersInRoom = rooms[clientList[clientId].roomId].gamersSend;
                                Send4All(clientId, Command.ListUsers, msgToSend);

                                r.gamersSend = r.gamersSend.Replace("& ", " ");
                            }
                            break;

                        case Command.Success:
                            if (clientId != -1 && clientList[clientId].roomId != -1)
                            {
                                var r = rooms[clientList[clientId].roomId]; //активная комната
                                int clientRoomId = findClient(r.clientsInRoom, clientSocket);
                                r.clientsInRoom[clientRoomId].voated = 0; //сбрасываем сыгранные карты
                                r.clientsInRoom[clientRoomId].discarded = 0;
                                r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "#");

                                bool isReady = true;
                                foreach (ClientInfo cl in r.clientsInRoom)
                                    if (cl.discarded > 0) { isReady = false; break; }
                                if (isReady) roundBegin(r, clientId, new Random(), false);
                                else
                                {
                                    msgToSend.UsersInRoom = r.gamersSend;
                                    Send4All(clientId, Command.ListUsers, msgToSend);
                                }
                            }
                            break;

                        #endregion

                        case Command.List:
                            //сформировать список столов и вернуть назад
                            msgToSend.cmdCommand = Command.List;
                            msgToSend.list = rooms;
                            message = msgToSend.ToByte();

                            //Send the message to all users

                            if (clientSocket.Connected)
                                clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendOne),
                                    new PacketInfo(clientSocket, Command.List, -1));
                            else connectionLost("Socket disconnected", clientSocket);
                            //writeToLog2("Отправлено к " + clientList[clientId].login + " " + msgToSend.cmdCommand.ToString());
                            playersChanged(true, null);
                            break;

                        case Command.chat:
                            if (clientId != -1)
                            {
                                if (msgReceived.cardID == 1) //сообщение пришло для игровой комнаты
                                {
                                    if (msgReceived.UsersInRoom.StartsWith("@kick")) //получена команда
                                        if (clientList[clientId].isAdmin)
                                        {
                                            string target = msgReceived.UsersInRoom.Remove(0, 6);
                                            for (int i=0; i< rooms[clientList[clientId].roomId].clientsInRoom.Count; i++)
                                                if (rooms[clientList[clientId].roomId].clientsInRoom[i].login == target)
                                                {
                                                    msgToSend.cmdCommand = Command.Disconnect;
                                                    message = msgToSend.ToByte();
                                                    rooms[clientList[clientId].roomId].clientsInRoom[i].acceptEvent.Reset();
                                                    rooms[clientList[clientId].roomId].clientsInRoom[i].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                                        new AsyncCallback(OnSendOne), new PacketInfo(rooms[clientList[clientId].roomId].clientsInRoom[i].socket, Command.Disconnect, -1));
                                                    rooms[clientList[clientId].roomId].clientsInRoom[i].acceptEvent.WaitOne();
                                                }
                                        }

                                        msgToSend.gameToConnectRoomName = msgReceived.UsersInRoom;
                                        msgToSend.login = clientList[clientId].login;
                                        msgToSend.cardID = 1;
                                        Send4All(clientId, Command.chat, msgToSend);

                                }
                                else
                                {
                                    msgToSend.gameToConnectRoomName = msgReceived.UsersInRoom;
                                    msgToSend.login = clientList[clientId].login;
                                    msgToSend.cmdCommand = Command.chat;
                                    msgToSend.cardID = 0;
                                    message = msgToSend.ToByte();
                                    lock (removeLobbyLocker)
                                    {
                                        acceptLobbyEvent.Reset();
                                        sendLobby = 0;
                                        int waiterNum = 0;
                                        for (int i = 0; i < clientList.Count; i++)
                                            if (clientList[i].roomId == -1)
                                                waiterNum++;
                                        if (waiterNum == 0) return;
                                        for (int i = 0; i < clientList.Count; i++)
                                            if (clientList[i].roomId == -1)
                                                if (clientList[i].socket.Connected)
                                                    clientList[i].socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendLobby),
                                                     new PacketInfo(clientList[i].socket, Command.chat, waiterNum));
                                                else connectionLost("Socket disconnected", clientList[i].socket);
                                        acceptLobbyEvent.WaitOne();
                                    }

                                }
                            }
                            break;

                        case Command.logOut:
                            if (clientId != -1)
                            {
                                writeToLog("Игрок " + clientList[clientId].login + " вышел из комнаты " + rooms[clientList[clientId].roomId].roomName);
                                afterDisconnect(clientId, clientSocket, msgToSend);

                                clientList[clientId].roomId = -1;
                                roomsChanged(null, null);
                                playersChanged(true, null);
                            }
                            break;

                        case Command.Disconnect:
                            if (clientId != -1)
                            {
                                if (clientList[clientId].roomId != -1)
                                    afterDisconnect(clientId, clientSocket, new Data());

                                writeToLog("Игрок " + clientList[clientId].login + " отключился");
                                lock (removeLobbyLocker) clientList.RemoveAt(clientId);
                                roomsChanged(null, null);
                                playersChanged(true, null);
                            }
                            break;
                    }

                    //If the user is logging out then we need not listen from her
                    if (msgReceived.cmdCommand != Command.Disconnect && msgToSend.cmdCommand != Command.Failed)
                    {
                        //Start listening to the message send by the user
                        clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
                    }
                }
                log2Changed(log, null);
            }

            catch (Exception ex)
            {
                Socket clientSocket = (Socket)ar.AsyncState;
                connectionLost(ex.Message, clientSocket);
            }
        }
Пример #2
0
        private void afterDisconnect(int clientId, Socket clientSocket, Data msgToSend)
        {
            bool IsNotRemoved = true;
            var r = rooms[clientList[clientId].roomId];
            int clientRoomId = findClient(r.clientsInRoom, clientSocket);
            if (clientList[clientId].isAdmin == true) //вышел админ, меняем его чтобы могли запускать игру
            {
                clientList[clientId].isAdmin = false;
                int newAdminId = clientRoomId - 1;
                if (newAdminId == -1) newAdminId = clientRoomId + 1;
                if (newAdminId == r.clientsInRoom.Count) newAdminId = 0;
                if (r.clientsInRoom.Count > 1)
                {
                    r.clientsInRoom[newAdminId].isAdmin = true;
                    //отправляем уведомление об админстве
                    msgToSend.cmdCommand = Command.setAdmin;
                    byte[] message = msgToSend.ToByte();
                    //while (r.clientsInRoom[newAdminId].isBusy == true) Thread.Sleep(30);
                    if (r.clientsInRoom[newAdminId].socket.Connected)
                    {
                        r.clientsInRoom[newAdminId].acceptEvent.Reset();
                        r.clientsInRoom[newAdminId].socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(OnSendOne),
                            new PacketInfo(r.clientsInRoom[newAdminId].socket, Command.setAdmin, -1));
                        r.clientsInRoom[newAdminId].acceptEvent.WaitOne();
                    }
                    else connectionLost("Socket disconnected", r.clientsInRoom[newAdminId].socket);
                    //r.clientsInRoom[newAdminId].isBusy = true;
                    //writeToLog2("Отправлено к " + r.clientsInRoom[newAdminId].login + " " + msgToSend.cmdCommand.ToString());
                }
            }

            if (rooms[clientList[clientId].roomId].status == 1)
            {
                if (r.phase == 5 && r.clientsInRoom.Count > 1) //отключился в этап голосования
                {
                    //делаем дамп его записи
                    ClientInfo clone = new ClientInfo();
                    clone.isLeader = clientList[clientId].isLeader;
                    clone.ip = "LoggedOut";
                    clone.socket = null;
                    clone.voated = clientList[clientId].voated;
                    clone.discarded = clientList[clientId].discarded;
                    clone.login = clientList[clientId].login;
                    clone.roomId = clientList[clientId].roomId;
                    r.clientsInRoom.RemoveAt(clientRoomId);
                    r.clientsInRoom.Insert(clientRoomId, clone);
                    IsNotRemoved = false; //подменили данные чувака, его вынесли из списка клона вставили
                    r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "?"); //типа пометили его как ушедшего но не удалили

                    //проверка готовности, вдруг тот кто ушел - последний
                    bool isReady = true;
                    foreach (ClientInfo cl in r.clientsInRoom)
                    {
                        if (cl.login == clientList[clientId].login) continue;
                        if (cl.login == r.clientsInRoom[findLeaderID(clientId)].login) continue;
                        if (cl.voated <= 0 && cl.ip != "LoggedOut") { isReady = false; break; }
                    }
                    if (isReady)
                    {
                        calcResult(r, clientId, msgToSend);
                    }

                    r.gamersSend = r.gamersSend.Replace("& ", " ");
                }
                if (r.phase == 4 && r.clientsInRoom.Count > 1) //отключился когда сбрасывал карту
                {
                    if (clientList[clientId].isLeader == true)
                    {
                        //делаем дамп его записи
                        ClientInfo clone = new ClientInfo();
                        clone.isLeader = clientList[clientId].isLeader;
                        clone.ip = "LoggedOut";
                        clone.socket = null;
                        clone.voated = clientList[clientId].voated;
                        clone.discarded = clientList[clientId].discarded;
                        clone.login = clientList[clientId].login;
                        clone.roomId = clientList[clientId].roomId;
                        r.clientsInRoom.RemoveAt(clientRoomId);
                        r.clientsInRoom.Insert(clientRoomId, clone);
                        IsNotRemoved = false; //подменили данные чувака, его вынесли из списка клона вставили
                        r.gamersSend = r.gamersSend.Replace(clientList[clientId].login, clientList[clientId].login + "?"); //типа пометили его как ушедшего но не удалили

                    }
                    //проверяем, что был ли он последним не сбросившим
                    bool flag = true;
                    foreach (ClientInfo ci in r.clientsInRoom)
                    {
                        if (ci.login == clientList[clientId].login) continue;
                        if (ci.discarded == 0) { flag = false; break; }//кто-то тоже не скинул
                    }
                    if (flag) //он последний, его и ждали
                    {
                        r.clientsInRoom.RemoveAt(clientRoomId); //удаляем его наконец
                        IsNotRemoved = false;
                        Data msgToSendV = new Data(r.clientsInRoom.Count);
                        msgToSendV.cmdCommand = Command.VoatingTurn;
                        msgToSendV.userCards = ShuffleDiscarded(clientId);
                        Send4All(clientId, Command.VoatingTurn, msgToSendV);
                        r.phase = 5; //все сбросили карты - время для голосования!
                        r.gamersSend = rooms[clientList[clientId].roomId].gamersSend.Replace("# ", " ");
                    }
                }
                //ведущий игрок вышел из комнаты
                if (clientRoomId == findLeaderID(clientId))
                {
                    int curLeader = clientRoomId;
                    if (r.clientsInRoom[clientRoomId].ip != "LoggedOut")
                    {
                        if (r.phase == 2) curLeader++;
                        else curLeader--;
                        if (curLeader == r.clientsInRoom.Count) curLeader = 0;
                        if (curLeader == -1) curLeader = r.clientsInRoom.Count - 1;
                        if (r.clientsInRoom.Count > 1) r.clientsInRoom[curLeader].isLeader = true;
                        r.clientsInRoom[clientRoomId].isLeader = false;
                    }
                    if (r.phase == 2 && r.clientsInRoom.Count > 2)
                    {
                        msgToSend.cmdCommand = Command.LeaderTurn;
                        byte[] message = msgToSend.ToByte();
                        //while (r.clientsInRoom[curLeader].isBusy == true) Thread.Sleep(30);
                        if (r.clientsInRoom[curLeader].socket.Connected)
                        {
                            r.clientsInRoom[curLeader].acceptEvent.Reset();
                            r.clientsInRoom[curLeader].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                new AsyncCallback(OnSendOne), new PacketInfo(r.clientsInRoom[curLeader].socket, Command.LeaderTurn, -1));
                            r.clientsInRoom[curLeader].acceptEvent.WaitOne();

                            msgToSend.cmdCommand = Command.Waiting;
                            msgToSend.login = r.clientsInRoom[curLeader].login;
                            message = msgToSend.ToByte();
                            r.acceptAllEvent.Reset();
                            r.sendCount = 2;
                            for (int i = 0; i < r.clientsInRoom.Count; i++)
                            {
                                if (i == curLeader || i == clientRoomId) continue;
                                if (r.clientsInRoom[i].socket.Connected)
                                    r.clientsInRoom[i].socket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                        new AsyncCallback(OnSendRoom), new PacketInfo(r.clientsInRoom[i].socket, Command.Waiting, -2));
                                else
                                {
                                    connectionLost("Socket disconnected", r.clientsInRoom[i].socket);
                                    r.acceptAllEvent.Set();
                                }
                            }
                            r.acceptAllEvent.WaitOne();
                            r.gamersSend = r.gamersSend.Replace("# ", " ");
                        }
                        else connectionLost("Socket disconnected", r.clientsInRoom[curLeader].socket);

                    }
                }

                if (r.phase == 6 && r.clientsInRoom.Count > 1) //отключился при ознакомлении с результатами
                {
                    //тут пофиг кто ушел, проверка последнего
                    bool isReady = true;
                    foreach (ClientInfo cl in r.clientsInRoom)
                        if (cl.discarded > 0 && cl.login != clientList[clientId].login) { isReady = false; break; }
                    if (isReady)
                    {
                        r.clientsInRoom.RemoveAt(clientRoomId); //удаляем его наконец
                        IsNotRemoved = false;
                        roundBegin(r, clientId, new Random(), false);
                    }
                }
            }

            //Thread.Sleep(100);
            string test = r.gamers;
            test = test.Replace(" " + clientList[clientId].login + ";", null);
            test = test.Replace(clientList[clientId].login + "; ", null);
            test = test.Replace("; " + clientList[clientId].login, null);
            r.gamers = test;
            r.gamersSend = r.gamersSend.Replace(clientList[clientId].login + " ", null);
            r.gamersSend = r.gamersSend.Replace(clientList[clientId].login + "* ", null);
            r.gamersSend = r.gamersSend.Replace(clientList[clientId].login + "# ", null);
            if (IsNotRemoved) r.clientsInRoom.RemoveAt(clientRoomId); //удаляем его наконец
            playersChanged(false, null); //обновляем таблицу на серваке
            //проверяем есть ли пустые комнаты
            if (r.clientsInRoom.Count == 0)
            {
                int rid = clientList[clientId].roomId;
                rooms.RemoveAt(rid);
                foreach (ClientInfo cl in clientList)
                    if (cl.roomId > rid) cl.roomId--;
            }
            else Send4All(clientId, Command.ListUsers, msgToSend);
        }