public void StartReceiving()
        {
            CruMessage[] receiveMsg = new CruMessage[50];

            // 데이터를 받는 것은 언제나 열려있어야 한다.
            // 데이터를 받아서 중앙에서 처리해줄 수 있도록 해야함.
            while (true)
            {
                Receive();
            }
        }
Example #2
0
        public void PushUnicastDataToClient(CruMessage msg, int clientNum)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("parameter is null");
            }

            lock (_clientList)
            {
                _clientList[clientNum].PushUnicastData(msg);
            }
        }
Example #3
0
        // 클라이언트로 보낼 메시지 큐
        // 큐의 사이즈가 커질 수 있으니... 메시지 통신 사이즈를 늘려야하나?
        // 큐는... 리스트 같은거라 Enqueue랑 Dequeue 동기화 안해줘도 상관없지 않나?
        public void PushBroadcastData(CruMessage msg)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("parameter is null");
            }

            lock (_sendQueue)
            {
                _sendQueue.Enqueue(msg);
            }
        }
Example #4
0
        // 클라이언트로부터 온 메시지들을 저장하는 큐
        public void PushReceiveData(CruMessage msg, int clientNum)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("msgs is null");
            }

            lock (_receiveQueue)
            {
                _receiveQueue.Enqueue(msg);
            }
        }
Example #5
0
        // 데이터 사이즈는 버퍼의 최종 사이즈보다 같거나 작다. 왜냐하면, 보낼 때, buffer사이즈보다 작은 사이즈를 보내기 때문!
        // 만약 데이터 사이즈와 버퍼 사이즈가 같다면... 그건 추가적으로 오는 데이터가 있을 수 있다는거니... 추가적인 작업이 있어야 함.
        public CruMessage[] ReceiveByteToMsgs(byte[] buffer, int receiveDatasize)
        {
            CruMessage[] result;
            CruMessage   temp;
            int          headsize;
            int          transferdDataSize = 0;
            short        dataCnt;
            short        type;
            int          idx = 0;

            // 데이터 수 확인
            headsize = CruNetworkProtocol.Head.HEADSIZE_DATACOUNT;
            dataCnt  = BitConverter.ToInt16(buffer, 0);
            result   = new CruMessage[dataCnt];
            idx     += headsize;

            // 개별 데이터 확인
            headsize = CruNetworkProtocol.Head.HEADSIZE_TYPE;

            for (int i = 0; i < dataCnt; ++i)
            {
                // type 확인
                type = BitConverter.ToInt16(buffer, idx);
                idx += headsize;

                // data 확인
                switch (type)
                {
                case (short)CruNetworkProtocol.MSG_TYPE.RESULT_PLAYERS_LOCATION:
                    temp = ExtractMutableDatas(type, buffer, idx, receiveDatasize, out transferdDataSize);
                    idx += transferdDataSize;
                    transferdDataSize = 0;
                    break;

                default:
                    temp = ExtractDatas(type, buffer, idx, receiveDatasize);
                    idx += CruNetworkProtocol.GetMessageTotalSIze(type);
                    break;
                }

                result[i] = temp;
            }

            if (idx > receiveDatasize)
            {
                return(null);
            }

            return(result);
        }
        // Single Item
        public void Enqueue(CruMessage item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item is null");
            }

            if (Count == _capacity)
            {
                throw new IndexOutOfRangeException("queue is full");
            }

            lock (_queue)
            {
                _queue.Enqueue(item);
            }
        }
Example #7
0
        public int ConnectToGame(string id, string token)
        {
            /* 순서 */

            /* 먼저 아이디와 토큰정보를 받아서  유저 체크를 한다.
             * 제대로 인증되면, 그 때, ClientData를 통해 주기적으로 통신(Thread 실행)을 받는다. */
            byte[]     buffer   = new byte[1024];
            int        result   = 0;
            int        datasize = 0;
            CruMessage msg      = new CruMessage(CruNetworkProtocol.MSG_TYPE.CHECK_USER, new object[2] {
                id, token
            });

            datasize = _messageTransfer.ExtractSendDatas(msg, buffer, 0);

            // 로그인 서버 포트로 연결할 것
            Socket client = Connect("localhost", 0);

            // 로그인 정보 전달.
            client.Send(buffer, 0, datasize, SocketFlags.None);
            Array.Clear(buffer, 0, buffer.Length);
            datasize = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

            msg = _messageTransfer.ExtractDatas(CruNetworkProtocol.MSG_TYPE.CHECK_USER, buffer, 0, datasize);

            // datas = _messageTransfer.
            result = (int)msg.Datas[0];

            // 제대로 연결되었다면
            if (result == 1)
            {
                // 제대로 연결되었기에 ClientData 할당. 아닌가...? 그냥 새로 하나 만들까?
                _client = new ClientData(client, (int)msg.Datas[1]);
                // 제대로 사용하려면, 미리 Event를 할당해놓아야 한다.
                _client.sendCompleteCommonEvent    = ProcessSend;
                _client.receiveCompleteCommonEvent = ProcessReceive;

                _client.StartDataTransmit();
            }
            else
            {
                // 제대로 연결이 되지 않았을 때 처리.
            }

            return(result);
        }
