青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

創(chuàng)建游戲內(nèi)核(24)

 

本篇是創(chuàng)建游戲內(nèi)核(23)的續(xù)篇,涉及到的DirectPlay基礎知識請參閱使用DirectPlay進行網(wǎng)絡互聯(lián)(2)使用DirectPlay進行網(wǎng)絡互聯(lián)(3)

 

使用NETWORK_SERVER處理服務器

可以使用類NETWORK_SERVER來處理網(wǎng)絡服務器端,這個類用于初始化DirectPlay服務器對象,主持游戲會話,處理收到和 要發(fā)送的網(wǎng)絡消息。

來看看它的定義:

//====================================================================================
// This class encapsulate server how to communicate with client.
//====================================================================================
typedef class NETWORK_SERVER
{
public:
    NETWORK_SERVER();
    
virtual ~NETWORK_SERVER();

    IDirectPlay8Server* get_server();

    BOOL init();
    BOOL shutdown();

    BOOL host(
const GUID* guid_adapter, long port, const char* session_name, 
        
const char* session_pwd = NULL, long max_players = 0);

    BOOL disconnect();
    BOOL is_connected();

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

    BOOL disconnect_player(
long player_id);

    BOOL get_ip(
char* ip, ulong player_id = 0);
    BOOL get_name(
char* name, ulong player_id);
    
long get_port();
    BOOL get_session_name(
char* session_name);
    BOOL get_session_pwd(
char* session_pwd);
    
long get_max_players();
    
long get_cur_players_num();    

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:
    IDirectPlay8Server* _server;
    BOOL                _is_connected;
    
long                _port;

    
char                _session_name[MAX_PATH];
    
char                _session_pwd[MAX_PATH];

    
long                _max_players;
    
long                _cur_players_num;    
} *NETWORK_SERVER_PTR;

類的實現(xiàn):
//---------------------------------------------------------------------------------
// Constructor, zero member data.
//---------------------------------------------------------------------------------
NETWORK_SERVER::NETWORK_SERVER()
{
    memset(
this, 0, sizeof(*this) - 4);
}

//---------------------------------------------------------------------------------
// Destructor, shutdown server.
//---------------------------------------------------------------------------------
NETWORK_SERVER::~NETWORK_SERVER()
{
    shutdown();
}

//---------------------------------------------------------------------------------
// Shutdown server.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::shutdown()
{
    
if(! disconnect())
        
return FALSE;

    _server = NULL;
    
return TRUE;
}

//---------------------------------------------------------------------------------
// Disconnect server to all clients.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::disconnect()
{
    
if(_server)
    {
        
// closes the open connection to a session
        if(FAILED(_server->Close(0)))
            
return FALSE;
    }

    _is_connected       = FALSE;
    _port               = 0;
    _session_name[0]    = NULL;
    _session_pwd[0]     = NULL;
    _max_players        = 0;
    _cur_players_num    = 0;

    
return TRUE;
}

//---------------------------------------------------------------------------------
// Return pointer to IDirectPlay8Server object.
//---------------------------------------------------------------------------------
IDirectPlay8Server* NETWORK_SERVER::get_server()
{
    
return _server;
}

//---------------------------------------------------------------------------------
// Create IDirectPlay8Server object.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::init()
{
    
// shutdown old server object first
    shutdown();

    
// create the server object
    if(FAILED(CoCreateInstance(CLSID_DirectPlay8Server, NULL, CLSCTX_INPROC, IID_IDirectPlay8Server,
                               (
void**) &_server)))
    {
        
return FALSE;
    }

    
return TRUE;
}

//---------------------------------------------------------------------------------
// Host server.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::host(const GUID* guid_adapter, long port, 
                          
