Exemplo n.º 1
0
 public void SendPacketAll(int roomID, COMMAND command, PacketMaker packet)
 {
     if (roomDic.TryGetValue(roomID, out Room room))
     {
         room.SendPacketAll(command, packet);
     }
 }
Exemplo n.º 2
0
        public void SendMsg(string msg)
        {
            PacketMaker maker = new PacketMaker();

            maker.SetMsgLength(Encoding.UTF8.GetByteCount(msg));
            maker.SetCommand((int)COMMAND.RECEIVE_CHAT_MSG);
            maker.SetStringData(msg);

            SendPacket(COMMAND.RECEIVE_CHAT_MSG, maker);
        }
Exemplo n.º 3
0
        public void SendPacketAll(COMMAND command, PacketMaker packet)
        {
            foreach (var user in tokenList)
            {
                //// 같으면 넘긴다
                //if (user == token)
                //    continue;

                user.SendPacket(command, packet);
            }
        }
Exemplo n.º 4
0
        // 패킷 전송
        public void SendPacket(COMMAND command, PacketMaker packet)
        {
            lock (lockQueueObj)
            {
                // 큐에 데이터가 없다면 추가하고 패킷을 보내자
                if (packetQueue.Count == 0)
                {
                    packetQueue.Enqueue(packet);
                    StartSend();

                    return;
                }

                // 큐에 데이터가 있다면 넣기만 하자
                packetQueue.Enqueue(packet);
            }
        }
Exemplo n.º 5
0
        private void StartSend()
        {
            lock (lockQueueObj)
            {
                bool isComplete = true;

                // 체크를 큐가 들어있는지로 하므로 끝나기 전까지 dequeue 금지
                PacketMaker maker = packetQueue.Peek();

                // 데이터를 보내자
                sendArgs.AcceptSocket = null;
                sendArgs.SetBuffer(maker.dataBuffer, 0, maker.currentPos);
                isComplete = socket.SendAsync(sendArgs);
                if (!isComplete)
                {
                    SendComplete(socket, sendArgs);
                }
            }

            //switch (command)
            //{
            //    case COMMAND.SET_USER_ID_DONE:
            //        sendArgs.AcceptSocket = null;
            //        sendArgs.SetBuffer(packet.dataBuffer, 0, packet.currentPos);
            //        socket.SendAsync(sendArgs);

            //        break;

            //    case COMMAND.RECEIVE_CHAT_MSG:
            //        sendArgs.AcceptSocket = null;
            //        sendArgs.SetBuffer(packet.dataBuffer, 0, packet.currentPos);
            //        socket.SendAsync(sendArgs);

            //        break;
            //}
        }