Example #8
0
        public void Push(CruMessage item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item is null");
            }

            if (Count == _capacity)
            {
                throw new IndexOutOfRangeException("pool is full");
            }

            item.Initialize(0, null);
            lock (_pool)
            {
                _pool.Push(item);
            }
        }
Example #9
0
        // 연결되었다면 token값 할당. 아니라면 token == null
        public int ConnectToLogin(string id, string pw, out string token)
        {
            // todo
            // id, pw를 로그인서버로 검증받아서 token을 받는다.
            // 결과로 온 연결 실패 값에 따라 다른 명령 처리할 것.
            byte[] buffer   = new byte[1024];
            int    datasize = 0;
            int    result   = 0;

            token = null;

            CruMessage msg = new CruMessage(CruNetworkProtocol.MSG_TYPE.LOGIN_REQUEST, new object[2] {
                (string)id, (string)pw
            });

            // 로그인 요청할 데이터 세팅
            datasize = _messageTransfer.SingleMsgToSendData(msg, buffer, 0, buffer.Length);
            //byte[] buffer = _messageTransfer.DatasToByte(CruNetworkProtocol.MSG_TYPE.LOGIN_REQUEST, datas);

            // 로그인 서버 포트로 연결할 것
            Socket client = Connect("localhost", 8080);

            if (client == null)
            {
                return(-1);
            }

            // 로그인 정보 전달.
            client.Send(buffer, 0, datasize, SocketFlags.None);
            Array.Clear(buffer, 0, buffer.Length);
            datasize = client.Receive(buffer, 0, buffer.Length, SocketFlags.None);

            CruMessage[] receivemsg = _messageTransfer.ReceiveByteToMsgs(buffer, datasize);

            result = (short)receivemsg[0].Datas[0];

            if (result == 0)
            {
                token = (string)receivemsg[0].Datas[1];
            }

            return(result);
        }
Example #10
0
        // 메시지들을 클라이언트로 보낼 byte[]로 변환.
        public int SingleMsgToSendData(CruMessage msg, byte[] buffer, int offset, int buffersize)
        {
            byte[] temp;
            int    datasize = 0;
            int    msgSize  = 0;
            int    dataCnt  = 1;

            // 보낼 데이터 수
            //datasize = CruNetworkProtocol.Head.HEADSIZE_DATACOUNT;
            temp = BitConverter.GetBytes((short)dataCnt);
            Array.Copy(temp, 0, buffer, offset, temp.Length);
            datasize += temp.Length;

            // 데이터 처리
            {
                // msg 추출
                switch (msg.Type)
                {
                case (short)CruNetworkProtocol.MSG_TYPE.RESULT_PLAYERS_LOCATION:
                    msgSize = ExtractMutableSendDatas(msg, buffer, datasize);
                    break;

                default:
                    msgSize = ExtractSendDatas(msg, buffer, datasize);
                    break;
                }

                if (msgSize == 0)
                {
                    throw new SystemException("메시지를 변환하는 과정에서 오류가 발생했습니다.");
                }

                // 추출된 byte 수 만큼 datasize 증가.
                datasize += msgSize;
            }
            if (datasize > buffersize)
            {
                throw new SystemException("buffer size를 초과하였습니다.");
            }

            return(datasize);
        }
