void InGameListner()
    {
        int counter = 0;

        print("Start");
        while (true)
        {
            byte[] buf = new byte[1024];
            try {
                udpClient.ReceiveFrom(buf, ref targetEndPoint);
                if (buf.Length > 0)
                {
                    // CNM에서 현재 아이디와 일치하는 정보를 빼온다. 누락됬다면 몽땅 처리해버림.
                    ClientNetworkMessage cnm = MyTool.BytesToStruct <ClientNetworkMessage>(buf);
                    while (counter != cnm.first_id + 1) // 마지막(첫번째) 데이터와 일치할때까지
                    {
                        byte[] currentBuf;
                        if (cnm.first_id == counter)
                        {
                            ++counter;
                            currentBuf = cnm.first;
                        }
                        else if (cnm.first_id + 1 == counter)
                        {
                            currentBuf = cnm.second;
                            ++counter;
                        }
                        else if (cnm.first_id + 2 == counter)
                        {
                            ++counter;
                            currentBuf = cnm.third;
                        }
                        else
                        {
                            counter    = cnm.first_id + 1;
                            currentBuf = cnm.third;
                        }
                        lock (listenerLocker)
                        {
                            networkReceivedList.Enqueue(currentBuf);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                print("리스너 폭팔 : " + e.Message);
                refreshThread = true;
                break;
            }
        }
        print("Exit");
    }
    private void Update()
    {
        if (listnerThread != null)
        {
            print(listnerThread.ThreadState + "상태");
        }
        switch (currentState)
        {
        case ClientNetworkState.Matching:
            if (targetIp.Length != 0)
            {
                string newTartget;
                lock (listenerLocker)
                {
                    newTartget = targetIp;
                }
                if (newTartget == "0")
                {
                    BindPlayerServer();
                }
                else
                {
                    ConnectToPlayerServer();
                }
            }
            break;

        case ClientNetworkState.InGame:
            // 메세지큐 수신 처리
        {
            while (networkReceivedList.Count > 0)
            {
                byte[] recievedBuf;
                lock (listenerLocker)
                {
                    recievedBuf = networkReceivedList.Dequeue();
                }
                switch ((CTCType)recievedBuf[0])
                {
                case CTCType.AttackSuccess:
                {
                    byte[] realBuf = new byte[recievedBuf.Length - 1];
                    for (int i = 0; i < recievedBuf.Length - 1; ++i)
                    {
                        realBuf[i] = recievedBuf[i + 1];
                    }
                    CM_AttackSuccess msg = MyTool.BytesToStruct <CM_AttackSuccess>(realBuf);
                    GameMain.GetInstance().Attack((msg.type == CharacterType.Local ? CharacterType.Enemy : CharacterType.Local), msg.damage, true);
                }
                break;

                case CTCType.SendTime:
                {
                    byte[] realBuf = new byte[recievedBuf.Length - 1];
                    for (int i = 0; i < recievedBuf.Length - 1; ++i)
                    {
                        realBuf[i] = recievedBuf[i + 1];
                    }
                    CM_SendTime msg = MyTool.BytesToStruct <CM_SendTime>(realBuf);
                    GameMain.GetInstance().timer = msg.timer - (float)(DateTime.Now - DateTime.Parse(msg.dateTime)).TotalSeconds;
                }
                break;

                case CTCType.Disconnect:
                {
                    ChangeState(ClientNetworkState.Matching);
                    return;
                }
                break;

                case CTCType.NoticeDeath:
                {
                    byte[] realBuf = new byte[recievedBuf.Length - 1];
                    for (int i = 0; i < recievedBuf.Length - 1; ++i)
                    {
                        realBuf[i] = recievedBuf[i + 1];
                    }
                    CM_NoticeDeath msg = MyTool.BytesToStruct <CM_NoticeDeath>(realBuf);
                    GameMain.GetInstance().Death((msg.characterType == CharacterType.Local ? CharacterType.Enemy : CharacterType.Local), msg.position, true);
                }
                break;

                case CTCType.UpdatePosition:
                {
                    byte[] realBuf = new byte[recievedBuf.Length - 1];
                    for (int i = 0; i < recievedBuf.Length - 1; ++i)
                    {
                        realBuf[i] = recievedBuf[i + 1];
                    }
                    CM_UpdatePosition msg = MyTool.BytesToStruct <CM_UpdatePosition>(realBuf);
                    Enemy.GetInstance().UpdatePosition(msg.position, msg.velocity);
                }
                break;

                case CTCType.UseSkill:
                {
                    byte[] realBuf = new byte[recievedBuf.Length - 1];
                    for (int i = 0; i < recievedBuf.Length - 1; ++i)
                    {
                        realBuf[i] = recievedBuf[i + 1];
                    }
                    CM_UseSkill msg = MyTool.BytesToStruct <CM_UseSkill>(realBuf);
                    LocalCharacter.GetInstance().InstantiateMissle(msg.skillType, msg.position, msg.rotation, true);
                }
                break;
                }
            }
        }

            // 메세지 전송 처리
            {
                for (int i = 0; i < networkSendList.Count; ++i)
                {
                    SendToServer(networkSendList[i]);
                }
                networkSendList.Clear();
            }
            break;
        }
        if (matchingFlag)
        {
            if (currentState != ClientNetworkState.Ready)
            {
                ChangeState(ClientNetworkState.Matching);
            }
            matchingFlag = false;
        }
        if (refreshThread && listnerThread.ThreadState == ThreadState.Stopped)
        {
            listnerThread.Start();
            refreshThread = true;
        }
    }
Exemplo n.º 3
0
    void Update()
    {
        while (messageQueue.Count != 0)   // 네트워크 메세지를 처리함.
        {
            if (messageQueue.Count > 0)
            {
                NetworkData receivedData;
                lock (listenerLocker)
                {
                    receivedData = messageQueue.Dequeue();
                }
                // 네트워크 처리
                if ((CTSType)receivedData.bytes[0] == CTSType.Matching)
                {
                    for (int i = matchingReadyClients.Count - 1; i >= 0; --i)
                    {
                        if (MyTool.EndPointToIp(matchingReadyClients[i]) == MyTool.EndPointToIp(receivedData.ep))
                        {
                            matchingReadyClients.Remove(matchingReadyClients[i]);
                        }
                    }
                    matchingReadyClients.Add(receivedData.ep);
                    byte[] buf = new byte[1];
                    buf[0] = (byte)STCType.Connected;
                    udpSocket.SendTo(buf, receivedData.ep);
                    Print("매칭 요청 성공, 매칭 중인 유저 수 : " + matchingReadyClients.Count + " " + MyTool.EndPointToIp(receivedData.ep));
                }
                else if ((CTSType)receivedData.bytes[0] == CTSType.Disconnect)
                {
                    matchingReadyClients.Remove(receivedData.ep);
                    Print("매칭 해제 성공");
                }
                else if ((CTSType)receivedData.bytes[0] == CTSType.UpdateRanking)
                {
                    byte[] buf = new byte[receivedData.bytes.Length - 1];
                    for (int i = 0; i < receivedData.bytes.Length - 1; ++i)
                    {
                        buf[i] = receivedData.bytes[i + 1];
                    }
                    CM_UpdateRanking rankingRequest = MyTool.BytesToStruct <CM_UpdateRanking>(buf);
                    // 랭킹을 등록 시켜줌
                    {
                        //DB정보 입력
                        string sqlDatabase = "Server=" + sqlDBip + ";Database=" + sqlDBname + ";UserId=" + sqlDBid + ";Password="******"";
                        //접속 확인하기
                        try
                        {
                            sqlconn = new MySqlConnection(sqlDatabase);
                            sqlconn.Open();

                            MySqlCommand dbcmd = new MySqlCommand("insert into myrank (id, kda) values ('" + rankingRequest.name + "', " + rankingRequest.score + ");", sqlconn); //명령어를 커맨드에 입력
                            dbcmd.ExecuteNonQuery();                                                                                                                              //명령어를 SQL에 보냄

                            sqlconn.Close();
                            Print("랭킹 등록 : " + rankingRequest.name + " " + rankingRequest.score);
                        }
                        catch (Exception e)
                        {
                            Print("DB 접속 실패 : " + e.Message);
                            transform.Find("DBState").GetComponent <UnityEngine.UI.Text>().text = "DB상태 : <color=red>접속실패</color>";
                        }
                    }
                }
                else if ((CTSType)receivedData.bytes[0] == CTSType.SelectRanking)
                {
                    // 랭킹을 조회 시켜줌
                    {
                        //DB정보 입력
                        string sqlDatabase = "Server=" + sqlDBip + ";Database=" + sqlDBname + ";UserId=" + sqlDBid + ";Password="******"";
                        //접속 확인하기
                        try
                        {
                            sqlconn = new MySqlConnection(sqlDatabase);
                            sqlconn.Open();

                            DataTable       dt  = new DataTable(); //데이터 테이블을 선언함
                            MySqlCommand    cmd = new MySqlCommand("select id, kda from myrank order by kda desc limit 10;", sqlconn);
                            MySqlDataReader rdr = cmd.ExecuteReader();

                            string newString = "";
                            int    count     = 1;
                            while (rdr.Read())
                            {
                                newString += count + "@" + rdr["id"] + "&" + int.Parse(rdr["kda"] + "") + "$";
                                count++;
                            }
                            rdr.Close();
                            sqlconn.Close();

                            byte[] stringBuf = Encoding.UTF8.GetBytes(newString);
                            byte[] sendBuf   = new byte[stringBuf.Length + 1];
                            sendBuf[0] = (byte)STCType.SelectRanking;
                            for (int i = 0; i < stringBuf.Length; ++i)
                            {
                                sendBuf[i + 1] = stringBuf[i];
                            }
                            udpSocket.SendTo(sendBuf, receivedData.ep);

                            Print("랭킹 조회 : " + newString);
                        }
                        catch (Exception e)
                        {
                            Print("DB 접속 실패 : " + e.Message);
                            transform.Find("DBState").GetComponent <UnityEngine.UI.Text>().text = "DB상태 : <color=red>접속실패</color>";
                        }
                    }
                }
            }
        }
        while (matchingReadyClients.Count >= 2) // 리스트의 0번과 1번을 매칭 시켜줌.
        {
            // 1의 정보를 0에 전송
            {
                byte[] newBuf = new byte[1];
                newBuf[0] = (byte)STCType.Mathched_S;
                udpSocket.SendTo(newBuf, matchingReadyClients[0]);
            }
            // 0의 정보를 1에 전송
            {
                byte[] newMsg = Encoding.UTF8.GetBytes(MyTool.EndPointToIp(matchingReadyClients[0]));
                byte[] newBuf = new byte[newMsg.Length + 1];
                newBuf[0] = (byte)STCType.Mathched_C;
                for (int i = 0; i < newMsg.Length; ++i)
                {
                    newBuf[i + 1] = newMsg[i];
                }
                udpSocket.SendTo(newBuf, matchingReadyClients[1]);
            }
            matchingReadyClients.Remove(matchingReadyClients[1]);
            matchingReadyClients.Remove(matchingReadyClients[0]);
            Print("매칭 성사 !, 매칭 중인 유저 수 : " + matchingReadyClients.Count);
        }
        if (dieFlag)
        {
            Print("쓰레드 재실행!");
            listenerThread = new Thread(new ThreadStart(NetworkListener));
            listenerThread.Start();
            dieFlag = false;
        }
    }