const char* session_name, const char* session_pwd, long max_players)
{
    
// disconnect from current connection
    disconnect();

    _port = port;

    
// error checking
    if(_server == NULL || session_name == NULL || port == 0)
        
return FALSE;

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

    IDirectPlay8Address* dp_address;

    
// create an address object
    if(FAILED(CoCreateInstance(CLSID_DirectPlay8Address, NULL, CLSCTX_INPROC, IID_IDirectPlay8Address,
                               (
void**) &dp_address)))
        
return FALSE;

    DPN_APPLICATION_DESC app_desc;
    WCHAR w_session_name[MAX_PATH], w_session_pwd[MAX_PATH];

    
// set protocol
    if(FAILED(dp_address->SetSP(&CLSID_DP8SP_TCPIP)))
        
goto fail;

    
// set the port - must not be 0
    if(FAILED(dp_address->AddComponent(DPNA_KEY_PORT, &_port, sizeof(DWORD), DPNA_DATATYPE_DWORD)))
        
goto fail;

    
// set adapter (if any)
    if(guid_adapter)
    {
        
if(FAILED(dp_address->AddComponent(DPNA_KEY_DEVICE, guid_adapter, sizeof(GUID), DPNA_DATATYPE_GUID)))
            
goto fail;
    }

    
// 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

    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;
    }

    _max_players = max_players;

    app_desc.dwMaxPlayers = max_players;

    
// start the hosting
    if(FAILED(_server->Host(&app_desc, &dp_address, 1, NULL, NULL, NULL, 0)))
        
goto fail;

    dp_address->Release();
    _is_connected = TRUE;

    
return TRUE;

fail:
    dp_address->Release();
    
return FALSE;
}

//---------------------------------------------------------------------------------
// Check whether server is hosting now.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::is_connected()
{
    
return _is_connected;
}

//---------------------------------------------------------------------------------
// Send data to client.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::send_data(DPNID player_id, void* data, ulong size, ulong flags)
{
    
// error checking
    if(_server == NULL || size == 0)
        
return FALSE;

    DPNHANDLE async_handle;
    DPN_BUFFER_DESC buf_desc;

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

    
if(FAILED(_server->SendTo(player_id, &buf_desc, 1, 0, NULL, &async_handle, flags)))
        
return FALSE;

    
return TRUE;
}

