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

            戰魂小筑

            討論群:309800774 知乎關注:http://zhihu.com/people/sunicdavy 開源項目:https://github.com/davyxu

               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評論 :: 0 Trackbacks

            #

            使用ProtocolBuffer的編譯程序protoc可以將.proto生成*.pb.cc的C++代碼文件. 但是在帶有預編譯頭的工程里, 就經常需要手動添加類似stdafx.h的包含. 這里使用批處理來完成這一過程:

            BuildProtoCC.bat

            @echo off

            set protofile=%1%.proto
            set output_cc=%1%.pb.cc

            "protoc.exe" %protofile% --cpp_out .
            @echo 使用%protofile%生成%output_cc%

            if exist "pchheader.txt" goto 合并預編譯頭 else echo pchheader.txt NOT EXIST

            :合并預編譯頭
            @echo 嘗試刪除以前的中間文件
            del *.pched
            @echo 合并編譯頭文件pchheader.txt到生成%output_cc%
            copy pchheader.txt+"%output_cc%" "%output_cc%.pched" /y
            @echo 等待protoc.exe結束
            @ping -n 2 127.1>nul
            echo 清理文件
            del "%output_cc%"
            ren "%output_cc%.pched" "%output_cc%"

             

            這段批處理這樣使用:

            假設你有一個叫login.proto文件和批處理放在一起

            在同一目錄再放置一個pchheader.txt文件,并在里面寫入#include "stdafx.h”

            調用一下批處理

            call BuildProtoCC.bat login

            注意login不能帶后綴

            將使用protoc.exe生成login.pb.cc和login.pb.h 然后使用批處理合并文件功能自動合并預編譯頭

            posted @ 2011-11-02 17:32 戰魂小筑 閱讀(2228) | 評論 (1)編輯 收藏

            幫朋友轉招聘

             

            應用軟件工程師

            職位描述:

               使用C/C++,MFC和數據庫等工具構建用戶需求的應用軟件。

            職位薪水:
               4000~8000 + 項目獎金

            職位需求:
            1、熟練掌握C語言或C++語言。
            2、熟悉MFC的使用,有Windows GUI編程經驗。
            3、熟悉數據庫的使用并有相關應用經驗。
            4、具備良好的編程思想。
            5、具有一年以上應用軟件開發經驗。

            工作地點:成都, 有意者請密我細談

            posted @ 2011-10-25 14:09 戰魂小筑 閱讀(335) | 評論 (0)編輯 收藏

            我在工程里使用以下函數給線程設置一個方便調試的名稱

                typedef struct tagTHREADNAME_INFO
                {
                    DWORD dwType;        // must be 0x1000
                    LPCSTR szName;        // pointer to name (in user addr space)
                    DWORD dwThreadID;    // thread ID (-1=caller thread)
                    DWORD dwFlags;        // reserved for future use, must be zero
                } THREADNAME_INFO;
             
                void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
                {
                    THREADNAME_INFO info;
                    info.dwType = 0x1000;
                    info.szName = szThreadName;
                    info.dwThreadID = dwThreadID;
                    info.dwFlags = 0;
             
                      // Visit http://www.shnenglu.com/sunicdavy for original article
                    __try
                    {
                        RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
                    }
                    __except(EXCEPTION_CONTINUE_EXECUTION)
                    {
                        int a =1;
                    }
                }

            使用期間一直正常. 隨著工程需求變化,我需要頻繁的將一個被命名的線程創建工作一段時間后馬上結束釋放資源并重新創建,出現了死鎖問題

            死鎖總是發生在主線程的Sleep或者是SetEvent兩個WindowsAPI函數. 而且僅僅在Visual Studio 2008里調試時會發生死鎖,脫離調試環境一切正常.

            我開始打日志調試, 結果發現死鎖前能夠正常創建線程,但是線程函數根本沒有調用進入.之后就在主線程Sleep處死鎖了.

            由于SetThreadName沒有使用正規的API接口,而是使用拋異常方式, 而且線程名稱應該只在Visual Studio IDE中才能顯示, MSDN對RaiseException的描述里也有說明可以使用WaitForDebugEvent接收應用程序拋得異常.因此可以推斷是SetThreadName造成的問題. 屏蔽SetThreadName,測試通過

            posted @ 2011-10-12 09:50 戰魂小筑 閱讀(3027) | 評論 (1)編輯 收藏

               在龔敏敏的 《關于D3D11,你必須了解的幾件事情系列》文章里看到DX11支持DX9特性的細節,特別在DX11的例子中試了一下。

            我的顯卡是Geforce GT440,跑DX11的例子沒有大問題,修改了一下DXSDK里的最簡單Shader例子,跑出來的結論是,DX9_3可以創建設備,但是在CreateVertexShader地方失敗了,嘗試將Shader編譯版本降低到VS_2_0也是持續失敗,于是乎證明了DX11的接口及引擎不能簡單通過調節FEATURE_LEVEL來變成DX9級別跑, 最關鍵的是,DX11不支持XP,XP下跑DX11的例子直接就報找不到DLL。

            因此,我覺得DX11里的DX9的兼容級別很蛋疼,毫無用處的東西。

            龔敏敏的KlayGE引擎在某此升級時直接刪除了DX11以前的所有插件,只使用OpenGL來兼容XP, 可喜的是OpenGL 4.0沒有微軟那么霸道及商業化,可以為XP提供DX11級別的特性,這才是趨勢。

            posted @ 2011-09-29 17:52 戰魂小筑 閱讀(2199) | 評論 (1)編輯 收藏

            使用protobuf的生成器可以對proto文件進行解析后生成指定的目標語言代碼.隨著項目的不斷擴大, 協議修改變的非常頻繁, 因此每次重編變的異常耗時. 模仿C/C++編譯器的時間戳檢查生成機制,我給protobuf生成器添加了時間戳檢查功能. 下面說下原理:

            此功能不是必須的, 可以通過命令行指定—timestampfile FILE 來指定要生成的proto文件對應的時間戳

            每次運行解析器時, 解析器通過命令行獲取proto文件, 我們可以先讀取之前保存的時間戳, 然后與這個文件的當前修改時間進行對比

            如果時間戳不相等,說明文件已經被修改, 需要重新生成.之后更新時間戳文件即可.

            下面是在protobuf的protoc工程里添加的代碼:

            command_line_interface.cc

            void CommandLineInterface::ReadTimeStampFile( const string& timestampfile )
            {
                FILE* f = fopen( timestampfile.c_str(), "rb" );
            
                if ( f == NULL )
                    return;
            
                time_stamp_map_.clear( );
            
                while( !feof( f ) )
                {
                    size_t read = 0;
            
                    int strlen = 0;
                    read = fread( &strlen, 1 , sizeof strlen,  f );
            
                    if ( read == 0 )
                        break;
            
                    std::string filename;
                    filename.resize( strlen );
            
                    read = fread( (void*)filename.data(), 1, sizeof(char) * strlen, f );
            
                    if ( read == 0 )
                        break;
            
            
                    __time64_t timestamp;
                    read = fread( &timestamp, 1, sizeof(timestamp), f );
            
                    if ( read == 0 )
                        break;
            
                    time_stamp_map_[filename] = timestamp;
                }
            
                fclose( f );
            }
            
            void CommandLineInterface::WriteTimeStampFile( const string& timestampfile )
            {
                FILE* f = fopen( timestampfile.c_str(), "wb" );
            
                if ( f == NULL )
                    return;
            
                for ( time_stamp_map::iterator it = time_stamp_map_.begin();
                    it != time_stamp_map_.end();
                    it++)
                {
                    const std::string& filename = it->first;
                    __time64_t timestamp = it->second;
            
                    int strlen = filename.length();
                    fwrite( &strlen, 1, sizeof(strlen), f );
                    fwrite( (void*)filename.data(), 1, sizeof(char)*strlen, f );
                    fwrite( &timestamp, 1, sizeof( timestamp ), f );
                }
                
                fclose( f );
            }
            
            bool CommandLineInterface::NeedGenerate( const std::string& filename )
            {
                struct _stat buf;
            
                if ( _stat( filename.c_str(), &buf ) != 0 )
                {
                    // file error
                    return true;
                }
            
                time_stamp_map::iterator it = time_stamp_map_.find( filename );
            
                
                if ( it != time_stamp_map_.end() )
                {
                    __time64_t& timestamp = it->second;
            
                    if ( timestamp == buf.st_mtime )
                        return false;
                }
            
                // don't hold the time stamp or time stamp not match, generate it!
                
                // save to map , then write time stamp
                time_stamp_map_[filename] = buf.st_mtime;
            
                return true;
            }
            
            
            void CommandLineInterface::CheckFileStamp( const string& timestampfile )
            {
                
                ReadTimeStampFile( timestampfile );
            
                
            
                for (vector<string>::iterator it = input_files_.begin();
                    it != input_files_.end();) {
                    
                    if ( !NeedGenerate( *it) )
                    {
                        it = input_files_.erase( it );
                    }
                    else
                    {
                        ++it;
                    }
                }
            
            
                WriteTimeStampFile( timestampfile );
            }
             

            以上代碼為核心邏輯, 之后在int CommandLineInterface::Run(int argc, const char* const argv[]) 函數中添加代碼:

            int CommandLineInterface::Run(int argc, const char* const argv[]) {
              Clear();
              if (!ParseArguments(argc, argv)) return 1;
            
              // Set up the source tree.
              DiskSourceTree source_tree;
              for (int i = 0; i < proto_path_.size(); i++) {
                source_tree.MapPath(proto_path_[i].first, proto_path_[i].second);
              }
            
              // Map input files to virtual paths if necessary.
              if (!inputs_are_proto_path_relative_) {
                if (!MakeInputsBeProtoPathRelative(&source_tree)) {
                  return 1;
                }
              }
            
              // Allocate the Importer.
              ErrorPrinter error_collector(error_format_, &source_tree);
              Importer importer(&source_tree, &error_collector);
            
              vector<const FileDescriptor*> parsed_files;
            
            
              if ( time_stamp_filename_ != "" )
                CheckFileStamp( time_stamp_filename_ );

            加黑部分為添加的代碼, 這里是檢查時間戳的入口

            同時,我們還需要添加命令行解析開關, 這里在

            bool CommandLineInterface::InterpretArgument(const string& name,
                                                         const string& value) {

            函數中,找到:

              } else if (name == "--error_format") {
                if (value == "gcc") {
                  error_format_ = ERROR_FORMAT_GCC;
                } else if (value == "msvs") {
                  error_format_ = ERROR_FORMAT_MSVS;
                } else {
                  cerr << "Unknown error format: " << value << endl;
                  return false;
                }
            
              } 
              else if ( name == "--timestampfile" ){
                    time_stamp_filename_ = value;
              }
              else if (name == "--plugin") {
                if (plugin_prefix_.empty()) {
                  cerr << "This compiler does not support plugins." << endl;
                  return false;
                }

            加黑部分為解析開關

             

            之后在頭文件中添加聲明代碼:

              // Time stamp function
              void ReadTimeStampFile( const string& timestampfile );
            
              void WriteTimeStampFile( const string& timestampfile );
            
              bool NeedGenerate( const std::string& filename );
            
              void CheckFileStamp( const string& timestampfile );
            
              typedef std::map<std::string, __time64_t> time_stamp_map;    // proto file name as key, timestamp as value
              time_stamp_map time_stamp_map_;
              string time_stamp_filename_;
            
            轉載請注明: 戰魂小筑http://www.shnenglu.com/sunicdavy
            posted @ 2011-08-16 11:38 戰魂小筑 閱讀(3892) | 評論 (1)編輯 收藏

            protocolbuffer默認支持java, python 和c++,其他的語言需要自己編寫代碼生成器他語言的代碼.

            不過官網也提到過ActionScript3的支持,點擊看這里

            protobuf-actionscript3包括ActionScript3的序列號及反序列化的as源碼.以及protoc的as3代碼生成器的C++代碼

            另外, protobuf-actionscript3還需要一個加密庫as3crypto支持,需要一并下載

            當然, protobuf 庫也是最重要的.

            下面說明如何編譯出支持as3的protoc代碼生成器:

             

            1. 將protobuf-actionscript3庫中compiler\as3目錄拷貝到protobuf庫的src\google\protobuf\compiler下.目錄結構如下:

            as3\
                cpp\
                java\
                python\
                code_generator.cc
                command_line_interface.cc

            ...

             

            2.打開protobuf工程中的sln, 在libprotoc添加剛才添加的as3目錄下的所有文件

            3. 在protoc工程的main.cc中添加

              google::protobuf::compiler::as3::As3Generator as3_generator;
              cli.RegisterGenerator("--as3_out", &as3_generator,
                  "Generate ActionScript source file."); 

            4. 打開as3_file.h

            注釋掉以下代碼

            namespace protobuf {
              class FileDescriptor;        // descriptor.h
              namespace io {
                class Printer;             // printer.h
              }
              namespace compiler {
                class OutputDirectory;     // code_generator.h
              }
            }

            包含內添加

            #include <google/protobuf/stubs/common.h>
            #include <google/protobuf/compiler/code_generator.h>
            #include <google/protobuf/io/printer.h>
            5. 編譯出protoc.exe
            6. 準備proto文件, 使用protoc.exe使用類似CPP生成的方式進行生成
            7. 將protobuf-actionscript里的as3-lib及下載好的加密的swc整合到自己的flash工程即可開始使用
            posted @ 2011-08-10 22:00 戰魂小筑 閱讀(2886) | 評論 (0)編輯 收藏

            LNK4099號警告發生于 靜態庫沒有提供pdb文件給之后使用靜態庫的工程鏈接中

            解決方法如下:

             

            找到靜態庫的工程屬性:C/C++->Output Files

            將Program Database File Name改為與靜態庫同名的pdb文件

            清理工程, 重新編譯,將lib及pdb提供給鏈接工程即可

             

            P.S. 默認配置中的pdb是vcXX.pdb XX為VC版本, vs2008對應VC90.pdb

             

            轉載請注明: 戰魂小筑http://www.shnenglu.com/sunicdavy

            posted @ 2011-08-09 10:53 戰魂小筑 閱讀(6804) | 評論 (2)編輯 收藏

            對于習慣于SVN的集中式代碼管來說,Windows下的TortoiseHg需要一些規范來避免代碼合并錯誤及丟失,下面我具體說下TortoiseHg操作中的一些注意要點.

            這里使用的TortoiseHg版本是2.0.4,對應的Mercurial版本是1.8.3,操作環境為局域網

            1. 克隆代碼

            image

            局域網獲取代碼時,代碼源(Source)的格式是 http://ip-address:8000

            而代碼源的機器需要打開WorkBench->Repository->Web Server...

            默認情況下,不打開Web Server,別人是無法獲取你電腦上的代碼庫的.

            2. 代碼changeset的辨別

            image 

            默認的,Graph里左邊一支是自己的版本,右邊的一支代表其他人提交過來的changeset. 帶圈的代表工作目錄基于的版本修改

            3. 同步代碼

            默認情況下,Push是被禁用的,這也能避免別的不必要的版本被推送到自己的代碼庫.

            需要同步代碼時點擊面板的Synchronize,彈出Remote Repository.

            image

            在文本框里可以輸入http://ip-address:8000之類的地址,點擊右邊的軟盤圖標可以保存該地址以便下次再同步

            點擊Preview可以預覽對方代碼庫的修改,Accept后被獲取到本地

             

            4. 獲取別人代碼,合并本地正在修改的代碼

            image

            出現以上提示時,選擇Merge來合并本地修改.

            不過使用TortoiseHg時, 不建議使用這種方式,比較好的方法應該是在合并前提交自己代碼進庫,參考下面一條.

            5. 獲取別人代碼, 合并已經提交的本地代碼,本地沒有掛起修改的代碼

              使用這種方法時, Pull過代碼后,不Update,而是直接Merge with Local

            image

            碰到有沖突時,需要解決沖突

            image

            請使用Tool Resolve, TortoiseHg會使用你從設定中選擇的合并工具來進行代碼合并,其他功能很類似于SVN. 如果合并不爽,也可以重新進行合并

             

            6. 重新恢復沖突解決

            如果由于誤操作關閉合并對話框,或者是需要提交本地代碼而關閉對話框, 可以在Repository->Resolve…重新打開對話框

             

            以上為本人的一些心得,歡迎板磚伺候

            轉載請注明 戰魂小筑 及本文地址

            posted @ 2011-05-25 19:22 戰魂小筑 閱讀(3691) | 評論 (0)編輯 收藏

            等了大半年,松鼠腳本終于釋出了3.0穩定版本

            松鼠腳本可以說是Lua的超級增強版,作者在Crysis項目使用Lua多年,深知Lua的優缺點.之后自己編寫了松鼠腳本來解決諸如class,attribute,delegation,更強大的thread,exception等等功能.

            松鼠腳本本身對Windows開發人員極為照顧,第三方庫可謂豐富,遠程調試,代碼加色及語法檢查都可以直接在VS2008的IDE中進行.

            簡單的遠程調試功能需要以下步驟:

            1. 下載松鼠腳本3.0版本

            2. 在松鼠腳本Wiki中下載SQDBG遠程調試庫

            3. 將sqdbg工程放到SQUIRREL3之下,打開SQUIRREL3\squirrel.sln,將sqdbg添加到工程,編譯所有

            4. 在這個Solution下,創建一個Squirrel松鼠工程

            image

            5. 在新創建的松鼠工程屬性中如下圖設置

            image 

            Interpreter其實就是啟動調試器(不是sq.exe)

            WorkingDirectory 就是main.nut所在的目錄(官網的路徑設置有點誤導)

            Command Line Options 就是傳入sqdbg.exe的命令行參數

            修改下main.nut文件,例如:

            for(local i = 1;i<10;i++)
            {
                print( i );
            }

            在print語句前打上斷點,調試松鼠工程,即可看到調試結果

            image

             

            有關于SQDBG多文件調試:

            SQDBG默認只能調試1個文件,顯然是個玩具,不能應對游戲和其他領域的多文件調試. 分析了下SQDBG的代碼

               1:  int main(int argc, char *argv[])
               2:  {
               3:      if(argc < 2){
               4:          scprintf(_SC("SQDBG error : no file specified"));
               5:          return -1;
               6:      }
               7:          
               8:      HSQUIRRELVM v = sq_open(1024);
               9:      sqstd_seterrorhandlers(v);
              10:   
              11:      //!! INITIALIZES THE DEBUGGER ON THE TCP PORT 1234
              12:      //!! ENABLES AUTOUPDATE
              13:      HSQREMOTEDBG rdbg = sq_rdbg_init(v,1234,SQTrue);
              14:      if(rdbg) {
              15:   
              16:          //!! ENABLES DEBUG INFO GENERATION(for the compiler)
              17:          sq_enabledebuginfo(v,SQTrue);
              18:   
              19:          sq_setprintfunc(v,printfunc,errorfunc);
              20:   
              21:          //!! SUSPENDS THE APP UNTIL THE DEBUGGER CLIENT CONNECTS
              22:          if(SQ_SUCCEEDED(sq_rdbg_waitforconnections(rdbg))) {
              23:              scprintf(_SC("connected\n"));
              24:   
              25:              const SQChar *fname=NULL;
              26:  #ifdef _UNICODE
              27:              SQChar sTemp[256];
              28:              mbstowcs(sTemp,argv[1],(int)strlen(argv[1])+1);
              29:              fname=sTemp;
              30:  #else
              31:              fname=argv[1];
              32:  #endif 
              33:              //!!REGISTERS STANDARDS LIBS
              34:              sq_pushroottable(v);
              35:              sqstd_register_bloblib(v);
              36:              sqstd_register_iolib(v);
              37:              //!!EXECUTE A SCTIPT
              38:              if(SQ_FAILED(sqstd_dofile(v,fname,SQFalse,SQTrue))) {
              39:                  PrintError(v);
              40:                  _getch();
              41:              }
              42:          }
              43:          //!! CLEANUP
              44:          sq_rdbg_shutdown(rdbg);
              45:      }
              46:      else {
              47:          PrintError(v);
              48:      }
              49:      sq_close(v);

            發現寫這個庫的老外還是很認真的,使用了sq_rdbg作為debugger的api前綴,意味著這個庫代碼是可以復用的.

            注意第38行:

            sqstd_dofile(v,fname,SQFalse,SQTrue)

            這就是SQDBG只能debug 1個文件的原因.

            如果需要在項目中做遠程調試,只需要將這句代碼換為工程中加載所有腳本的代碼和注冊系統API代碼即可

             

            當然,最簡單的方法,直接在代碼頂端添加dofile引用另外的代碼即可

            posted @ 2011-05-14 17:42 戰魂小筑 閱讀(5309) | 評論 (5)編輯 收藏

            最近正為游戲引擎選擇一款較好的邏輯腳本而頭疼不已

            1. Lua

            Lua用了5,6年的樣子,從LuaPlus到lua-tinker再到lua_bind. 雖然lua本身很小巧方便,但是其不支持面向對象特性,讓很多人在使用時模擬了很多面向對象的特性,但是這種做法在調試時簡直是噩夢.

            我覺得游戲腳本最好是能預編譯成byte code,讓編譯器在編譯期將很多的bug暴露出來,而不是像lua那樣.很多空訪問錯誤必須要等到runtime才能暴露.讓調試效率大大降低.這點,mono C#就是極好的選擇.

            2. Mono

            由于Unity的流行,Mono被帶入游戲開發者的視線內.其內置的很多系統腳本都是用C#寫成,而且邏輯腳本用C#編寫也是非常清晰嚴謹的.

            據說Mono在Windows下編譯異常麻煩,而且嵌入方式也沒有太多例子,現在這塊嚴重缺乏資料.

            3. V8

            Google V8正是由于Chrome而風靡起來.直接JIT方式就是Chrome速度飛快的原因.

            最近down了一個下來試了下,果然名不虛傳,API也非常的易用.不過由于不是很熟悉JavaScript的原因, 自己用scons編譯出一個v8的shell,跑了一個帶類繼承的例子,居然不識別class關鍵字.這才感嘆還不如用小巧的lua呢.在我看來,JavaScript與Lua比較,也就是個能new,但是沒class的語言.也被別人稱為半吊子面向對象,都是使用prototype方式來實現類功能.

            4. JavaScriptCore

            在Google V8的類測試碰壁后,馬上研究了下Unity下的JavaScript到底用了什么庫,沒錯就是Apple Safari里的JavaScriptCore. 這東西資料比Mono還少,都是高齡庫了.想必整合不是一般的麻煩.但是還是不確定這個腳本引擎是否原生支持類

            5. Python

            Python? 沒想過這種格式詭異的語言,正如Unity里支持Boo(一種很類似Python的語言)很少有人用一樣, 上次用過Python是在一個build系統里, 游戲里是不會考慮這種腳本系統的,效率也是很大的原因.

            6. AngleScript, GameMonkey

            這兩種語言都是很老的游戲腳本語言,不過都是類c++方式的,不過由于項目使用不多,或許是有一定的bug,資料也相對較少,所以可能最后考慮

            posted @ 2011-05-14 15:13 戰魂小筑 閱讀(11639) | 評論 (24)編輯 收藏

            僅列出標題
            共26頁: First 8 9 10 11 12 13 14 15 16 Last 
            东京热TOKYO综合久久精品| 一本色道久久HEZYO无码| www.久久热.com| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久精品国产国产精品四凭| 久久综合噜噜激激的五月天| 欧美激情精品久久久久久久九九九 | 久久久久无码精品| 性欧美丰满熟妇XXXX性久久久| 久久强奷乱码老熟女网站| 久久精品亚洲AV久久久无码| 性做久久久久久免费观看| 久久国产精品77777| 天堂久久天堂AV色综合| 国产成人精品久久一区二区三区av | 久久久久久曰本AV免费免费| 久久亚洲国产午夜精品理论片| 久久人人妻人人爽人人爽| 久久精品国产精品青草app| 精品免费tv久久久久久久| 婷婷久久综合九色综合绿巨人| 久久亚洲精品国产精品| 偷窥少妇久久久久久久久| 香蕉久久夜色精品国产2020| 怡红院日本一道日本久久 | 嫩草伊人久久精品少妇AV| 日韩AV毛片精品久久久| 99久久精品无码一区二区毛片| 久久综合久久综合九色| 久久亚洲AV成人出白浆无码国产| 久久成人小视频| 综合久久精品色| 色8激情欧美成人久久综合电| 久久996热精品xxxx| 久久国产色av免费看| 中文字幕无码av激情不卡久久| 色婷婷久久久SWAG精品| 久久强奷乱码老熟女网站| 久久久久久久综合综合狠狠| 天天做夜夜做久久做狠狠| 7777精品伊人久久久大香线蕉|