Example #11
0
        // CruMessage를 만드는 곳
        public CruMessage ExtractDatas(short type, byte[] buffer, int offset, int totalmsgssize)
        {
            CruMessage result;

            object[] datas;
            int[]    datasizelist;
            CruNetworkProtocol.DATA_TYPE[] typelist;
            int bufferIdx   = 0;
            int setDataSize = 0;

            datasizelist = CruNetworkProtocol.GetMessageSizeList(type);
            typelist     = CruNetworkProtocol.GetMessageTypeList(type);

            datas = new object[datasizelist.Length - 1];

            for (int i = 1; i < datasizelist.Length; ++i)
            {
                // 실제 버퍼 입력받을 위치
                bufferIdx = offset + setDataSize;

                // 다음에 처리할 사이즈가 총 버퍼의 사이즈를 넘어간다면,
                if (bufferIdx + datasizelist[i] > totalmsgssize)
                {
                    throw new SystemException("버퍼 사이즈를 넘겼습니다.");
                }

                // 데이터 Get
                switch (typelist[i])
                {
                case CruNetworkProtocol.DATA_TYPE.BOOLEAN:
                    datas[i - 1] = BitConverter.ToBoolean(buffer, bufferIdx);
                    break;

                case CruNetworkProtocol.DATA_TYPE.SHORT:
                    datas[i - 1] = BitConverter.ToInt16(buffer, bufferIdx);
                    break;

                case CruNetworkProtocol.DATA_TYPE.INT:
                    datas[i - 1] = BitConverter.ToInt32(buffer, bufferIdx);
                    break;

                case CruNetworkProtocol.DATA_TYPE.FLOAT:
                    datas[i - 1] = BitConverter.ToSingle(buffer, bufferIdx);
                    break;

                case CruNetworkProtocol.DATA_TYPE.DOUBLE:
                    datas[i - 1] = BitConverter.ToDouble(buffer, bufferIdx);
                    break;

                case CruNetworkProtocol.DATA_TYPE.STRING:
                {
                    int stringsize = BitConverter.ToInt16(buffer, bufferIdx);
                    datas[i - 1] = Encoding.ASCII.GetString(buffer, bufferIdx + CruNetworkProtocol.Head.HEADSIZE_STRING, stringsize);
                }
                break;

                default:
                    break;
                }

                setDataSize += datasizelist[i];
            }

            // 변화한 데이터 사이즈가, 총량을 넘어갔을 때 ㅇㅇ
            if (setDataSize > datasizelist[0])
            {
                return(null);
            }

            result = new CruMessage(type, datas);

            return(result);
        }
Example #12
0
        public int ExtractMutableSendDatas(CruMessage msg, byte[] buffer, int offset)
        {
            /*
             * 일반적으로 가변데이터 형식은 똑같다.
             * type + data갯수 + (data 정보들) + (data 정보들) + ...
             */
            byte[] temp;
            short  type = msg.Type;

            object[] datas         = msg.Datas;
            int      headSize      = 0;
            int      dataCnt       = datas.Length;
            int      dataSize      = 0;
            int      totalDataSize = 0;

            int[] datasizelist;
            CruNetworkProtocol.DATA_TYPE[] typelist;

            headSize     = CruNetworkProtocol.Head.HEADSIZE_TYPE;
            datasizelist = CruNetworkProtocol.GetMessageSizeList(type);
            typelist     = CruNetworkProtocol.GetMessageTypeList(type);

            // type 처리
            temp = BitConverter.GetBytes(type);
            Array.Copy(temp, 0, buffer, offset + dataSize, headSize);
            dataSize += headSize;

            // data count 처리
            temp = BitConverter.GetBytes((short)datas[0]);
            Array.Copy(temp, 0, buffer, offset + dataSize, datasizelist[1]);
            dataSize += datasizelist[1];

            // data 처리
            for (int i = 1; i < dataCnt; ++i)
            {
                for (int j = 2; j < datasizelist.Length; ++j)
                {
                    // 버퍼 사이즈 넘어가는지 체크
                    if (offset + dataSize + datasizelist[j] > buffer.Length)
                    {
                        throw new SystemException("버퍼 사이즈를 넘어갑니다.");
                    }

                    switch (typelist[j])
                    {
                    case CruNetworkProtocol.DATA_TYPE.BOOLEAN:
                        temp = BitConverter.GetBytes((bool)datas[i]);
                        break;

                    case CruNetworkProtocol.DATA_TYPE.SHORT:
                        temp = BitConverter.GetBytes((short)datas[i]);
                        break;

                    case CruNetworkProtocol.DATA_TYPE.INT:
                        temp = BitConverter.GetBytes((int)datas[i]);
                        break;

                    case CruNetworkProtocol.DATA_TYPE.FLOAT:
                        temp = BitConverter.GetBytes((float)datas[i]);
                        break;

                    case CruNetworkProtocol.DATA_TYPE.DOUBLE:
                        temp = BitConverter.GetBytes((double)datas[i]);
                        break;

                    case CruNetworkProtocol.DATA_TYPE.STRING:
                    {
                        short stringsize;
                        temp = new byte[datasizelist[j]];

                        if ((string)datas[i] == null)
                        {
                            stringsize = 0;
                        }
                        else
                        {
                            stringsize = (short)((string)datas[i]).Length;
                        }

                        // Set string size
                        Array.Copy(BitConverter.GetBytes(stringsize), temp, CruNetworkProtocol.Head.HEADSIZE_STRING);

                        // Set string data
                        if (datas[i] != null)
                        {
                            Encoding.ASCII.GetBytes((string)datas[i], 0, ((string)datas[i]).Length, temp, CruNetworkProtocol.Head.HEADSIZE_STRING);
                        }
                    }
                    break;

                    default:
                        break;
                    }

                    Array.Copy(temp, 0, buffer, offset + dataSize, datasizelist[j]);
                    dataSize += datasizelist[j];
                }
            }

            // 총 데이터 사이즈 = 헤드사이즈 + 데이터묶음 수 사이즈 + ((데이터 묶음 사이즈) * 데이터 묶음 수)
            totalDataSize = headSize + datasizelist[1] + ((datasizelist[0] - datasizelist[1]) * (short)datas[0]);

            if (dataSize != totalDataSize)
            {
                return(0);
            }

            return(dataSize);
        }
