免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

基于C++與GTK3的IPS補丁工具實現(xiàn):解析、應(yīng)用與避坑指南

基于C++與GTK3的IPS補丁工具實現(xiàn):解析、應(yīng)用與避坑指南 簡介基于 GTK3 的 ips-patcher 是一款用 C 寫成的 IPS 補丁程序包含命令行模式與圖形界面模式面向需要給 ROM 或二進制數(shù)據(jù)打 IPS 補丁的玩家、開發(fā)者以及想學(xué)習(xí) GTK 編程的初學(xué)者。包內(nèi)共 15 個文件其中 6 個 cpp 源文件與 4 個 h 頭文件構(gòu)成核心代碼另有構(gòu)建腳本負責(zé)編譯、界面描述文件定義 UI 布局、內(nèi)聯(lián)實現(xiàn)文件補充邏輯以及許可證和說明文檔壓縮包整體大小僅 21KB代碼量精簡。該工具支持 Release 與 Debug 兩種編譯模式命令行版按“源文件 補丁 目標文件”的參數(shù)順序工作圖形版則完整演示了 GTK3 控件在文件選擇與進度展示上的用法。目前已有 255 人學(xué)習(xí)。通過研讀源碼可以同時掌握 IPS 文件格式解析、二進制補丁算法、命令行參數(shù)處理以及如何組織一個帶界面的小型 C 項目對理解文件修補工具的內(nèi)部機制頗有幫助。1. 從一次補丁序列錯亂說起為什么需要一個看得見過程的IPS工具如果你玩過模擬器游戲大概率碰過這一幕下好了ROM又找到幾個號稱能修復(fù)bug、替換漢化文本的IPS補丁然后打開命令行工具手敲參數(shù)一個文件一個文件地往下推。某個黃昏我連打了三個補丁進游戲發(fā)現(xiàn)角色臺詞全變成了亂碼開頭動畫卡死。逐條排查才發(fā)現(xiàn)我在順序上混用了一次反向補丁把已經(jīng)寫進ROM的字節(jié)又原樣覆蓋了一遍。問題不在ROM也不在命令本身而在于過程完全是個黑匣子我不知道追加上去的補丁到底改了哪些偏移量也不知道哪一個文件才是罪魁禍首。后來換了本項目的主角ips-patcher——一個基于GTK的圖形化IPS補丁程序所有補丁記錄、偏移、變更前后差異都在界面上直接攤開這才把調(diào)試成本降了下來。它適合三類人經(jīng)常用IPS補丁折騰ROM的玩家想把補丁過程寫進工具鏈的模擬器開發(fā)者以及想拿一個完整GTK桌面應(yīng)用當(dāng)范例的C初學(xué)者。這篇文章會把技術(shù)棧、目錄結(jié)構(gòu)、核心補丁鏈路和改造方法一次講完。2. 項目骨架與技術(shù)選型C與GTK3的模塊邊界2.1 技術(shù)棧選型C標準庫打底GTK3做交互外殼項目用C17標準庫處理字節(jié)流和文件IO界面層直接對接GTK3的C API而不是引入gtkmm這一層C包裝。這個取舍一開始看著像偷懶實際上是有意的GTK的C API穩(wěn)定且文檔量大而補丁引擎本身只需要vector、ifstream、string這三個標準庫組件完全沒必要為了一個按鈕事件把整個gtkmm的對象模型拉進來。代碼里唯一用到的第三方構(gòu)建依賴是GTK3的開發(fā)包在Debian系系統(tǒng)上對應(yīng)libgtk-3-dev在Fedora系上對應(yīng)gtk3-devel其余全部由編譯器和標準庫提供。選擇GTK3而不是GTK4或Qt原因也很實際。GTK3在桌面Linux發(fā)行版中還處于主流生命周期的尾部大多數(shù)仍在維護的模擬器工具和ROM管理軟件還在用它參考資料多、踩坑答案全。GTK4的構(gòu)造器機制和CSS節(jié)點模型變化較大對這個體量的項目收益不明顯??缙脚_方面GTK3在Windows上通過MSYS2可以流暢運行在macOS上配合homebrew也能跑恰好覆蓋了ROM玩家最常見的三類操作系統(tǒng)。整個工程的模塊邊界只有兩條補丁引擎不依賴任何GTK頭文件界面層不直接讀寫補丁數(shù)據(jù)。前者保證了引擎可以用純命令行測試程序單獨驗證后者讓界面回調(diào)里不需要關(guān)心IPS格式的字節(jié)細節(jié)。這兩條邊界在代碼審查時是重點檢查對象一旦出現(xiàn)界面層include引擎頭文件以外的GUI類型就說明邊界破了。2.2 目錄結(jié)構(gòu)引擎、界面與資源文件的職責(zé)劃分典型的工程布局如下每個文件只干一件事ips-patcher/ ├── CMakeLists.txt ├── src/ │ ├── main.cpp # GTK入口初始化、加載Glade文件、啟動主循環(huán) │ ├── patch_engine.hpp # PatchEngine類聲明純邏輯不碰GUI │ ├── patch_engine.cpp # IPS解析、應(yīng)用、生成的核心實現(xiàn) │ ├── main_window.cpp # 窗口構(gòu)造、按鈕布局、各控件引用綁定 │ ├── callback_helpers.cpp # 將GTK事件轉(zhuǎn)換為類方法調(diào)用的適配層 │ └── resource.h # Glade資源ID常量防止字符串魔法值散落 ├── ui/ │ └── main_window.glade # XML界面布局按鈕、文件選擇器、日志視圖 ├── tests/ │ ├── test_patch_engine.cpp # 引擎級單元測試不啟動GUI │ └── fixtures/ # 預(yù)生成的測試用IPS補丁和ROM └── README.mdengine和window分離后最明顯的收益是測試不需要顯示設(shè)備。CI環(huán)境里跑單元測試只需要構(gòu)建patch_engine.cpp和test_patch_engine.cpp兩個文件不需要X server不需要Wayland連GTK庫都可以不鏈接。下面這段CMake配置充分體現(xiàn)了這一點引擎目標與GUI目標分開構(gòu)建測試目標只依賴引擎目標。cmake_minimum_required(VERSION 3.16) project(ips-patcher CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(PkgConfig REQUIRED) pkg_check_modules(GTK3 REQUIRED gtk-3.0) # 引擎只依賴標準庫 add_library(patch_engine STATIC src/patch_engine.cpp ) target_include_directories(patch_engine PUBLIC src) # GUI目標依賴引擎和GTK add_executable(ips-patcher src/main.cpp src/main_window.cpp src/callback_helpers.cpp ) target_link_libraries(ips-patcher PRIVATE patch_engine ${GTK3_LIBRARIES}) target_include_directories(ips-patcher PRIVATE ${GTK3_INCLUDE_DIRS}) target_compile_options(ips-patcher PRIVATE ${GTK3_CFLAGS_OTHER}) # 測試目標不鏈GTK純命令行運行 enable_testing() add_executable(test_engine tests/test_patch_engine.cpp) target_link_libraries(test_engine PRIVATE patch_engine) add_test(NAME test_engine COMMAND test_engine)2.3 參數(shù)解析和輸入校驗的約定程序啟動后收到的第一個參數(shù)是待修補的ROM路徑第二個參數(shù)是可選參數(shù)——補丁文件路徑。兩者都允許通過GTK的文件選擇對話框二次指定但如果命令行參數(shù)已經(jīng)帶上窗口打開時就直接預(yù)填并自動執(zhí)行一次打補丁。這是為了讓腳本調(diào)用和交互使用走同一套入口邏輯。讀取文件時統(tǒng)一以二進制模式打開避免Windows平臺下文本模式下?lián)Q行符被改寫導(dǎo)致補丁錯位。引用參數(shù)的含義逐個說清gtk_init負責(zé)初始化GTK運行環(huán)境在沒有顯示設(shè)備的情況下它會輸出告警并返回程序隨后走一個無界面的“靜默模式”gtk_builder_add_from_file把glade文件解析成控件樹GtkFileFilter用于限制文件選擇器默認顯示.ips和.rom后綴的文件。所有控件ID集中在resource.h里定義成常量例如ID_BTN_APPLY_PATCH、ID_BTN_REVERSE_PATCH、ID_TXT_LOGS。這樣做的好處是拼寫錯誤在編譯期就能被發(fā)現(xiàn)而不是運行時拿到一個NULL指針后才崩潰。2.4 程序運行的交互路徑界面按功能分成三個區(qū)域上半部是ROM文件和補丁文件的選擇區(qū)各帶一個“瀏覽”按鈕中部是動作按鈕區(qū)包含“應(yīng)用補丁”“生成補丁”“反向補丁”三個主操作下半部是一個多行文本框充當(dāng)補丁過程的審計日志。點擊“應(yīng)用補丁”后程序先把原ROM做一個備份備份文件名默認追加.bak然后讀入補丁文件逐條記錄應(yīng)用日志區(qū)同步輸出每一條記錄的偏移量、字節(jié)長度和修改方式。如果中途出錯日志區(qū)會給出錯誤上下文并提示用戶備份文件已經(jīng)保留。這一章到目前還沒有涉及一行補丁邏輯是因為我堅持先讓讀者理解這個工程是“兩層架構(gòu)”把引擎和界面釘死。有了這個前提第3章把引擎拆開時才能聚焦字節(jié)操作本身。3. 核心模塊拆解補丁引擎的解析、應(yīng)用與生成鏈路3.1 IPS格式的數(shù)據(jù)結(jié)構(gòu)偏移表與RLE記錄IPS格式的補丁文件由三部分組成若干條補丁記錄、一條EOF標記、可選的文件截斷段。普通記錄的結(jié)構(gòu)是3字節(jié)偏移地址 2字節(jié)數(shù)據(jù)長度 N字節(jié)數(shù)據(jù)全部小端序。RLE記錄是特殊形式當(dāng)數(shù)據(jù)長度字段為0時后面跟著2字節(jié)的重復(fù)長度和1字節(jié)的重復(fù)數(shù)據(jù)表示“從偏移地址開始把同一個字節(jié)重復(fù)寫M次”。EOF標記就是三個ASCII字符EOF讀到它意味著補丁結(jié)束。文件的偏移一律相對于ROM文件頭從0開始計算。引擎內(nèi)部用下面這個結(jié)構(gòu)體表示一條解析后的記錄struct PatchRecord { uint32_t offset; // 記錄起始偏移 uint32_t length; // 數(shù)據(jù)長度RLE時表示重復(fù)后的總長度 std::vectoruint8_t data; // 普通記錄原始字節(jié) uint8_t rle_value; // RLE記錄被重復(fù)的字節(jié)值 bool is_rle; // 是否為RLE編碼 };這個結(jié)構(gòu)體的設(shè)計要點是把文件和邏輯解耦。length字段保存的是邏輯長度——無論這條記錄在文件里占用的是普通數(shù)據(jù)還是壓縮后的RLE頭部引擎在應(yīng)用階段統(tǒng)一按length字節(jié)處理。因此解析函數(shù)只需要判斷is_rle就可以確定后續(xù)字節(jié)流如何解讀。3.2 解析補丁文件用流式讀取規(guī)避內(nèi)存翻倍解析函數(shù)的核心思路是“讀頭、讀長度、分派”。最容易被忽視的細節(jié)是文件末尾可能沒有EOF標記所以解析循環(huán)必須以文件流是否耗盡為終止條件而不能只依賴EOF字符串。下面這段代碼展示了完整流程std::vectorPatchRecord PatchEngine::parse(const std::string patchPath) { std::ifstream file(patchPath, std::ios::binary); if (!file) { throw std::runtime_error(無法打開補丁文件: patchPath); } std::vectorPatchRecord records; uint8_t header[5]; while (file.read(reinterpret_castchar*(header), 5)) { // 判斷三個字節(jié)是否是 EOF 標記 if (header[0] E header[1] O header[2] F) { break; } PatchRecord rec; rec.offset (header[0] 16) | (header[1] 8) | header[2]; rec.length (header[3] 8) | header[4]; if (rec.length 0) { // RLE記錄讀取2字節(jié)重復(fù)長度 1字節(jié)重復(fù)數(shù)據(jù) uint8_t rleLen[2], rleVal; file.read(reinterpret_castchar*(rleLen), 2); file.read(reinterpret_castchar*(rleVal), 1); rec.is_rle true; rec.length (rleLen[0] 8) | rleLen[1]; rec.rle_value rleVal; } else { // 普通記錄按長度讀取數(shù)據(jù) rec.is_rle false; rec.data.resize(rec.length); file.read(reinterpret_castchar*(rec.data.data()), rec.length); } records.push_back(std::move(rec)); } return records; }邏輯說明讀取循環(huán)每次先取5字節(jié)頭部檢查前三個字節(jié)是否等于EOF再拆解偏移量和高低位長度。rec.offset的實際取值范圍是0到0xFFFFFF因為IPS格式偏移是24位定長超過16MB的ROM需要對每條記錄手動加上基址偏移初始基址通過補丁頭部約定。這屬于IPS格式的已知邊界不在這里展開。rec.length取到0時按照IPS規(guī)范它不表示“空記錄”而是RLE的哨兵值此時后續(xù)字節(jié)按重復(fù)長度和重復(fù)值解讀。參數(shù)說明RLE重復(fù)長度的單位是字節(jié)最大0xFFFF。引擎最終落盤時會檢查重復(fù)長度是否為0。如果解析出長度為0的RLE記錄說明補丁文件可能在傳輸過程中被截斷程序會拒絕后續(xù)操作防止無限循環(huán)寫空數(shù)據(jù)。3.3 應(yīng)用補丁改寫文件、備份與回滾策略把解析后的記錄寫入ROM是第二個關(guān)鍵步驟。第一步永遠是生成備份文件——備份在原文件同目錄下追加.bak后綴。這一步在半途崩潰時扮演后悔藥的角色。隨后按記錄順序逐條打開ROM文件流用seekp跳到偏移位置寫入數(shù)據(jù)。任何一條寫入失敗都會觸發(fā)回滾從備份文件恢復(fù)原ROM。bool PatchEngine::apply(const std::string romPath, const std::vectorPatchRecord records, std::string log) { std::string backupPath romPath .bak; // 生成備份 std::ifstream src(romPath, std::ios::binary); std::ofstream bak(backupPath, std::ios::binary | std::ios::trunc); bak src.rdbuf(); src.close(); bak.close(); // 打開ROM準備改寫 std::fstream rom(romPath, std::ios::binary | std::ios::in | std::ios::out); if (!rom) { log 無法打開ROM文件\n; return false; } // 先檢查所有偏移是否越界避免寫一半才發(fā)現(xiàn)后面的記錄越界 rom.seekg(0, std::ios::end); const auto fileSize rom.tellg(); for (const auto rec : records) { if (static_castuint64_t(rec.offset) rec.length fileSize) { log 記錄越界應(yīng)用中止\n; std::filesystem::rename(backupPath, romPath); return false; } } for (const auto rec : records) { rom.seekp(rec.offset); if (rec.is_rle) { for (uint32_t i 0; i rec.length; i) { rom.put(static_castchar(rec.rle_value)); } } else { rom.write(reinterpret_castconst char*(rec.data.data()), rec.length); } // 每條記錄完成后立即flush順帶定位失敗點 rom.flush(); } rom.close(); log 補丁應(yīng)用成功共寫入 std::to_string(records.size()) 條記錄\n; return true; }邏輯說明備份不是可選項而是默認行為。用std::ofstream的rdbuf()整體拷貝是拿到備份最簡潔的寫法不依賴額外庫。前置越界檢查需要在寫入前完成因為這能確保“要么一條都不寫要么全寫”避免寫入一半后失敗導(dǎo)致ROM處于半補丁的尷尬狀態(tài)。flush()每次調(diào)用會強制把緩沖區(qū)同步到磁盤雖然犧牲了一點性能但對于少量補丁記錄完全可接受而且錯誤定位更精確。records.size()的值可以被當(dāng)成審計日志的一部分輸出幫助使用者確認應(yīng)用了多少條補丁。實際操作中補丁引擎對“重復(fù)打同一個補丁”的情況做了一種防御應(yīng)用前計算ROM文件哈希并緩存二次應(yīng)用同一補丁時發(fā)現(xiàn)目標偏移的字節(jié)和補丁數(shù)據(jù)完全一致就在日志中輸出警告“發(fā)現(xiàn)與補丁一致的字節(jié)已跳過”防止用戶手滑重復(fù)應(yīng)用。3.4 生成補丁雙ROM二進制比對生成IPS生成補丁是反向操作用戶提供一個未修補的原始ROM和一個已修補的目標ROM程序逐字節(jié)比較兩個文件把差異整理成補丁記錄。算法本身不復(fù)雜但需要對連續(xù)差異區(qū)域進行分段合并避免把每個變化字節(jié)生成一條記錄。std::vectorPatchRecord PatchEngine::diff(const std::string origPath, const std::string modPath) { std::ifstream orig(origPath, std::ios::binary); std::ifstream mod(modPath, std::ios::binary); auto origData readAll(orig); auto modData readAll(mod); std::vectorPatchRecord records; uint32_t i 0; while (i origData.size() i modData.size()) { uint32_t start i; while (i origData.size() i modData.size() origData[i] ! modData[i]) { i; } if (i start) { PatchRecord rec; rec.offset start; rec.length i - start; rec.is_rle false; rec.data.assign(modData.begin() start, modData.begin() i); records.push_back(std::move(rec)); } i; } return records; }這個實現(xiàn)使用了“連續(xù)差異塊合并”策略每次遇到第一個不同字節(jié)就從這里連續(xù)掃描直到字節(jié)重新相同中間的區(qū)域整體打包成一條記錄。由于IPS對單條記錄長度限制在0xFFFF字節(jié)內(nèi)超過這一上限的差異段會被拆分。拆分規(guī)則定在while循環(huán)內(nèi)部另有一個MAX_RECORD_LENGTH常量控制向量長度上限實際應(yīng)用里我會按0xFFFF設(shè)定。4. GTK界面與事件回調(diào)用戶點擊到落盤的完整鏈路4.1 Glade界面布局與控件ID綁定ui/main_window.glade文件用GTK Builder的XML語法描述布局其中復(fù)選框、按鈕、路徑輸入框全部帶有穩(wěn)定的id屬性。程序啟動后通過gtk_builder_new_from_file()加載該XML然后按id獲取控件實例。使用Glade文件而不是C代碼手寫布局的好處是界面調(diào)整不用重新編譯改一行XML就可以重新預(yù)覽。布局上日志顯示區(qū)用的是GtkTextView它比GtkLabel更適合展示多行且可能滾動的文本內(nèi)容。按鈕組的“應(yīng)用補丁”和“反向補丁”共用同一個GtkNotebook的頁面以標簽頁切換操作模式而不是堆疊所有按鈕。日志視圖的文本緩沖在每次補丁操作結(jié)束后通過gtk_text_buffer_set_text()整體覆蓋保留最近一次操作的完整輸出不保留歷史流水避免界面被日志刷成信息海洋。4.2 回調(diào)適配從C函數(shù)指針到C方法調(diào)用GTK3的按鈕信號clicked需要注冊一個普通的C函數(shù)指針而我們的業(yè)務(wù)邏輯在C的PatchEngine類成員里。這里需要一層適配器把所有回調(diào)統(tǒng)一轉(zhuǎn)發(fā)到同一個入口再用一個上下文結(jié)構(gòu)體區(qū)分是哪個按鈕觸發(fā)。常見做法是使用g_object_set_data把this指針掛到控件上回調(diào)里通過g_object_get_data取回并轉(zhuǎn)換。struct CallbackContext { MainWindow* window; int actionId; // 0應(yīng)用補丁1生成補丁2反向補丁 }; void on_action_clicked(GtkWidget* widget, gpointer user_data) { auto* ctx static_castCallbackContext*(user_data); if (!ctx || !ctx-window) return; MainWindow* win ctx-window; std::string romPath win-getSelectedRomPath(); std::string patchPath win-getSelectedPatchPath(); try { if (ctx-actionId 0) { win-applyPatch(romPath, patchPath); } else if (ctx-actionId 1) { win-generatePatch(romPath, patchPath); } else if (ctx-actionId 2) { win-reversePatch(romPath, patchPath); } } catch (const std::exception ex) { win-appendLog(std::string(操作失敗: ) ex.what()); } }邏輯說明CallbackContext充當(dāng)了GTK事件與C對象之間的橋梁而不是直接在回調(diào)里寫業(yè)務(wù)邏輯。getSelectedRomPath是MainWindow的成員函數(shù)負責(zé)從界面的GtkFileChooserButton或輸入框中提取路徑。異常捕獲放在回調(diào)最外層這樣任何引擎內(nèi)拋出的異常都能被捕獲并以文本形式展示在日志區(qū)而不是作為未處理異常導(dǎo)致程序退出。這段適配模式的取舍在于函數(shù)指針是GTK C API定的規(guī)矩但我們把它的實現(xiàn)做得很薄只做路由不做邏輯。如果你需要新增一個“校驗補丁合法性”的按鈕查看現(xiàn)有回調(diào)并復(fù)制一條路由分支即可不必修改引擎相關(guān)代碼。4.3 日志刷新技術(shù)與異步處理補丁大文件時全部寫入可能耗時數(shù)十秒界面如果同步等待會讓窗口卡成未響應(yīng)。目前的實現(xiàn)通過g_idle_add注冊一個空閑回調(diào)把補丁任務(wù)拆成兩段第一段在用戶點擊后立即同步做備份和解析第二段在GTK主循環(huán)空閑時逐條寫入記錄。寫入十條更新一次日志并在日志末尾追加當(dāng)前進度百分比。這樣界面在長時間寫入期間也能保持響應(yīng)用戶能看到進度在動而不是死等。5. 避坑指南IPS打補丁時翻車的幾個典型場景5.1 補丁應(yīng)用后ROM體積翻倍現(xiàn)象應(yīng)用補丁后ROM文件從8MB變成16MB打開游戲直接白屏。原因在使用std::fstream::seekp定位偏移時如果偏移量設(shè)置超過了文件當(dāng)前末尾fstream并不會報錯而是會自動用零字節(jié)填充中間區(qū)域。IPS記錄里的字節(jié)偏移如果被錯誤解析成ROM地址以外的數(shù)值例如把滾動校驗數(shù)據(jù)也當(dāng)成了記錄起點就會導(dǎo)致每次寫入都產(chǎn)生大量空洞。解決應(yīng)用補丁前必須做雙重校驗——先檢查文件長度再檢查記錄中最大偏移是否超過ROM末尾。引擎里的越界檢查代碼會在寫入前把所有記錄的offset length與文件大小比較一旦越界馬上中止并恢復(fù)備份。5.2 GTK回調(diào)內(nèi)拿到的控件指針是NULL現(xiàn)象點擊按鈕時程序直接段錯誤退出gdb回溯發(fā)現(xiàn)是某個控件上調(diào)用了gtk_widget_get_*。原因Glade文件里的控件ID拼寫錯誤gtk_builder_get_object返回了NULL但.glade文件中同一ID在后續(xù)又被定義了一次Builder沒有報錯而是靜默返回最后一次實例。這類錯誤常見的玄學(xué)之處在于日志區(qū)按鈕正常而文件選擇按鈕直接崩潰因為兩個控件ID的起名風(fēng)格太接近。解決所有控件ID統(tǒng)一在resource.h中定義編譯期常量不再在C代碼里寫字符串字面量。同時增加一個開發(fā)模式加載Glade文件后遍歷檢查每個常量的get_object返回值是否為NULL發(fā)現(xiàn)NULL立即在日志區(qū)輸出紅色錯誤提示。從那以后我每次新增控件都把id常量放到位強制編譯期檢查。5.3 EOF標記誤觸發(fā)導(dǎo)致補丁提前結(jié)束現(xiàn)象補丁文件明明包含后續(xù)記錄但程序只應(yīng)用了一部分剩余記錄被靜默忽略。原因有個別補丁生成工具把三條連續(xù)字節(jié)E O F作為普通數(shù)據(jù)寫進了某個記錄的同一位次而我的解析循環(huán)判斷EOF的時機過早——它在讀取記錄頭部三字節(jié)后直接比對沒有先判斷當(dāng)前處于“數(shù)據(jù)區(qū)”還是“頭部區(qū)”。數(shù)據(jù)區(qū)內(nèi)部可能天然出現(xiàn)這三個ASCII字符。解決解析循環(huán)把“識別文件流當(dāng)前位置”和“讀取頭部”拆成兩步只有在每次讀取頭部之前才進行EOF判斷。修正后的循環(huán)把read邏輯與EOF判定放在同一個循環(huán)體頂部避免數(shù)據(jù)區(qū)內(nèi)的EOF字節(jié)干擾。5.4 Windows下原文件無法重命名現(xiàn)象在Windows上點擊“恢復(fù)備份”時操作系統(tǒng)提示文件正在被另一個進程使用無法覆蓋原文件。原因補丁應(yīng)用完成后fstream雖然調(diào)用了close()但在異常路徑上忘記關(guān)閉文件流。例如在應(yīng)用過程中有一條記錄發(fā)生越界檢查異常函數(shù)直接返回false而沒有走到rom.close()那一行。Windows對打開的文件句柄有強制寫保護導(dǎo)致后續(xù)備份恢復(fù)失敗。解決所有文件流都使用RAII確保離開作用域即關(guān)閉不再依賴手動close()。std::fstream的析構(gòu)函數(shù)會自動釋放句柄所以把代碼改成不顯式調(diào)用close()依賴局部變量生命周期管理。這條血淚經(jīng)驗后來我用在項目所有文件操作上沒再出過同類問題。5.5 補丁應(yīng)用一半突然斷電導(dǎo)致文件損壞現(xiàn)象進程被強制結(jié)束后ROM文件長度停留在某個中間值后續(xù)字節(jié)全部丟失。原因?qū)懭雴螚l記錄后雖然調(diào)用了flush()但操作系統(tǒng)層面的頁面緩存還沒來得及落盤斷電就帶來文件截斷。這與其說是代碼bug不如說是強殺路徑預(yù)留不足。解決在“應(yīng)用補丁”和“生成補丁”前把備份文件寫入同一個磁盤分區(qū)但不在同目錄防止目錄項損壞時備份一起消失。寫入完所有記錄后再調(diào)一次fsync級別的落盤接口GTK跨平臺下直接調(diào)用fflush并重新打開文件確認長度一致不一致則在日志區(qū)報錯并引導(dǎo)用戶手動恢復(fù)備份。6. 二次開發(fā)把補丁引擎改造成支持多格式的通用工具最后一章落在“怎么改”。當(dāng)前引擎只處理IPS格式但現(xiàn)代ROM社區(qū)常用的BPS格式在一些場景下壓縮率更高、支持文件截斷。把engine層抽象出補丁格式接口是相對價值高的一個改造方向。改造點主要是給PatchEngine增加格式虛函數(shù)接口。IPS與BPS的差異在于BPS是變長整數(shù)編碼加校驗和但兩者都有“解析記錄”“應(yīng)用記錄”“生成記錄”三個生命周期。我把現(xiàn)有代碼的重構(gòu)思路寫出來class IFormatHandler { public: virtual ~IFormatHandler() default; virtual bool parse(const std::string patchPath, std::vectorPatchRecord out) 0; virtual bool apply(const std::string romPath, const std::vectorPatchRecord records, std::string log) 0; virtual bool generate(const std::string origPath, const std::string modPath, const std::string outPatchPath) 0; }; class IpsHandler : public IFormatHandler { // 現(xiàn)有實現(xiàn)原樣遷入 }; class BpsHandler : public IFormatHandler { // BPS解析與生成邏輯 };然后MainWindow根據(jù)補丁文件后綴選擇handler.ips走IpsHandler.bps走BpsHandler。新增格式時只需要添加新的子類實現(xiàn)不需要動窗口代碼。驗證方式給tests/fixtures目錄新增一個BPS樣例文件測試用例寫兩輪——第一輪用IpsHandler做了一遍第二輪用BpsHandler跑一遍然后斷言兩次應(yīng)用結(jié)果的文件哈希完全一致。這樣保證“應(yīng)用-驗證”閉環(huán)在不同格式下輸出一致。實際改這段代碼時我最深的體會是當(dāng)初把引擎與GUI分成兩個目標編譯是值得的。測試BPS格式時完全沒碰GTK相關(guān)庫在命令行下直接跑測試程序幾十毫秒就得到結(jié)果。反觀早期版本把引擎函數(shù)全部塞在main_window.cpp里要驗證格式改動就得開著窗口點半天按鈕效率完全不在一個量級。從那以后我再設(shè)計這類工具時都先強制定好純邏輯層與界面層的邊界再動手寫第一行代碼。希望這篇拆解能幫你在自己的項目里少走一段彎路。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
色情五月天婷婷| 亚洲男人的天堂婷婷色五月| 强辱丰满人妻HD中文字幕| 九九99在线观看视频| www激情| 久久精品视频9| 九月激情综合| 丁香五月成人社区| 99热99网| 色综合久久天天综合网| 综合精品99| 五月丁香六月婷综合成人综合| 欧美六月| 碰碰操91| 香蕉色色网| 欧美日韩99| 九九色视频| 丁香五月天网站| 五月天婷婷网站| 五月婷在线观看| 国产裸舞表演WWWW| 久热99中文字幕| PORNY九色9l自拍视频成人| 成人色情五月天婷婷丁香| 五月间天堂综合| 男女啪啪做爰高潮无遮挡| 日日噜噜夜夜狠狠久久丁香六月| 丁香六月天堂| 婷婷激情五月天亚洲综合| 97干欧美| 97干欧美| 激情文学第四色婷婷丁香五月| 日本猛少妇色XXXXX猛叫| 99视频| 这里只有精品日韩精品| 99热99成人| 婷婷五月天中文字幕| 色色欧美色色色| 五月丁香六月激情在线| 99热免费观看| 99热精品在线观看| 五月色网| 久草婷婷| 丰满少妇猛烈A片免费看观看 | 婷婷五月欧美综合| 日本啪啪视频HD| 婷婷五月丁香综合| 美国十月色婷婷在线观看| 丁香花五月天| 狠狠干青青草| 婷婷五月深爱五月| 婷婷五月天天天| 九色色| 99久久思思| 殴美日韩成人| 99在线视频精品| 91亚洲天堂| 人操91在线| www99精品在线观看| 四川BBB搡BBB爽爽视频| ai97re99一本| 婷婷五月天大香蕉| 99久久久免费| 婷婷五月综合婷婷| 天天操夜夜夜拍拍拍| 99精品视频免费在线播放| 二色AV| 色婷婷9| 天天综合久久| 国产精品大香蕉| 丁香五月婷婷超碰在线| 激情五月天在线观看色婷婷| 婷婷激情啪啪| 五月丁香婷婷婷激情爱爱| 五月天天天色| 色综合丁香| 99九九热在线观看| 久热91| 啪啪啪啪五月天| 五月激情丁香久久综合网| 日本色频| 狠狠草综合网| AV操逼网| 色婷婷丁香A片区毛片区女人区| 97人人草| 婷婷综合偷拍| 久久久久久久丁香五月天婷婷| 亚洲国产精品成人免费一区久久久在线观看AAAA | a九九热www| 9久国产精品| 久九色| WWW.天天日| 五月丁香成人网| 五月六月丁香激情视频| 婷婷色爱| 天天干天天操天天拍| 无码人妻少妇色欲AV一区二区 | 99爱在线免费视频| 久久探花91swag| 久久五月天丁香花| 色,激情五月天| 五月天开心婷婷久久| 色婷婷五月天综合网| 综合激情深爱| 99热这里只有精品中文字幕| 特黄三级又爽又粗又大| 99热九九这里只有精品| 国熟女视频| 丁香婷婷色情社区成人小说| 99热这里有精力| av九九| 亚洲日韩成人三级av| 天天日夜夜帕| 99∨VTV| 五月丁香六月激情网站| 天天综合情| 日本激情五月| 欧美精品999| 五月婷婷综合在线视频| 天天天天天天天干| 婷婷综合97| 91欧美| 禁片二区| 视频免费精品免费精品免费精品免费精品免费精品免费精品免费99 | 97精品人人A片免费看| 黄色AAAA韩国guochansanji| 六月婷婷网| 久久久五月四色| 五月丁香啪啪综合| 日韩久综合| 立川无码av| 亚洲va欧洲va国产va不卡| 天天综合在线网| 色色五月天 亚洲| www.色五月.com| 婷婷丁香五月天亚洲| 超碰在线人妻| 91日本在线| 91妻人人爽人人看片| 性热视频99精品| 天天综合情| 婷婷六月丁香欧美视频在线| 色婷婷激情五月天丁香| 亚洲AV激情五月综合网| 成人丁香五月| 亚洲av成人在线| 五月天俺去也| 国产人妻777人伦精品HD| www激情网站| 国产综合激情五月久久| 女人天堂AV| 久久香蕉婷婷| 99热精品在这里| 免费看成人AA片无码视频吃奶| 日本三久久| 精品A√| 99网| 九九草热在线观看| 99色视频| 熟女乱论网| 婷婷五月天视频免费在线观看| 亚洲中字AV电影在线网站| 91精品国产91久久久久青草| 久久精品4| 色色97丁香婷婷五月天| 97婷婷五月| 裸体做A爰片毛片A片免费| 五月久久婷婷丁香| 色综合久久99色| 久热免费视频| 色婷婷丁香综合中文字幕| 五月天综合视频| 精品人妻午夜一区二区三区四区| 五月天小说激情| 婷婷月综合| 亚洲AV永久无码影院黑人| 色五月天成人在线| 久久ri精品| 天堂五月婷婷| 1024国产在线| 日韩视频99| 1024成人免费看| 九九久久五月天综合伊人| 国产精品美女久久久久AV超清| 亚洲天堂热| 玖玖在线视| 97久久五月丁香婷婷| 夜夜干夜夜操| 五月丁香欧美综合| 久久久久久人妻| 人妻久久久久| 午夜精品久久久久久久爽| 青青热久久综合| 丁香五月影院| 淑女丝袜bi操逼123| 啪啪五月婷婷| 26uuu欧美| 99精品视频推荐| 婷婷刺激综合| 超碰在线免费观看日韩| 婷婷六月激情综合| 51成人| 大香蕉啪啪| 97丁香婷婷| 超碰超碰在线| 婷婷激情六月中文| 黄色99热| 日本久久天堂| 思思re视频在线| 伊人在线大香蕉网| 国产欧美第五十五页| 五月丁香婷婷在线| 610018岁成人视频| 婷婷内射视频在线| 99人这里只有精品| www综合久久| 99九九精品视频| 99性视频| 99色在线视频| 丁香六月婷婷色XXXXX| 久久综合伊人77777蜜臀| 色色五月天网站| 亚洲综合在线视频| 婷婷五月花| 五月婷婷色吧!| 91视频久久久| 专区无日本视频高清8| 影音先锋 婷婷| √天堂资源在线人妻熟女| 99精品在线| 久久精品国产精品| ww久久| 五月激情综合婷婷| www.久久爱.com| 色情综合| 狠狠爱婷婷丁香| 欧美激情五月天婷婷| 久久五月丁香综合| 亚洲超碰在线| 夜夜爱伊人| 五月色婷婷综合丁香精品无遮挡| 五月婷婷激情性爱| 婷婷五月色花丁香社区| 蜜臀AV在线观看| 久久天天| 激情婷婷五月天在线观看| 韩国19 主播内部福利vip免费播放| 99热在线观看| 久久3p| 久久香蕉婷婷五月天| 免费看片操逼| 狠狠婷婷色综合| 超碰猛烈的性猛交| 丁香激情五月少妇| 亚洲无码成人性爰网| 婷婷综合97| 99年操人人爽| 97热这里精品在线视频| 99热这里只有精品最新网址| 激情的五月| 97婷婷丁香| 婷婷丁香中文字幕| 久久久GOGO无码啪啪艺术 | 婷婷丁香红五月91C| 欧美视频五区| 欧美日本另类| 久久黄色片| 99热6这里只有精品6| 色五月婷婷自拍| 丁香五月天堂婷婷| 99国产精品白浆在线观看免费| 亚洲色图五月丁香| 天天色天天日| 丁香涩涩五月天| 91狠狠综合久久| 91在线观看www| 国产毛片精品一区二区色欲黄A片| 国产激情综合五月久久| 99亚洲精品| 精品色色色| 日本va网站| 热中文字幕| 色五月婷婷影院| 色综合女人99| 五月婷久久综合| 久久性综合| 久久丁香五月婷婷| 亚洲激情在线| 狼人久草| 日本欧美在线| se99视频| www婷婷| 国产成人AV在线| 亚洲激情另类| 亚洲婷婷基地| 狠狠人妻色综合| 99免费视频| WWW,婷婷,COM| 亚洲热热视频| 99热只有| 亚洲啪视频| 99国产精品久久久久久久久久久| 婷婷六月色| 99热97| av性爱网站| 色婷婷在线视频综合| 激情五月无码| 这里只有精品久| 内射激情在线| 伍月婷婷六月丁香| 激情综合另类| 色色色色综合| 97操视频| 99热综合| 26uuu色五月| 香蕉99网| 九九热大香蕉| 五月色婷婷影视在线电影| 六月婷婷网| 99久久黄色顶级视频| 亚州激情网| 五月天婷婷黄色视频| 日日操夜夜爽白洁| 五月天成人在线播放丁香| www.激情五月天com| 丁香五月婷婷欧美成人色图| 97色在线观看视频| 日韩无码专区| 婷婷色综合网日韩国产| 久99久视频免费观看| 热久国产| 五月天综合区| 激情综合五| 五月婷婷丁香综合| 91av传媒高清在线视频网| 极品精品一区二区三区在线| www.婷婷,com| 婷婷五月综合欧美在线播放| 久久久久久久久人妻| 天天综合精品| 婷婷伊人綜合中文字幕| AV在线不卡网站| 日韩精品超碰在线观看| 77799热| 色丁香婷婷美女视频网站| 婷婷丁香五月高清| 丁香五月六月| 婷婷五月天首页激情| 久久丁香五月| 婷婷激情5月| 色五月大| 大地9中文在线观看免费高清| 97超碰,人人舔,人人操,人人摸 | 国产精品久久久久久喷浆| 九九久久腿| 综合久久六月| 五月婷婷激情综合在线| 婷婷五月天伊人网| 色婷婷av在线观看| 第四色大香蕉| 丁香六月天色婷婷| 激情亚洲网| 嫩草AV久久伊人妇女超级A| 啪啪东京热| 五月亭亭六月色| 狠狠五月激情丁香六月| www.狠狠| 综合激情在线| 五月六月婷| 99性爱视频| 97偷拍在线视频| 激情五月天黄色小说| 这里只有精品视频一区| 99这里| 9色小视频在线观看| 99久久99久久综合| 99热成人| 91丁香色五月| 久久杏爱视频| 亚洲九九夜夜| 亚洲狠狠婷婷| 丁香美女主播视频在线观看| 狠狠干综合| 五月开心久久| 五月丁香六月激情综合欧美| 国产精品VIDEOSSEX久久发布| 婷婷五月无码| 久8色色| 天天操天天操天天操天天操天天操| 久久免费干| 狠狠五月丁香色婷| 天天插天天射| 久99| 中文字幕av久久爽一区| 久久婷婷亚洲无码一起| 99综合激情久久精品久久| 亚洲色婷婷| 9视频1在线| 五月天婷婷青青草| 久久AV无码精品人妻系列试探| 国产免费AV网站| 79精品视频在线观看,| 欧美性生交xXxX久久久| 五月综合婷婷网| 丁香五月成人社区| 综合久久9| 久色视频| 伊人热婷婷| 国产婷婷五月天| 国产精品美女久久久久AV超清| 人妻熟女一区二区AV| 那里有AV网址| 99热8| 欧洲不卡视频| 久久综合激情| 五月丁香999| 色99热| 五月天婷婷爱| 亚洲AV永久无码影院黑人| 色综合日日| 国产伦亲子伦亲子视频观看| 亚洲人妻一区二区| 亚洲视频综合网| 激情纯色婷婷五月天在线不卡视频| 久久这里只有精品热在99| 97色片| www.91在线观看| 1区2区视频| 六月色播| 狠狠色五月| 色婷另类| 激情五月天色色| 香蕉久久国产AV一区二区| 久99久在线| 九九综合九九| 狠狠色婷婷7| 五月天啪啪| 97久久人人人干| 婷婷久久五月丁香| 婷婷亚洲色| 全国最新疫情| 婷婷五月娱乐在线| 狠狠色97| 久久五月丁香伊人青草| 五月丁香婷婷欧美色图视频五月丁香777电影 | 五月噜噜| 无码人妻一区二区一牛影视| 久久婷婷亚洲| 综合婷婷| 亚洲精品无码99热| 亚洲六月婷婷| 久久五月婷婷电影| 搡BBBB搡BBB搡18 | 97色色色色色| 大香蕉五月天婷婷| 国产肥白大熟妇BBBB视频| 99视频这里只有久久精品 | 亚洲精品性色| 亚洲无码另类| 五月丁香婷婷激情| 亚洲爱婷婷| 日韩啪啪视频| 五月天伊人日日噜影片AV| 久综合九综合99| 五月丁香在线| 亚洲精99| 久热久操久热久草国产91| www.henhenl| 五月天激情网址| 丁香五月人妻| 色吧五月婷婷| 26uuu视频欧美| 激情小说色五月| www.99热在线| 欧美黑人巨大猛烈cuckold| 亚洲国产色婷婷| 丁香五月婷婷超碰在线| 五月天欧美激情| 99re在线免费视频| 97人人射| 色色色网站| 人妻久久久久久久久妻久久久久久久久| 99ER热精品视频| 亚洲色热| 九九热区一区二区三区| 久久久激情视频| 国产AV影片| 久久精品夜色噜噜亚洲a∨| 五月丁香色婷婷伊人| 狼人伊人干| 五月天综合| 亚州日本欧州韩美高青高潮一| 2020日日干| 亚洲亚洲人成综合网络| 色婷婷亚洲婷婷| 国色天香伊人狠狠色| 丁香花五月天激情| 影院久久久| 五月婷婷激情综合| 国产婷婷综合| 99免费热视频| 人妻videos人妻高清| 日韩黄色网络| 97人人操人人拍| 成片免费观看视频大全| 大香蕉婷婷五月| 久久久人妻系列| 六月亚洲婷婷6月中文字幕| 99热99在线精品| 极品人妻VIDEOSSS人妻| 激情五月天色色网| 91精品久久久久| 五月丁香色| 99er这里只有精品| 97艹| 猫咪伊人AV| 色色操| 老司机伊人| 精品综合久久久久久五月天| 天天情天天狠天天透| 九九99男女视频在线观看| 丁香五月之久操视频| 久热这里只有| 玖玖综合色| 婷婷五月天六月丁香| 综合五月天亚洲婷婷| 久久久久久久久久91| 一区=区操屄高清大全av| 最近韩国日本免费高清观看| 久久久久久久久久8888| 中文字幕在线不卡| 大香蕉五月婷婷| 五月激情站| 深夜A片| 天天日,夜夜爽| 99日韩| 婷婷久久丁香五月| 美腿丝袜AV天堂网| 五月天婷婷久草丁香| 玖久久网站| 丰满少妇乱A片无码| 日日干日日| 日本99视频| 六月婷婷综合| 丁香六月婷| 久久婷狠狠色| 九热...av| 五月天操逼网| WWW久久久| 色碰碰视频| 噜噜狠狠色综合久| 日本在线视频播放91| 这里有精品| 极品人妻VideOssS人妻| 婷婷色在线视频| 日本狠狠干| 五月天开心网| 亚洲综合视频在线| 六月婷婷五月丁香| 丰满人妻妇伦又伦精品国产| 五月丁香综合在线| 欧洲色区| 精品9久| 7777久久亚洲中文字幕| 999精品久久久久久久| 俺去婷婷 丁香| 九月综合| 色偷偷五月天| 荫道BBWBBB高潮潮喷| 香蕉久久av一区二区三区| 久久久国产精品黄毛片| 婷婷五月天大香蕉在线视频观看| 婷婷五月色情| 六月丁香婷婷五月天| 26UUU成人网| 久久99热 这里有精品| 婷婷深爱五月丁香网| 79色色色色| www.久热| 96丁香六月婷婷蜜桃综合久久| 五月天婷婷久久| 变态 另类 在线 | 91婷婷五月天嫩女| 99综合久久| 六月丁香网| 伊人网色婷婷五月天| 日韩久久欧亚| 五月天综合在线| 六月激情婷婷综合| 五月天婷婷激情在线色图| 五月丁香777| 在线日韩视频| 亚洲九九99精品视频在线播放| 婷婷第一页| www久久99| 五月色情网| 亚洲视频色婷婷| 激情五月天丁香| 日韩黄在免| 五月天停停日日| 五月婷婷丁香深深爱| 久久这里只有精品视频1| 久久免费操| 精品国产AV色一区二区深夜久久| 色婷婷综合电影| 成人五月天在线观看| 色色丁香激情五月| 婷婷五月综合激情| 九九久久污| 天天摸.天天mo| 五月婷婷中文字幕| 手机激情网| www,色婷婷| 思思99热| 视频一二区| 操操操av| 九九99九九99九九99视频网| 波多野结衣不卡AV| 涩综合在线| 播五月开心婷婷欧美综合| 久操婷婷| 精品一区二区三区三区| 色播五月丁香婷婷| 欧美婷婷| 吊色AV男人的天堂| 日日爽天天| 色色婷婷五月天| 婷婷五月色惰| 激情网婷婷婷| 嫩BBB槡BBBB搡BBBB| 欧美性猛交99久久久99| 激情婷婷网| 婷婷激情五月| 欧美va视频| 久久精品只有这| 嫩BBB搡BBBB榛BBBB| 婷婷五月丁香久久| 这里只有精品免费| 亚洲av电影在线| 天天干狠狠操| 99热| 另类视频一区| 久久婷婷国产| 伊人久久大香线蕉综合网站| www.六月丁香看AV| 成人午夜天| 丁香婷婷六月激情文学| 色停停香蕉视频| 中文字幕婷婷在线| 亚城区在线| 亚洲偷| 婷婷六月综合在线| 伊人久久婷婷| 国产在线黄色| 超碰免费大香蕉| 久久99热网| www.99热国产| 色五月婷婷视频| 超碰精品在线| 色五月无码| 99色综合| 99热只有精品在线播放| 热99在线精品| 五月丁香少妇| 色婷久九| 99精品自拍视频| 超碰97干| 丁香五月激情啪啪| 色情五月婷婷| 性色人人爽| 99热婷婷| 开心 五月 综合| 色婷婷狠狠| 视色网在线播放| 中国女人做爰A片| 欧美天天干五月丁香| 成人av免费观看| 91超碰人人操| 俺去也五月天| 深爱激情AV| 亚洲亚洲人成综合网络| 安息电影在线观看完整版| 成人丁香五月| www.六月丁香看AV| www.五月婷| 99资源在线视频| 久久性操| 五月天婷婷影院| 丁香五月天激情AV| 嫩草极品| 一起草性爱不卡视频| 99热碰碰| 天天爱天天秀天天做| 97视频.干com| 人妻AV在线| 国产日批视频免费播放| 免费观看欧美成人AA片爱我多深| 乱色色色| 日本久久婷婷| 五月婷婷激情网| 五月激情综合深爱| 色综合中文色综合网| 特级西西4444www无码| 开心久久爱五月天| 黄页免费一级视频懂色| 丁香五月激情婷婷| 99aese| 六月丁香成人| 亭亭玉月丁香| 天天天天天久久久久久| 五月婷婷AV| 91婷婷五月天综合视频| 99久热精品在线| 婷婷五月天成人网| 婷婷五月天啪啪| 91热99| 亚洲乱码日产精品BD| 五月天 无码| site:xiongshengzz.com| 五月天婷婷色播综合在线| 激情五月婷婷| 九九热在线观看视频网站| aaa9区免费在线观看| 亚洲啪啪视频| 互月天综合| 婷综合| 伊久大香蕉| 久热欧美| 婷婷中文字暮| 深爱丁香网| 99视频在线啪| 白人荫道BBWBBB大荫道| 日本一级特黄大片AAAAA级| 婷婷色香六月综合激情| 成人电影在线免费试看| 婷婷五月天国产传媒| 婷婷五月天堂| 亚洲天堂aaa| 99久久丝| 超碰国产在线观看| 亚洲乱码日产精品BD| 综合激情在线视频| 思思热99在线视频| 精品在线| 激情性爱五月| 日韩欧美性爱| 无码人妻AV久久久一区二区三区| 麻豆雪千夏| 久久亚洲婷婷| 99re在线观看视频| 97操在线视频| 热久69| 97色射| 五月天激情婷婷| 丁香婷婷六月| 婷婷夜夜操| 狠狠干在线视频| 五月婷婷综合网| 欧美日韩五月婷婷| 久久久aaa| 国产日韩精品SUV| 99热思思| 亚洲日韩欧美综合VA| ss99热| 六月亚洲婷婷6月中文字幕| 日本在线99| 久久天堂女人| 丁香五月婷婷av影院| 九九Av| 思思热视频在线观看| 成人av在线网址| 天天操人人干| 婷婷久久亚洲| 婷婷五月天激情影片| 天天做天天爱天天爽在| 久久综合激情五月天| 超碰操网| 激情久久久久久| 久久性刺激| 东北黄色一级| 97在线日本| 丁香五月天婷婷大香蕉| 碰碰碰碰碰99| 亚洲AV成人在线观看| 日韩乱轮AV| 丁香五月狠狠在线观看| 欧美性爱专区| 国产婷婷五月| 91日日日| 九九色精品| 综合五月草| 成人欧美一区二区三区在线观看| 五月丁激情| m色激情网| 五月天婷婷在线AN| 婷婷在线视频| 九色PORNY9l原创自拍| 激情五月小说婷婷| 欧美这里只有精品| 欧美 日韩 成人| 伊人玖玖网| 色哟哟精品| 午夜丁香| 日韩啪啪视频| 无码AV免费精品一区二区三区| 农村熟妇高潮精品A片| 欧美性生交XXXXX无码小说| 天天爱天天操| 激情婷婷| 亚洲精品成人| 久久丁香五月婷婷| 国产午夜精品AV一区二区麻豆| 色青青电影色五月| 97人人干。| 日韩精品一区二区亚洲AV观看| 婷婷五月激情欧美| site:xmssd.com| 激情小说五月天中文字幕| 天天舔天天摸天天射| 五月婷婷丁香六月在线| 五月婷婷色五月| 91婷色| 精品久热| 国产免费性爱| 综合色婷婷| 日韩成人电影AV| 99久久国产成人精品| 婷婷深爱网| 99热这里只有在线| 66色在线日韩| 五月激情小说| 丁香五月婷婷婷桃花影院| 色999亚洲人成色| 久久视频九九视频| 五月丁香 啪啪| 青青久在线视频免费观看| 欧美婷婷九月| 丁香五月天激情婷婷丁香六月| 久狠日av| 天天干天天拍| 欧美婷婷九月| 狠狠操天天操综合| 99在线免费视频| 欧美成人AAA片一区国产精品| 久热伊人9| 亚洲婷婷丁香五月天激情小说| 日韩aaa| 婷婷综合| www999日韩精品| 亚洲综合在线丁香五月| 六月丁香啪啪| 91热久| 国产激情综合五月| 影音先锋偷偷色男人站| 婷婷D区| 激情综合色网| 天天摸天天透天天舔| h在线看免费版在线看| 婷婷伊人75| 蜜桃婷婷丁香| www色色色com| 色噜噜狠狠色综合成人网| 99re在线这里只有精品视频首页| 99re思思久久| 婷婷色色欧美| 五月婷婷之美女图片| 午夜大香蕉| 大香蕉婷婷丁香视频在线| 午夜激情五月天| 国外亚洲成AV人片在线观看| 色色五月丁香婷婷| 五月天狠狠网| 婷婷丁香成人色综合| 激情5月舔| 五月色色网| 色色影院黄大片| 亚洲人成人五月天| 丁香五月花| 色五月婷婷五月丁香五月激情五月视频| 99热综合| 五月色婷婷夜色| 亚洲人妻一区二区 | 久狠狠狠| 九九成年视频| 丁香婷婷色五月合集| 色婷婷五月天| 2014天天爽| 成人日韩欧美| 五月婷网| 97碰| 91精品婷婷国产综合| 日韩无码色色| 丁香六月成人网| 综合伊人狠狠| 亚洲av另类在线观看| 色狠狠综合网| 强壮公让我夜夜高潮A片视频| 五月丁香婷婷综合| 五月丁香综合激情| 成人av在线网站| 五月天丁香婷婷社区| 久草九九| 亚洲免费观看高清完整版AV线| 91 九色 入口| 五月久久婷婷成人网| 国产婷婷久久| 中文av网| 天堂爱啪啪| 欧美性爱中文字幕| 久久丝袜婷婷| 五月丁香啪啪综合| 九九AV在线| 久久久97| 金桔一区二区ab地址| 天天草天天爽| 婷婷丁香五月天综合网| 777米奇影视第四色| 丁香花五月天| 成人五月天综合网| www.五月天社区| 99视频在线看| 91se在线观看| 色五月色五天色情网| 99爱在线精品视频免费观看| 桃色Av色哟哟| 国产真实乱了老女人视频| 亚洲五月婷天天操| 日韩AC在线免费观看| www色婷婷com| 天天综合五月天| 色播六月| 色五月涩涩婷婷蜜桃| 成人国产欧美大片一区| 六月婷婷亚洲| 五月婷婷九九热| 婷婷五月电影院| 丁香五月综合久久八| 国产精产国品一二三在观看| 丁香五月久久综合| 色婷婷综合在线| 色综合久久中文| 99开心五月五月丁香激情| 国产3p露脸普通话对白| 婷婷五月天欧美图片在线播放电驴| 色玖玖网| www狠狠| 丁香五月成人论坛| 伊人九九九久| 色色色国产| 大波美女VA网站| 91九色无码内射| 伊人久久艹| 丁香婷婷六月天| 国产综合丁香五月天| 九月婷婷久久| 色狠狠伊人久久五月丁香| 五月天婷婷网站| 91热在线| 精品99爱免费视频在线观看| 婷婷伊人綜合| AA丁香综合激情| 婷婷丁香五月天中文字幕| 玖玖午夜视频| 国外亚洲成AV人片在线观看| 久久久久久性爱视频| 午夜成人AV在线| 黄色片久久| 久9精品视频| 欧美综合丁香网| 日本免费91| 欧美成人AAA片一区国产精品| 五月丁香亚洲婷婷| 啪啪色激情五月天| WWW.五月com| 婷婷99| 天天干天天射综合网| 日韩成人网址| 狠狠爱丁香婷| 人妻少妇色综合| 欧美成人性爱网| 99热思思在线观看| 超碰人人99| 日韩av一区二区在线/日产精品久久久 | 色婷婷狠狠| 精品动漫 无码av| 久久99综合| 亚洲99在线| 午夜无码精品色综合久久| 色九月婷婷综合| 一起操最新网址| 91性高潮久久久久久久久| 五月天亚洲色| 五月综亚洲| 久久丁香五月婷婷| 无码一区二区三区四区五区91c| 丁香五月天激情综合| 亭亭五月丁香五月天激情| 综合狠狠五月婷婷| 日韩性视频| 亚洲AV永久无码影院黑人 | 五月婷婷伊人网| 日本在线视频www色| 久久激情婷婷| 亚洲12p| 婷婷激情小说| 综合性爱网| 五月天激情子轮| 加勒比色色| 色色五月婷婷| 午夜丁香综合婷婷| 超碰2021| 国产亚洲精品久久久久苍井松| www色色com| 婷婷五月在线观看| 久久思思精品| 久久伊人日日夜夜| 五月丁香怕啪啪| 国产激情AV| 五月婷婷|欧美| 欧美婷婷综合| 97碰碰久久| 最近免费中文字幕大全高清大全1| 日韩啪啪视频| 91视频精品99| 五月亭亭开心网| 99久久玖玖| 色性五月天| 欧洲综合视频在线观看。欧洲,亚洲综合食品在线观看。 | 久久综合网免费视频| 久久99婷婷| 婷婷五月大香蕉| 123草逼网| 啪啪六月婷婷| 婷婷丁香五月激情密臀av| 五月婷婷丁香综合,亚洲天堂| 色五月色综合| 天天干在线播放| 99丁香婷婷综合网| 中文字幕乱码亚洲精品一区| 色色亚洲| 成人精品一区日本无码网| 久久婷婷五月综合| 97色干| 婷婷五月天AV| 九九在线精品| 婷婷五月天成人| 中字幕视频在线永久在线观看免费| 五月婷婷影院| 99在线观看| 激情第四色| 99精品无码| 九九视频在线观看视频6 | 熟女少妇内射日韩亚洲| 少妇真实被内射视频三四区| 日本少妇裸体做爰高潮片| 亚洲精品一区中文字幕乱码| 性生生活大片又黄又| 色色色com| 99视频日韩| 久久婷婷五月激情综合| 丁香五月先锋| 午夜成人天堂久久无码日韩久久| 九九热黄色| site:hcxsz888.com| 韩国情人在线电视剧免费观看高清版全集 | 五月婷婷香蕉| 五月丁香另类网| 99热很操老逼| 六月婷基地| 中文无码婷婷| 综合五月丁香久久| 99色播| www.成人婷婷综合| www.色婷婷| 亚洲中文字幕av| 婷婷色五月激情| 久久久久久久11111111111| 99re资源在线视频导航| 黄色91在线观看| 综合久久97| 99er免费在线观看| 9久热这里只有精品| 亚洲另类视频| 久久综合干| 日本狠狠干| 久久综合55| 9久热免费视频99| 五月天婷综合网站| 天堂AV在线看| 激情AV在线| 国产亚洲在线| 色五月色开心开心五月| 婷婷色吧| 色五月丁香总合网| 狠狠插日日干撸| 婷婷五月色综合| 国产精产国品一二三在观看| 中文字幕综合色| 欧美久久婷婷| 国产一区男女| 色婷婷综合影院| 99久久婷婷国产综合精品草原| 99热最新国内| 色丁香五月天| 亚洲看av的网站| 婷婷丁香亚洲色综合91| 99无码视频| 亚洲成Av人片乱码色第1集| 欧美婷婷| 日操夜撸| 日本人妻A片成人免费看片| 亚洲熟妇AV乱码在线观看| 亚洲精品亚洲人成人网| 丁香婷婷色五月激情综合| 大香蕉在线99热| www.五月婷婷| 另类图片婷婷五月天| 91九色精品女同系列| 激情综合网激情五月婷婷| 久久九九玖玖| 深爱激情av| 色5月婷婷| 婷婷五月成人社区| 色五月激情视频在线综合| 久狠日av| 亚洲午夜av| 99色免费| 亚洲人人干| 伊人超碰| 潮汕成人AV片在线| 色五月xxx| 99热这里只有精品5| 嫩BBB搡BBBB榛BBBB| 色五月超碰| 五月亭亭综合五码| 五月丁香在线观看| 99伊人婷婷在线| 思思热性操| 日韩亚洲视频| 亚洲成人中文字幕| 亚洲瑟瑟精品在线| 九九热99热| 大香蕉伊在| 偷拍视频五月天| 五月丁香六月激情在线| 中文在线成人| 丁香婷婷六月在线资源观看| 国产超碰在线| 色五月婷婷7777| 五月丁香啪啪网| 激情五月天视频| 婷婷五月天天| 狠狠干五月天婷婷网| 亚洲秘 无码一区二区三区妃光/1| 国产成人AV不卡| 久热这里只有精品3| 欧美日韩成人在线观看| 五月婷婷亚洲综合在线 | 8050一级网| 日操| 91色婷婷综合久久中文字幕二区| 婷婷丁香色性爱| 丁香五月天啪啪激情综和网| 色五月激情综合网| 色色色婷婷五月天| 婷婷另类小说| 丁香五月ⅤA久久久| 五月婷丁香亚洲| 亚洲爆乳无码精品AAA片蜜桃| 久久xxxx| 中文字幕AV在线播放| 5五月综合网亚洲| 思思精品热在线| 极骚大香蕉伊人| 森林影视大全,最好看的2019年视频 | 久青草影院| 亚洲精品网站色视频| 九热视频| 五月丁香久久综合| 操操国产| 玖玖激情五月天| 日日操夜夜爽| 久久aaaaa| 天天摸天天做天天爱天天爽| 伊人大香蕉爱聚| 操啊操av| 久久密臀婷婷| 俺去啦综合网| 欧美三级韩国三级日本三斤| 婷婷五月色网| 黃色三级三级三级三级 qixing300.shrkbk.com www.jinbozs.com tianmiaosw.com | 97影院一级片| 日韩啪| 五月婷婷狠狠干| www.五月婷婷久久.com| 九九99九九99| 色啪综合| 人妻久久久久| 激情九月婷婷| 日韩黄黄| 亚洲乱码日产精品BD| 涩涩婷婷五月| 思思热99er| 99A片| 98永久精品| 91丨九色丨丰满人妖| 婷婷五月电影院| 99精品色| 九九成人高清视频| 国产熟妇乱子伦hd| 久久这里有精品视频在线免费观看| 九九热狼人| 五月天激情www| 99在线热视频| 欧美内射AA| 激情婷婷色小说| 五月J香蕉婷婷| 26UUU欧美| 天天肏高清在线| 色色五月婷| site:esunnet.com| 狠狠一日| 人人草人人看| 97色婷婷成人综合在线观看| 99ri视频| 开心五月婷| 激情图片婷婷丁香五月| 第四色激情网| 亚洲天堂AV免费片| 伊人九九68| 操逼巨乳91| 亚洲激情亚洲激情 | 另类天堂| 人妻肉射免费观看| WWW.久久久久久久久久久久久| 九九精品综合| 日本色婷婷五月天成人电影| 久久婷婷网址| 情色婷婷五月天| 免费AV黄在线播放| 丁香五月色激情| 天天操婷婷| 亚洲天堂AV免费片| 色色97丁香婷婷五月天| 婷婷欧美综合| 丁六月激情| 一起操 91N.com| 色吧综合网| 99精品爱| 成人一级片| 亚洲精品久久久久久久久久吃药| 韩国天天婷婷| 亚洲久热| 激情五月婷婷色综合| 丁香色五月 97干| 日韩激情人伦人| 久久久久99精品成人网站| 超碰av在线| 国产午夜一区二区三区| 色婷婷狠狠| 亚洲区1| 可以看的av网站| 婷婷噜噜| 青青操绿aaa一区日v| 九九偷拍网| 欧美交换配乱吟粗大25P|