• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            創建游戲內核(25)【完】

             

            本篇是創建游戲內核(24)的續篇,涉及到的DirectPlay基礎知識請參閱使用DirectPlay進行網絡互聯(4)。

             

            使用NETWORK_CLIENT處理客戶端

            可以使用NETWORK_CLIENT類來處理網絡的客戶端對象,它的使用方法同NETWORK_SERVER對象的使用方法相似,但有一點不同,那就是連接到網絡的方法,必須使用NETWORK_CLIENT::connect來建立與服務器端的連接。

            來看看類的定義:

            typedef class NETWORK_CLIENT
            {
            public:
                NETWORK_CLIENT();
                
            virtual ~NETWORK_CLIENT();

                IDirectPlay8Client* get_client();

                BOOL init();
                BOOL shutdown();

                BOOL connnect(
            const GUID* guid_adapter, 
                              
            const char* server_ip, long server_port, 
                              
            const char* player_name,
                              
            const char* session_name, const char* session_pwd = NULL);

                BOOL disconnect();
                BOOL is_connected();

                BOOL send_data(
            void* data, ulong size, ulong flags = 0);
                BOOL send_text(
            char* text, ulong flags = 0);

                BOOL get_local_ip(
            char* local_ip);
                
            long get_server_port();
                BOOL get_name(
            char* name);
                BOOL get_session_name(
            char* session_name);
                BOOL get_session_pwd(
            char* session_pwd);

            protected:
                
            static HRESULT WINAPI _network_msg_handler(PVOID user_context, DWORD msg_id, PVOID msg_buffer);

                
            virtual BOOL _add_player_to_group(DPNMSG_ADD_PLAYER_TO_GROUP* msg) { return TRUE; }
                
            virtual BOOL _async_op_complete(DPNMSG_ASYNC_OP_COMPLETE* msg) { return TRUE; }
                
            virtual BOOL _client_info(DPNMSG_CLIENT_INFO* msg) { return TRUE; }
                
            virtual BOOL _connect_complete(DPNMSG_CONNECT_COMPLETE* msg) { return TRUE; }
                
            virtual BOOL _create_group(DPNMSG_CREATE_GROUP* msg) { return TRUE; }
                
            virtual BOOL _create_player(DPNMSG_CREATE_PLAYER* msg) { return TRUE; }
                
            virtual BOOL _destroy_group(DPNMSG_DESTROY_GROUP* msg) { return TRUE; }
                
            virtual BOOL _destroy_player(DPNMSG_DESTROY_PLAYER* msg) { return TRUE; }
                
            virtual BOOL _enum_hosts_query(DPNMSG_ENUM_HOSTS_QUERY* msg) { return TRUE; }
                
            virtual BOOL _enum_hosts_response(DPNMSG_ENUM_HOSTS_RESPONSE* msg) { return TRUE; }
                
            virtual BOOL _group_info(DPNMSG_GROUP_INFO* msg) { return TRUE; }
                
            virtual BOOL _host_migrate(DPNMSG_HOST_MIGRATE* msg) { return TRUE; }
                
            virtual BOOL _indicate_connect(DPNMSG_INDICATE_CONNECT* msg) { return TRUE; }
                
            virtual BOOL _indicated_connect_aborted(DPNMSG_INDICATED_CONNECT_ABORTED* msg) { return TRUE; }
                
            virtual BOOL _peer_info(DPNMSG_PEER_INFO* msg) { return TRUE; }
                
            virtual BOOL _receive(DPNMSG_RECEIVE* msg) { return TRUE; }
                
            virtual BOOL _remove_player_from_group(DPNMSG_REMOVE_PLAYER_FROM_GROUP* msg) { return TRUE; }
                
            virtual BOOL _return_buffer(DPNMSG_RETURN_BUFFER* msg) { return TRUE; }
                
            virtual BOOL _send_complete(DPNMSG_SEND_COMPLETE* msg) { return TRUE; }
                
            virtual BOOL _server_info(DPNMSG_SERVER_INFO* msg) { return TRUE; }
                
            virtual BOOL _terminate_session(DPNMSG_TERMINATE_SESSION* msg) { return TRUE; }

            protected:
                IDirectPlay8Client* _client;

                BOOL                _is_connected;

                
            char                _server_ip[MAX_PATH];
                
            long                _server_port;

                
            char                _name[MAX_PATH];

                
            char                _session_name[MAX_PATH];
                
            char                _session_pwd[MAX_PATH];    
            } *NETWORK_CLIENT_PTR;

            實現:
            //---------------------------------------------------------------------------------
            // Constructor, zero member data.
            //---------------------------------------------------------------------------------
            NETWORK_CLIENT::NETWORK_CLIENT()
            {
                memset(
            this, 0, sizeof(*this)-4);
            }

            //---------------------------------------------------------------------------------
            // Destructor, shutdown this client connection.
            //---------------------------------------------------------------------------------
            NETWORK_CLIENT::~NETWORK_CLIENT()
            {
                shutdown();
            }

            //---------------------------------------------------------------------------------
            // Shutdown this client connection.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::shutdown()
            {
                
            if(! disconnect())
                    
            return FALSE;

                _client = NULL;
                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Disconnet this client to any clients and servers.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::disconnect()
            {
                
            if(_client)
                {
                    
            if(FAILED(_client->Close(0)))
                        
            return FALSE;
                }
                
                _is_connected    = FALSE;
                _server_port     = 0;
                _server_ip[0]    = 0;
                _name[0]         = 0;
                _session_name[0] = 0;
                _session_pwd[0]  = 0;

                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Return pointer to DirectPlay client object.
            //---------------------------------------------------------------------------------
            IDirectPlay8Client* NETWORK_CLIENT::get_client()
            {
                
            return _client;
            }

            //---------------------------------------------------------------------------------
            // Create DirectPlay client object.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::init()
            {
                
            // shutdown older connection first
                shutdown();

                
            // create the client object
                if(FAILED(CoCreateInstance(CLSID_DirectPlay8Client, NULL, CLSCTX_INPROC, IID_IDirectPlay8Client,
                                           (
            void**) &_client)))
                    
            return FALSE;

                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Connect to server.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::connnect(const GUID* guid_adapter, 
                                          
            const char* server_ip, long server_port, 
                                          
            const char* player_name, 
                                          
            const char* session_name, const char* session_pwd)
            {
                
            // disconnnect older connection first
                disconnect();

                
            // error checking
                if(_client == NULL || session_name == NULL || player_name == NULL || server_ip == NULL)
                    
            return FALSE;

                
            if((_server_port = server_port) == 0)
                    
            return FALSE;

                
            // initialize the client object
                if(FAILED(_client->Initialize((PVOID)this, _network_msg_handler, 0)))
                    
            return FALSE;

                
            // assign client information

                DPN_PLAYER_INFO player_info;
                WCHAR w_player_name[MAX_PATH];

                ZeroMemory(&player_info, 
            sizeof(DPN_PLAYER_INFO));

                mbstowcs(w_player_name, player_name, strlen(player_name)+1);

                player_info.dwSize      = 
            sizeof(DPN_PLAYER_INFO);
                player_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
                player_info.pwszName    = w_player_name;

                _client->SetClientInfo(&player_info, NULL, NULL, DPNSETCLIENTINFO_SYNC);

                
            // create address objects

                IDirectPlay8Address* dp_address = NULL;
                IDirectPlay8Address* dp_device  = NULL;

                
            if(FAILED(CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC, IID_IDirectPlay8Address,
                                           (
            void**) &dp_address)))
                    
            return FALSE;

                
            if(FAILED(CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC, IID_IDirectPlay8Address,
                                           (
            void**) &dp_device)))
                {
                    dp_address->Release();
                    
            return FALSE;
                }

                
            // set protocols
                dp_address->SetSP(&CLSID_DP8SP_TCPIP);
                dp_device->SetSP(&CLSID_DP8SP_TCPIP);

                
            // set the port - must not be 0
                dp_address->AddComponent(DPNA_KEY_PORT, &_server_port, sizeof(DWORD), DPNA_DATATYPE_DWORD);    

                WCHAR w_server_ip[MAX_PATH];

                
            // set the host ip address
                mbstowcs(w_server_ip, server_ip, strlen(server_ip)+1);
                dp_address->AddComponent(DPNA_KEY_HOSTNAME, w_server_ip, (DWORD) ((wcslen(w_server_ip) + 1) * 
            sizeof(WCHAR)),
                                         DPNA_DATATYPE_STRING);

                
            // set the adapter
                dp_address->AddComponent(DPNA_KEY_DEVICE, guid_adapter, sizeof(GUID), DPNA_DATATYPE_GUID);
                dp_device->AddComponent(DPNA_KEY_DEVICE, guid_adapter, 
            sizeof(GUID), DPNA_DATATYPE_GUID);

                WCHAR w_session_name[MAX_PATH], w_session_pwd[MAX_PATH];

                
            // record the session name and password
                strcpy(_session_name, session_name);
                mbstowcs(w_session_name, session_name, MAX_PATH);

                
            if(session_pwd)
                {
                    strcpy(_session_pwd, session_pwd);
                    mbstowcs(w_session_pwd, session_pwd, MAX_PATH);
                }

                
            // setup the application description structure

                DPN_APPLICATION_DESC app_desc;

                ZeroMemory(&app_desc, 
            sizeof(DPN_APPLICATION_DESC));

                app_desc.dwSize          = 
            sizeof(DPN_APPLICATION_DESC);
                app_desc.dwFlags         = DPNSESSION_CLIENT_SERVER;
                app_desc.guidApplication = g_app_guid;
                app_desc.pwszSessionName = w_session_name;

                
            if(session_pwd)
                {
                    app_desc.pwszPassword = w_session_pwd;
                    app_desc.dwFlags |= DPNSESSION_REQUIREPASSWORD;
                }

                DPNHANDLE async_handle;

                BOOL ret_value = TRUE;

                
            // connect to server    
                HRESULT rv = _client->Connect(&app_desc, dp_address, dp_device, NULL, NULL, NULL, 0, NULL, &async_handle, 0);

                
            if(FAILED(rv))
                {
                    ret_value = FALSE;

                    
            if(rv == DPNERR_HOSTREJECTEDCONNECTION)
                        err_msg_box("Host reject connection.");
                    
            else if(rv == DPNERR_INVALIDAPPLICATION)
                        err_msg_box("The GUID supplied for the application is invalid.");
                    
            else if(rv == DPNERR_INVALIDDEVICEADDRESS)
                        err_msg_box("The address for the local computer or adapter is invalid.");
                    
            else if(rv == DPNERR_INVALIDFLAGS)
                        err_msg_box("The flags passed to this method are invalid.");
                    
            else if(rv == DPNERR_INVALIDHOSTADDRESS)
                        err_msg_box("The specified remote address is invalid.");
                    
            else if(rv == DPNERR_INVALIDINSTANCE)
                        err_msg_box("The GUID for the application instance is invalid.");
                    
            else if(rv == DPNERR_INVALIDINTERFACE)
                        err_msg_box("The interface parameter is invalid. This value will be returned in a connect request"
                        " if the connecting player was not a client in a client/server game or a peer in a peer-to-peer game.");
                    
            else if(rv == DPNERR_INVALIDPASSWORD)        
                        err_msg_box("An invalid password was supplied when attempting to join a session that requires a password.");
                    
            else if(rv == DPNERR_NOCONNECTION)
                        err_msg_box("No communication link was established.");
                    
            else if(rv == DPNERR_NOTHOST)
                        err_msg_box("An attempt by the client to connect to a nonhost computer.");
                    
            else if(rv == DPNERR_SESSIONFULL)
                        err_msg_box("The maximum number of players allotted for the session has been reached.");
                    
            else if(rv == DPNERR_ALREADYCONNECTED)
                        err_msg_box("The object is already connected to the session.");
                }   
                
                dp_address->Release();
                dp_device->Release();
                
            return ret_value;
            }

            //---------------------------------------------------------------------------------
            // Judge whether client has connected to server.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::is_connected()
            {
                
            return _is_connected;
            }

            //---------------------------------------------------------------------------------
            // Send data to server.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::send_data(void* data, ulong size, ulong flags)
            {
                
            // error checking
                if(_client == NULL)
                    
            return FALSE;

                
            // build a data structure

                DPN_BUFFER_DESC buffer_desc;

                buffer_desc.dwBufferSize = size;
                buffer_desc.pBufferData  = (BYTE*) data;

                DPNHANDLE async_handle;

                
            if(FAILED(_client->Send(&buffer_desc, 1, 0, NULL, &async_handle, flags)))
                    
            return FALSE;

                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Send text to server.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::send_text(char* text, ulong flags)
            {
                
            // error checking
                if(_client == NULL || text == NULL)
                    
            return FALSE;

                
            return send_data(text, (ulong)strlen(text) + 1, flags);
            }

            //---------------------------------------------------------------------------------
            // Get local ip address.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::get_local_ip(char* local_ip)
            {
                WSADATA wsa_data;

                
            if(WSAStartup(MAKEWORD(1, 0), &wsa_data))
                    
            return FALSE;

                
            char local_name[MAX_PATH];
                gethostname(local_name, MAX_PATH);

                HOSTENT* host_ent;

                
            if((host_ent = gethostbyname(local_name)) == NULL)
                {
                    WSACleanup();
                    
            return FALSE;
                }

                
            char* ip_addr = inet_ntoa(*((in_addr*) host_ent->h_addr_list[0]));
                
                WSACleanup();

                
            if(ip_addr == NULL)
                    
            return FALSE;

                strcpy(local_ip, ip_addr);

                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Return port which used to connect to server.
            //---------------------------------------------------------------------------------
            long NETWORK_CLIENT::get_server_port()
            {
                
            return _server_port;
            }


            //---------------------------------------------------------------------------------
            // Return name.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::get_name(char* name)
            {
                
            if(name == NULL)
                    
            return FALSE;

                strcpy(name, _name);
                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Get session name.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::get_session_name(char* session_name)
            {
                
            if(session_name == NULL)
                    
            return FALSE;

                strcpy(session_name, _session_name);
                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Get session password.
            //---------------------------------------------------------------------------------
            BOOL NETWORK_CLIENT::get_session_pwd(char* session_pwd)
            {
                
            if(session_pwd == NULL)
                    
            return FALSE;

                strcpy(session_pwd, _session_pwd);
                
            return TRUE;
            }

            //---------------------------------------------------------------------------------
            // Message handler.
            //---------------------------------------------------------------------------------
            HRESULT WINAPI NETWORK_CLIENT::_network_msg_handler(PVOID user_context, DWORD msg_id, PVOID msg_buffer)
            {
                NETWORK_CLIENT_PTR client;
                DPNMSG_CONNECT_COMPLETE* msg_connect_complte;

                
            if((client = (NETWORK_CLIENT_PTR) user_context) == NULL)
                    
            return E_FAIL;

                
            switch(msg_id)
                {
                
            case DPN_MSGID_ADD_PLAYER_TO_GROUP:
                  
            if(client->_add_player_to_group((DPNMSG_ADD_PLAYER_TO_GROUP*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_ASYNC_OP_COMPLETE:
                  
            if(client->_async_op_complete((DPNMSG_ASYNC_OP_COMPLETE*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_CLIENT_INFO:
                  
            if(client->_client_info((DPNMSG_CLIENT_INFO*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_CONNECT_COMPLETE:
                    
            // update connection information

                    msg_connect_complte = (DPNMSG_CONNECT_COMPLETE*) msg_buffer;

                    
            if(msg_connect_complte->hResultCode == S_OK)
                        client->_is_connected = TRUE;

                    
            if(client->_connect_complete((DPNMSG_CONNECT_COMPLETE*) msg_buffer))
                        
            return S_OK;

                    
            break;

                
            case DPN_MSGID_CREATE_GROUP:
                  
            if(client->_create_group((DPNMSG_CREATE_GROUP*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_CREATE_PLAYER:
                  
            if(client->_create_player((DPNMSG_CREATE_PLAYER*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_DESTROY_GROUP:
                  
            if(client->_destroy_group((DPNMSG_DESTROY_GROUP*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_DESTROY_PLAYER:
                  
            if(client->_destroy_player((DPNMSG_DESTROY_PLAYER*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_ENUM_HOSTS_QUERY:
                  
            if(client->_enum_hosts_query((DPNMSG_ENUM_HOSTS_QUERY*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_ENUM_HOSTS_RESPONSE:
                  
            if(client->_enum_hosts_response((DPNMSG_ENUM_HOSTS_RESPONSE*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_GROUP_INFO:
                  
            if(client->_group_info((DPNMSG_GROUP_INFO*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_HOST_MIGRATE:
                  
            if(client->_host_migrate((DPNMSG_HOST_MIGRATE*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_INDICATE_CONNECT:
                  
            if(client->_indicate_connect((DPNMSG_INDICATE_CONNECT*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_INDICATED_CONNECT_ABORTED:
                  
            if(client->_indicated_connect_aborted((DPNMSG_INDICATED_CONNECT_ABORTED*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_PEER_INFO:
                  
            if(client->_peer_info((DPNMSG_PEER_INFO*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_RECEIVE:
                  
            if(client->_receive((DPNMSG_RECEIVE*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_REMOVE_PLAYER_FROM_GROUP:
                  
            if(client->_remove_player_from_group((DPNMSG_REMOVE_PLAYER_FROM_GROUP*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_RETURN_BUFFER:
                  
            if(client->_return_buffer((DPNMSG_RETURN_BUFFER*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_SEND_COMPLETE:
                  
            if(client->_send_complete((DPNMSG_SEND_COMPLETE*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_SERVER_INFO:
                  
            if(client->_server_info((DPNMSG_SERVER_INFO*) msg_buffer))
                    
            return S_OK;
                  
            break;

                
            case DPN_MSGID_TERMINATE_SESSION:
                  client->_is_connected = FALSE;
                  
            if(client->_terminate_session((DPNMSG_TERMINATE_SESSION*) msg_buffer))
                    
            return S_OK;
                  
            break;
                }

                
            return E_FAIL;
            }

            測試代碼:
            /********************************************************************************
            PURPOSE:
                Test for class NETWORK_CLIENT.
            ********************************************************************************/


            #include "Core_Global.h"

            #define HOST_PORT   12345

            class CLIENT : public NETWORK_CLIENT
            {
            public:
                CLIENT()
                {
                    _is_connect_complete = FALSE;
                }

                BOOL connect_complete()
                {
                    
            return _is_connect_complete;
                }

            private:
                
            virtual BOOL _receive(DPNMSG_RECEIVE* msg)
                {
                    MessageBox(NULL, LPCSTR(msg->pReceiveData), "server message", MB_OK);
                    
                    
            return TRUE;
                }

                
            virtual BOOL _connect_complete(DPNMSG_CONNECT_COMPLETE* Msg)
                {
                    _is_connect_complete = TRUE;

                    
            return TRUE;
                }

            private:
                BOOL _is_connect_complete;
            };

            class APP : public APPLICATION
            {
            public:
                BOOL init()
                {
                    
            if(! _adapter.init())
                        
            return FALSE;

                    
            // get first adapter guid
                    GUID* guid_adapter = _adapter.get_guid(0);

                    
            if(! _client.init())
                        
            return FALSE;

                    
            if(! _client.connnect(guid_adapter, "127.0.0.1", HOST_PORT, "lovedday", "test_session"))
                        
            return FALSE;

                    
            while(! _client.connect_complete())
                        ;

                    
            if(! _client.send_text("Hi, how are you?"))
                        
            return FALSE;

                    
            return TRUE;
                }

                BOOL frame()
                {
                    Sleep(300);

                    
            return TRUE;
                }

                BOOL shutdown()
                {
                    
            return TRUE;
                }

            private:
                CLIENT _client;
                NETWORK_ADAPTER _adapter;
            };

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                APP app;

                
            return app.run();
            }

            posted on 2007-10-14 00:23 lovedday 閱讀(417) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久人人爽人人爽人人AV东京热| 欧美精品丝袜久久久中文字幕| 无码人妻久久一区二区三区免费丨 | 国产精品久久自在自线观看| 精品综合久久久久久97超人| 久久久久九九精品影院| 亚洲色欲久久久综合网| 国产成人精品综合久久久| 久久精品人人做人人妻人人玩| 国产精品熟女福利久久AV| 亚洲色大成网站WWW久久九九| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 精品综合久久久久久97超人| 久久九九免费高清视频 | 九九99精品久久久久久| 日日狠狠久久偷偷色综合免费| 国产精品美女久久久m| 久久久国产视频| 久久久艹| 国内精品伊人久久久久网站| 狠狠色婷婷久久一区二区三区| 麻豆国内精品久久久久久| 美女写真久久影院| 人人狠狠综合久久88成人| 色诱久久av| 欧美国产精品久久高清| a级毛片无码兔费真人久久| 国产亚洲欧美精品久久久| 一本久久知道综合久久| 欧美成人免费观看久久| 亚洲人成网站999久久久综合| 久久99久久无码毛片一区二区| 国内精品久久久久影院日本| 色欲久久久天天天综合网| 亚洲中文字幕无码久久精品1| 一本一道久久a久久精品综合 | 久久久久人妻一区精品果冻| 国内精品久久久久久野外| 久久99国产精品99久久| 久久免费高清视频| 国内精品伊人久久久久影院对白 |