Example #13
0
        public int ExtractSendDatas(CruMessage msg, byte[] buffer, int offset)
        {
            byte[] temp;
            short  type = msg.Type;

            object[] datas    = msg.Datas;
            int      headSize = 0;
            int      dataSize = 0;

            int[] datasizelist;
            CruNetworkProtocol.DATA_TYPE[] typelist;

            headSize     = CruNetworkProtocol.Head.HEADSIZE_TYPE;
            datasizelist = CruNetworkProtocol.GetMessageSizeList(type);
            typelist     = CruNetworkProtocol.GetMessageTypeList(type);

            temp = BitConverter.GetBytes(type);
            Array.Copy(temp, 0, buffer, offset + dataSize, headSize);
            dataSize += headSize;

            for (int i = 0; i < msg.Datas.Length; ++i)
            {
                // 버퍼 사이즈 넘어가는지 체크
                if (offset + dataSize + datasizelist[i + 1] > buffer.Length)
                {
                    throw new SystemException("버퍼 사이즈를 넘어갑니다.");
                }

                switch (typelist[i + 1])
                {
                case CruNetworkProtocol.DATA_TYPE.BOOLEAN:
                    temp = BitConverter.GetBytes((bool)datas[i]);
                    break;

                case CruNetworkProtocol.DATA_TYPE.SHORT:
                    temp = BitConverter.GetBytes((short)datas[i]);
                    break;

                case CruNetworkProtocol.DATA_TYPE.INT:
                    temp = BitConverter.GetBytes((int)datas[i]);
                    break;

                case CruNetworkProtocol.DATA_TYPE.FLOAT:
                    temp = BitConverter.GetBytes((float)datas[i]);
                    break;

                case CruNetworkProtocol.DATA_TYPE.DOUBLE:
                    temp = BitConverter.GetBytes((double)datas[i]);
                    break;

                case CruNetworkProtocol.DATA_TYPE.STRING:
                {
                    short stringsize;
                    temp = new byte[datasizelist[i + 1]];

                    if ((string)datas[i] == null)
                    {
                        stringsize = 0;
                    }
                    else
                    {
                        stringsize = (short)((string)datas[i]).Length;
                    }

                    // Set string size
                    Array.Copy(BitConverter.GetBytes(stringsize), temp, CruNetworkProtocol.Head.HEADSIZE_STRING);

                    // Set string data
                    if (datas[i] != null)
                    {
                        Encoding.ASCII.GetBytes((string)datas[i], 0, ((string)datas[i]).Length, temp, CruNetworkProtocol.Head.HEADSIZE_STRING);
                    }
                }
                break;

                default:
                    break;
                }

                Array.Copy(temp, 0, buffer, offset + dataSize, datasizelist[i + 1]);
                dataSize += datasizelist[i + 1];
            }

            if (dataSize != datasizelist[0] + headSize)
            {
                return(0);
            }

            return(dataSize);
        }
Example #14
0
 public void PushMessage(CruMessage msg)
 {
     _client.PushUnicastData(msg);
 }
Example #15
0
        // bool 형으로 만들어서 제대로 처리되었는지 확인해야할까...?
        public void MessageHandle(CruMessage msg, int clientNum)
        {
            CruNetworkProtocol.MSG_TYPE type = (CruNetworkProtocol.MSG_TYPE)msg.Type;

            switch (type)
            {
            case CruNetworkProtocol.MSG_TYPE.LOGIN_REQUEST:
                onLoginRequestEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.LOGIN_ACK:
                onLoginACKEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.CHECK_USER:
                onCheckUserEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.CHECK_USER_ACK:
                onCheckUserACKEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.PLAYER_DATA:
                onPlayerDataEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.CUSTOM_PLAYER_DATA:
                onCustomPlayerDataEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.PLAYER_LOCATION:
                onPlayerLocation(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.ITEM_DATA:
                onItemDataEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.MOVE:
                onMoveEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.LOOK:
                onLookEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.ITEM_BUY:
                onItemBuyEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.REQUEST_PLAYERS_LOCATION:
                onRequestPlayersLocation(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.RESULT_GETEXP:
                onResultGetEXPEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.RESULT_LEVELUP:
                onResultLevelUpEvent(msg, clientNum);
                break;

            case CruNetworkProtocol.MSG_TYPE.RESULT_ATTACK:
                onResultAttackEvent(msg, clientNum);
                break;

            default:
                throw new SystemException("해당 명령이 존재하지 않습니다.");
            }
        }