Exemplo n.º 6
0
        // 패킷 수신
        public void ReceivePacket(COMMAND command)
        {
            switch (command)
            {
            case COMMAND.SET_USER_ID:
            {
                string      msg   = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength);
                PacketMaker maker = new PacketMaker();
                if (!userManager.FindUserID(msg))
                {
                    maker.SetMsgLength(Encoding.UTF8.GetByteCount(msg) + 4);
                    maker.SetCommand((int)COMMAND.SET_USER_ID_DONE);
                    maker.SetIntData(1);
                    maker.SetStringData(msg);
                    userID = msg;

                    serverLogCallback(userID + "님이 접속하셨습니다.");
                    //userManager.SendMsgAll(userID + "님이 접속하셨습니다.", this);
                }
                else
                {
                    maker.SetMsgLength(Encoding.UTF8.GetByteCount("ID Already Exist") + 4);
                    maker.SetCommand((int)COMMAND.SET_USER_ID_DONE);
                    maker.SetIntData(0);
                    maker.SetStringData("ID Already Exist");
                }

                SendPacket(COMMAND.SET_USER_ID_DONE, maker);

                break;
            }

            case COMMAND.SEND_CHAT_MSG:
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(userID);
                builder.Append(" : ");
                builder.Append(Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength));

                roomManager.SendMsgAll(roomID, builder.ToString(), this);

                receiveMessageCallback(builder.ToString());

                builder.Clear();

                break;
            }

            case COMMAND.SERVER_DISCONNECTED:
            {
                // 아이디로 접속을 했다면
                if (!string.IsNullOrEmpty(userID))
                {
                    userManager.SendMsgAll(userID + "님이 접속을 종료하였습니다.", this);
                }

                // 해당 소켓에 대한 접속종료가 요청되었음.
                // UserManager에서 해당 토큰 삭제
                userManager.RemoveUserToken(this);
                socket.Disconnect(false);

                // 소켓 DisConnect 후 Dispose로 다 해제 해 주자
                socket.Dispose();
                receiveArgs.Dispose();
                sendArgs.Dispose();
                socket      = null;
                receiveArgs = null;
                sendArgs    = null;

                //receiveMessageCallback(msg);

                break;
            }

            case COMMAND.GET_ROOM:
            {
                StringBuilder builder = new StringBuilder();

                builder.Append(roomManager.GetRoomDic().Count);
                builder.Append("#");

                foreach (var data in roomManager.GetRoomDic())
                {
                    builder.Append(data.Value.GetRoomName());
                    builder.Append("^");
                    builder.Append(data.Value.GetRoomID());
                    builder.Append("^");
                    builder.Append(data.Value.GetRoomUserList().Count);
                    builder.Append("|");
                }

                if (builder.Length != 0)
                {
                    builder.Remove(builder.Length - 1, 1);
                }

                // 방의 수가 몇이되든 상관없으므로 패킷 생성해서 보내기
                PacketMaker maker = new PacketMaker();
                maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString()));
                maker.SetCommand((int)COMMAND.GET_ROOM_DONE);
                maker.SetStringData(builder.ToString());

                SendPacket(COMMAND.GET_ROOM_DONE, maker);

                break;
            }

            case COMMAND.CREATE_ROOM:
            {
                // 방 이름 가져오기.
                string roomName = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength);
                roomID = roomManager.CreateRoomID();

                Room room = new Room();
                room.SetRoomName(roomName);

                // 동일한 아이디의 방이 있으면 실패처리
                // 여기선 간단하게 현재 카운트를 아이디로하자...
                // 이대로 만들면 문제가 발생할 여지가 충분하다. 중간에 방이 삭제되면 어떻게 할 것인가?
                if (roomManager.CheckRoomID(roomID))
                {
                }

                room.SetRoomID(roomManager.GetRoomDic().Count);
                // 최소 방 생성자는 접속 유저이기도 하므로
                room.AddUser(this);

                // RoomManager에 셋팅
                roomManager.AddRoom(roomID, room);


                // 생성한 방에 대한 정보를 클라에 다시 넘겨주자
                StringBuilder builder = new StringBuilder();

                builder.Append(roomID);
                builder.Append("#");
                builder.Append(roomName);
                builder.Append("#");
                builder.Append(room.GetRoomUserList().Count);
                builder.Append("#");

                foreach (var data in room.GetRoomUserList())
                {
                    builder.Append(data.userID);
                    builder.Append("|");
                }

                PacketMaker maker = new PacketMaker();
                maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString()));
                maker.SetCommand((int)COMMAND.CREATE_ROOM_DONE);
                maker.SetStringData(builder.ToString());

                SendPacket(COMMAND.CREATE_ROOM_DONE, maker);


                // 해당 유저를 제외하고 방 갱신 패킷을 보내야함
                builder.Clear();
                builder.Append(roomManager.GetRoomDic().Count);
                builder.Append("#");

                foreach (var data in roomManager.GetRoomDic())
                {
                    builder.Append(data.Value.GetRoomName());
                    builder.Append("^");
                    builder.Append(data.Value.GetRoomID());
                    builder.Append("^");
                    builder.Append(data.Value.GetRoomUserList().Count);
                    builder.Append("|");
                }

                if (builder.Length != 0)
                {
                    builder.Remove(builder.Length - 1, 1);
                }

                // 방의 수가 몇이되든 상관없으므로 패킷 생성해서 보내기
                maker = new PacketMaker();
                maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString()));
                maker.SetCommand((int)COMMAND.GET_ROOM_DONE);
                maker.SetStringData(builder.ToString());

                userManager.SendPacketAll(COMMAND.CREATE_ROOM_DONE, maker, this);

                break;
            }

            case COMMAND.JOIN_ROOM:
            {
                // 접속할 룸 ID
                string roomName = Encoding.UTF8.GetString(receiveBuffers, (Defines.HEADERSIZE + Defines.COMMAND), totalByteLength);
                roomID = roomManager.FindRoomID(roomName);

                // 클라에 실패에 대한 메세지를 보내주자
                if (roomID == -1)
                {
                }

                Room room;

                // 접속할 룸을 찾아서 해당 유저를 추가한다
                if (roomManager.GetRoomDic().TryGetValue(roomID, out room))
                {
                    room.AddUser(this);
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(userID);
                builder.Append("님이 접속하셨습니다.");

                // 접속했다고 방의 다른 클라들에 메세지 보내주자
                roomManager.SendMsgAll(roomID, builder.ToString(), this);


                // 접속완료 메세지 보내기
                builder.Clear();
                builder.Append(roomID);
                builder.Append("#");
                builder.Append(roomManager.GetRoomName(roomID));
                builder.Append("#");
                builder.Append(room.GetRoomUserList().Count);
                builder.Append("#");

                foreach (var data in room.GetRoomUserList())
                {
                    builder.Append(data.userID);
                    builder.Append("|");
                }

                PacketMaker maker = new PacketMaker();
                maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString()));
                maker.SetCommand((int)COMMAND.JOIN_ROOM_DONE);
                maker.SetStringData(builder.ToString());

                roomManager.SendPacketAll(roomID, COMMAND.JOIN_ROOM_DONE, maker);

                break;
            }

            case COMMAND.EXIT_ROOM:
            {
                Room room;

                // 접속할 룸을 찾아서 해당 유저를 제거한다
                if (roomManager.GetRoomDic().TryGetValue(roomID, out room))
                {
                    room.RemoveUser(this);
                }

                StringBuilder builder = new StringBuilder();
                PacketMaker   maker   = new PacketMaker();

                // 룸에 접속한 유저가 있다면
                if (room.GetRoomUserList().Count != 0)
                {
                    // 접속종료를 다른 클라에 보내주자
                    builder.Append(userID);
                    builder.Append("님이 접속을 종료하셨습니다.");
                    roomManager.SendMsgAll(roomID, builder.ToString(), this);

                    // 접속이 종료되어 남은 리스트 보내주기
                    builder.Clear();
                    builder.Append(roomID);
                    builder.Append("#");
                    builder.Append(roomManager.GetRoomName(roomID));
                    builder.Append("#");
                    builder.Append(room.GetRoomUserList().Count);
                    builder.Append("#");

                    foreach (var data in room.GetRoomUserList())
                    {
                        builder.Append(data.userID);
                        builder.Append("|");
                    }

                    maker.SetMsgLength(Encoding.UTF8.GetByteCount(builder.ToString()));
                    maker.SetCommand((int)COMMAND.JOIN_ROOM_DONE);
                    maker.SetStringData(builder.ToString());

                    // 지금은 방에서 나간 유저에게도 보내지만 메소드를 하나 더 추가해서 자기 자신에겐 안보내는 것도 만들면 좋을듯
                    roomManager.SendPacketAll(roomID, COMMAND.JOIN_ROOM_DONE, maker);
                }
                // 유저가 없다면
                else
                {
                    // 방 목록에서 지우고
                    roomManager.RemoveRoom(roomID);
                }

                // 종료되었다고 알려주자
                maker = new PacketMaker();
                maker.SetMsgLength(BitConverter.GetBytes(1).Length);
                maker.SetCommand((int)COMMAND.EXIT_ROOM_DONE);
                maker.SetIntData(1);

                SendPacket(COMMAND.EXIT_ROOM_DONE, maker);

                break;
            }
            }
        }