//---------------------------------------------------------------------------------
// Send string to client.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::send_text(DPNID player_id, char* text, ulong flags)
{
    
// error checking
    if(_server == NULL || text == NULL)
        
return FALSE;

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

//---------------------------------------------------------------------------------
// Disconnect specified player.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::disconnect_player(long player_id)
{
    
// error checking
    if(_server == NULL)
        
return FALSE;

    
// try to disconnect the specified player
    if(FAILED(_server->DestroyClient(player_id, NULL, 0, 0)))
        
return FALSE;

    
return TRUE;
}

//---------------------------------------------------------------------------------
// Get ip address, include server and client ip address.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::get_ip(char* ip, ulong player_id)
{
    
// get host ip address if player_id == 0
    if(player_id == 0)
    {
        WSADATA wsa_data;

        
// initiates use of ws2_32.dll by a process
        if(WSAStartup(MAKEWORD(1, 0), &wsa_data))
            
return FALSE;

        
char local_name[MAX_PATH];

        
// retrieves the standard host name for the local computer
        gethostname(local_name, MAX_PATH);

        
// store information about a given host, such as host name, ip address, and so forth.
        HOSTENT* host_ent;

        
// retrieves host information corresponding to a host name from a host database
        if((host_ent = gethostbyname(local_name)) == NULL)
        {
            
// terminates use of the ws2_32.dll
            WSACleanup();
            
return FALSE;
        }

        
// get localip
        char* local_ip = inet_ntoa(*(in_addr*)host_ent->h_addr_list[0]);

        WSACleanup();

        
if(local_ip == NULL)
            
return FALSE;

        strcpy(ip, local_ip);

        
return TRUE;
    }

    
if(_server == NULL || !_is_connected)
        
return FALSE;

    IDirectPlay8Address* dp_address;

    
// retrieve the player information
    if(FAILED(_server->GetClientAddress((DPNID)player_id, &dp_address, 0)))
        
return FALSE;

    DWORD size  = MAX_PATH;
    DWORD flags = DPNA_DATATYPE_STRING;

    WCHAR client_address[MAX_PATH];

    
// retrieves information on the component at the specified key
    if(FAILED(dp_address->GetComponentByName(DPNA_KEY_HOSTNAME, client_address, &size, &flags)))
    {
        dp_address->Release();
        
return FALSE;
    }

    wcstombs(ip, client_address, MAX_PATH);

    dp_address->Release();
   
    
return TRUE;
}

//---------------------------------------------------------------------------------
// Get player name.
//---------------------------------------------------------------------------------
BOOL NETWORK_SERVER::get_name(char* name, ulong player_id)
{
    
if(_server == NULL)
        
return FALSE;

    DPN_PLAYER_INFO* player_info = NULL;
    DWORD size = 0;

    
// retrieves the client information set for the specified client

    HRESULT rv = _server->GetClientInfo(player_id, player_info, &size, 0);

    
if(FAILED(rv) && rv != DPNERR_BUFFERTOOSMALL)
        
return FALSE;

    player_info = (DPN_PLAYER_INFO*) 
new char[size];
    player_info->dwSize = 
sizeof(DPN_PLAYER_INFO);

    
if(FAILED(_server->GetClientInfo(player_id, player_info, &size, 0)))
    {
        delete[] player_info;
        
return FALSE;
    }

    wcstombs(name, player_info->pwszName, MAX_PATH);
    delete[] player_info;

    
return TRUE;
}

//---------------------------------------------------------------------------------
// Return port of server.
//---------------------------------------------------------------------------------
long NETWORK_SERVER::get_port()
{
    
return _port;
}

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

    strcpy(session_name, _session_name);
    
return TRUE;
}

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

    strcpy(session_pwd, _session_pwd);
    
return TRUE;
}

//---------------------------------------------------------------------------------
// Return max players permitted to login.
//---------------------------------------------------------------------------------
long NETWORK_SERVER::get_max_players()
{
    
return _max_players;
}

//---------------------------------------------------------------------------------
// Return current player number.
//---------------------------------------------------------------------------------
long NETWORK_SERVER::get_cur_players_num()
{
    
return _cur_players_num;
}

//---------------------------------------------------------------------------------
// Callback function to handler message for server.
//---------------------------------------------------------------------------------
HRESULT WINAPI NETWORK_SERVER::_network_msg_handler(PVOID user_context, DWORD msg_id, PVOID msg_buffer)
{
    NETWORK_SERVER* server;

    
if((server = (NETWORK_SERVER*) user_context) == NULL)
        
return E_FAIL;

    
// pass message to user-defined function

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

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

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

    
case DPN_MSGID_CONNECT_COMPLETE:
        
if(server->_connect_complete((DPNMSG_CONNECT_COMPLETE*) msg_buffer))
            
return S_OK;
        
break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
case DPN_MSGID_TERMINATE_SESSION:
        
if(server->_terminate_session((DPNMSG_TERMINATE_SESSION*) msg_buffer))
            
return S_OK;
        
break;
    }

    
return E_FAIL;
}

要使用NETWORK_SERVER類,需要將NETWORK_SERVER類作為基類派生出自己的類。這樣做的原因在于必須重載網(wǎng)絡處理函數(shù)以滿足自己具體的功能需要,NETWORK_SERVER類中包含了每條網(wǎng)絡消息,因此派生出來的類絕不會丟失重要的消息。

要主持游戲會話,需要適配器GUID、會話名稱、可選的密碼以及允許的玩家最大數(shù)目(使用0表示不限制玩家數(shù)目)。當調(diào)用NETWORK_SERVER::host函數(shù)時,DirectPlay就會初始化連接并將控制權(quán)返回給使用者。現(xiàn)在,假設有消息發(fā)過來,那么就應該接收發(fā)送過來的消息并在合適的時候處理它們。創(chuàng)建的每個消息處理函數(shù),如果返回TRUE就表明消息被成功處理,F(xiàn)ALSE表明有錯誤發(fā)生。

接著我們編寫一段代碼來測試NETWORK_SERVER類:

/********************************************************************************
PURPOSE:
    Test for class NETWORK_SERVER.
********************************************************************************/


#include "Core_Global.h"

#define HOST_PORT   12345

class SERVER : public NETWORK_SERVER
{
private:
    
virtual BOOL _receive(DPNMSG_RECEIVE* msg)
    {
        MessageBox(NULL, LPCSTR(msg->pReceiveData), "client message", MB_OK);

        
// send data back to client
        return send_data(msg->dpnidSender, msg->pReceiveData, msg->dwReceiveDataSize, DPNSEND_GUARANTEED);
    }
};

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

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

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

        
if(! _server.host(guid_adapter, HOST_PORT, "test_session"))
            
return FALSE;

        
return TRUE;
    }

    BOOL frame()
    {
        Sleep(300);

        
return TRUE;
    }

    BOOL shutdown()
    {
        
return TRUE;
    }

private:
    SERVER _server;
    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:12 lovedday 閱讀(409) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(178)

3D游戲編程相關(guān)鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            午夜精品久久久久久久久| 国产精品毛片| 亚洲综合久久久久| 久久精品国产一区二区电影| 亚洲精品日韩一| 亚洲欧美日韩中文视频| 亚洲国产欧美在线| 性色av一区二区三区| 亚洲精品一二区| 欧美中日韩免费视频| 99视频在线观看一区三区| 欧美综合77777色婷婷| 亚洲视频综合| 欧美成人性网| 久久精品一区二区国产| 欧美日韩国产欧美日美国产精品| 欧美中在线观看| 久久夜色精品国产欧美乱| 香蕉av777xxx色综合一区| 欧美啪啪一区| 欧美一级视频| 国产精品sm| 亚洲精品欧美| 国产欧美三级| 亚洲图片在区色| 在线亚洲+欧美+日本专区| 免费日韩视频| 欧美不卡视频| 一区二区自拍| 久久疯狂做爰流白浆xx| 先锋资源久久| 国产精品自拍小视频| av不卡在线观看| 宅男精品导航| 欧美日韩国产亚洲一区| 欧美成人一区二区| 在线观看中文字幕亚洲| 久久久久成人精品免费播放动漫| 久久激情视频| 国产亚洲一区二区三区在线观看| 亚洲影音一区| 欧美中文字幕在线播放| 国产网站欧美日韩免费精品在线观看| av不卡免费看| 午夜精品视频网站| 国产精品乱人伦中文| 中文av一区二区| 亚洲欧美日韩电影| 国产日韩欧美二区| 久久激情五月激情| 欧美a级理论片| 亚洲精品乱码久久久久久| 欧美波霸影院| 亚洲精品国产精品国自产观看浪潮 | 牛牛精品成人免费视频| 亚洲福利在线观看| 亚洲少妇最新在线视频| 欧美色欧美亚洲另类二区| 欧美一区二区在线播放| 亚洲国产女人aaa毛片在线| 午夜久久美女| 亚洲欧洲日产国产综合网| 国产精品草草| 久久资源av| 亚洲欧美日韩另类精品一区二区三区| 免费在线国产精品| 亚洲欧美视频一区| 亚洲国产成人av| 国产精品丝袜久久久久久app| 久久久久久伊人| 亚洲新中文字幕| 亚洲国产成人av在线 | 亚洲精品中文字幕女同| 国产亚洲欧美一区二区三区| 欧美国产日韩视频| 欧美一区在线直播| 亚洲视频电影在线| 亚洲国内高清视频| 久久躁日日躁aaaaxxxx| 午夜精品免费在线| 亚洲少妇一区| 亚洲伦理自拍| 亚洲高清在线观看一区| 国产欧美一区视频| 国产精品久久久久久久久免费 | 在线成人亚洲| 国产日韩成人精品| 国产精品久久久久久久免费软件| 蜜臀久久99精品久久久画质超高清| 亚洲一区免费| 一区二区激情视频| 亚洲精品在线免费观看视频| 免费毛片一区二区三区久久久| 性做久久久久久| 亚洲欧美日韩精品一区二区| 一本色道久久88综合日韩精品| 亚洲第一精品久久忘忧草社区| 国产模特精品视频久久久久| 国产精品福利在线观看| 欧美午夜片在线观看| 欧美日韩国产三区| 欧美精品网站| 欧美剧在线观看| 欧美精品在线网站| 欧美区在线播放| 欧美日韩免费观看一区二区三区| 欧美二区乱c少妇| 欧美成人在线网站| 欧美精品日韩精品| 欧美日韩精品免费在线观看视频| 欧美国产日韩一区二区三区| 欧美高清视频在线| 欧美人成网站| 国产精品乱人伦一区二区| 国产精品热久久久久夜色精品三区| 欧美午夜精品久久久久久久| 国产精品嫩草久久久久| 国产欧美精品国产国产专区| 国内精品久久久久影院色| 国产曰批免费观看久久久| 激情欧美日韩| 亚洲伦理一区| 午夜精品一区二区三区在线播放| 欧美一级精品大片| 久久综合色播五月| 亚洲高清久久网| 99视频精品| 香蕉av福利精品导航| 久久久久久九九九九| 欧美激情欧美狂野欧美精品| 欧美午夜激情视频| 韩国成人精品a∨在线观看| 亚洲二区免费| 亚洲在线一区二区三区| 久久久久久久999精品视频| 噜噜噜91成人网| 亚洲欧洲日韩综合二区| 香蕉久久一区二区不卡无毒影院 | 国产精品手机在线| 怡红院精品视频| 在线综合亚洲| 久久综合狠狠综合久久综青草| 亚洲欧洲精品一区二区三区不卡 | 欧美网站在线| 亚洲成色www久久网站| 日韩一区二区免费看| 性欧美精品高清| 欧美激情视频给我| 亚洲性视频网址| 久久精品国产v日韩v亚洲 | 亚洲一区二区三区涩| 老司机一区二区| 国产精品分类| 亚洲黄色影院| 久久成人免费日本黄色| 亚洲国产精品毛片| 欧美一区影院| 国产精品久久久久久五月尺| 亚洲国产精品电影在线观看| 欧美一区二区三区播放老司机| 欧美高清视频在线播放| 性欧美8khd高清极品| 欧美日韩在线播放一区二区| 亚洲国产欧美日韩| 久久天堂成人| 亚洲一区在线播放| 欧美日本成人| 亚洲高清二区| 噜噜噜91成人网| 欧美一区二区免费观在线| 欧美日韩亚洲激情| 亚洲精品日日夜夜| 欧美高清在线一区| 欧美一区二区黄色| 国产伦精品一区二区三| 亚洲午夜黄色| 亚洲精品久久7777| 欧美高清视频在线| 亚洲三级影片| 欧美国产精品| 美女999久久久精品视频| 狠狠色丁香婷综合久久| 久久精品亚洲国产奇米99| 亚洲午夜高清视频| 国产精品美腿一区在线看| 亚洲视频每日更新| 在线一区视频| 国产精品国产三级国产专区53| 在线亚洲免费| 中文精品在线| 国产精品久久久久久久久久久久久 | 亚洲一区二区三区在线观看视频| 亚洲国产精品国自产拍av秋霞| 久久人人爽爽爽人久久久| 伊人久久大香线| 欧美风情在线观看| 欧美高清在线精品一区| 一级日韩一区在线观看| 一区二区三区你懂的| 国产精品五月天|