99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

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
返回資訊列表
99这里只有精品| 亚洲一区二区无遮挡A片| 99精品偷自拍| 色色狼人综合| 色丁香五月天婷婷| 五月激情四射婷婷丁香| 九九久久99精品免费观看www| 国产精品国产成人国产三级| 色色五月天婷婷丁香| 久久久久亚洲A∨成人乱码电影| 丁香8月手机综合| 婷婷丁香色情| 婷婷色片| 五月婷婷,狠狠操| 五月丁香六月婷婷a v| 五月丁香激情综合啪啪| 九九九九九九九九九九九九九国产精品| 4399亚洲视频| 久9精品视频| 丁香色五月婷婷91桃色| 五月六月激情婷婷| 五月天婷婷丁香花| 极品 少妇 内射| 五月丁香婷婷色色| 夜夜 操无码| 国产色色小草视频| 成人国产网| 狠狠色噜噜狠狠狠888| 五月天婷综合| 国産精品| AV人人操| 一起草av| 亚洲乱码日产精品BD| 狠狠色丁香| 色色色色色色色色网站| 成人丁香婷婷| 婷婷五月情天| 丁香五月婷婷综合精品素人| 婷婷六月天| 97婷婷五月| 69五月天视频| 激情久久综合网| 九九热99精品| 99成人免费热视频| 99人妻碰碰碰久久久久视| 色人妻五月| 五月丁香激情在线| 狠狠操天天干| 涩涩涩五月天| 婷婷五月天天| 久久综合网桃花| 婷婷天堂综合网| 亚洲成人日韩无码精品| 国产免费av在线| 日本情色一区二区| 大香蕉久久| 狠狠舔| 激情久久久久久| 97丁香五月| 亲子乱AV一区二区三区下载| 包操45分钟网站| 99'无码| 91碰碰| 婷婷色激情网| 丁香五月综合在线观看| 人妻激情综合| 亚洲综合五月天婷婷丁香| 五月天综合| 综合婷婷| www.日本91| 色偷偷五月天| 色色色五月婷婷| 伊人久久艹| 欧美精品中文字幕亚洲专区| 婷婷五月六月丁香| 五月亭亭六月色| 五月丁香色婷婷伊人| 日韩五月天婷婷| 五月婷婷婷婷婷婷艺术| 99久久玖玖| 欧美色图天堂网| 亚洲激情网| 国产偷人爽久久久久久老妇APP| 九九色婷| 天天插天天插天天操| 26uuu色噜噜精品一区| 日本在线视频手机播放五月婷| caopeng97日韩| 五月丁香婷婷成人综合网| 五月天婷婷AV| 色综合色香蕉网| 五月婷婷婷| 久久伊人五月天| 免费观看全黄做爰的视频| 99天天操夜夜操| 婷婷九九视频| 五月天婷婷乱| 精品色色| 色三级色三级| 在线综合网| 五月激情视频| 九九热在线视频观看免费10| 夜夜操少妇| 91久久久久久久| 免费观看的av| 噜噜噜噜综合在线| 免费精品99| 丁香婷婷五月| 97在线精品| 五月天俺去也| 第四色网婷婷| eeuus五月婷| 逼逼AV| 蜜乳av一级av| 99综合| 九九热视频免费观看| 婷婷五月情天| AV中文网| 婷婷另类开心| www.zbzhongsen.com| 免费成人中文字幕| 婷婷五月色综合| 午夜成人网站在线观看| 99热欲| 丁香五月天激情婷婷丁香六月 | 日韩成人五月天| 激情五月天激情小说| 色五月综合网| 情情五月天色| 少妇性BBB搡BBB爽爽爽视頻| 五月婷婷亚洲综合网| 久久综合影院 | 91高潮喷水久久久久久久久| 五月婷婷九| jiZZdr| 大香蕉人在线65| 丁香婷婷五月基地| 亚洲性爱AV| 99热九九在线| 亚洲传媒在线观看| 丁香六月亚洲综合| 九九在线91| 激情五月天婷婷视频| 五月婷婷综合激情| 欧美噜噜免费观看| 操一区| 五月婷婷影院| 色色婷婷丁香| 99热在线观看| 九九视频精品在线免费| 好叼操在线观看| 思思久久思思| av超碰在线| 欧美激情综合色综合色| 狠狠综合久久综合| 综合激情在线| 婷婷欧美激情综合| 国产成人精品123区免费视频| 女性自慰系列第五页| www.婷婷五月天.com| 亚洲激情综| 色色99| 丁香五月欧美色综合| 夜夜干天天操| 超碰99在线观看| 99精品在这里| 日韩成人精品一区久久久久| 991自拍视频| Www.激情| 色色色色综合网| 久热人妻| 亚洲婷婷六月天| 天天日日夜夜爽。| AV在线观看网站| 天天摸天天肏| 亚洲AAAA网| AV亚洲在线| 精品久久这里热66| 日韩草草草草草草草草草草草草| 97日韩无套内| 五月久久婷婷天堂视频| 五月开心婷婷中文字幕| 亚洲一区二区色图-亚洲精品国产精品乱码-成人AV| 五月天婷婷免费视频| 欧美天堂久久| 国产成人精品一区二区三区视频| 色五月婷婷九月| 久久久婷婷婷| 丁香五月激情五月色综合| 99热这里只有精品 搜| 九九99视频精品| 五月婷婷六月丁香在线| 都市激情蜜桃婷婷五月天| 四川BBB搡BBB搡多人乱亂| 玖玖资源天天无码| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 九九热视频思思| 欧美精品A片一区在线观看| 婷婷大乡焦噜噜| 俺也去在线久久精品23欧美综合视频网站,丰满人妻一区二区三区在线视频53,丰满 | 9久久精品| 久99久热只有精品国产99| ztEJj| 九九精品亚洲| 亚洲色色色色| 婷婷五月激情热播| 69久久99精品久久久久| 99视频综合| 97精品综合久久| 提提热五月天婷婷| 那里有AV网址| 一起草无码| 国产成人精品一区二区三区视频| 五月丁香性爱| 99热这里只有精品9| 熟女乱论网| 日日干天天爽| 婷婷开心激情综合五月天| 日韩综合久| 色婷婷在线视频| 色五月婷婷影院| 天天综合亚洲综合网天天αⅴ| 婷婷天堂综合网| 激情五月久久| 婷婷五月天色色| 999热在线视频| 亚洲艹网| 激情五月综合| 大香蕉手机视频| 色播五月丁香综合| av五月丁香| 五月激情小说| 婷婷97狠狠成人网站| 色色色在线观看| 综合激情深爱| 五月丁香激情婷婷综合| 开心四月婷婷在线色播播| 免费97碰碰| 人妻无码视频网| www超碰| 在线中文字幕av| 99re最新地址| 亚洲婷婷免费| 六九色综合婷婷五月天| 久久小片| 五月天婷婷亚洲| 婷婷激情五月综合丁| 伊人青草成人| 五月亭亭激情综合| 人妻尝试久久久久久久久久久久| 五月四色色| 国产精品涩涩涩视频网站| 五月天色色网站| 狠狠色五月| 第五色婷婷| 丁香五月婷老师| 激情99在线视频| 五月天色婷婷基地| 婷婷王月天影院| 这里只有精品久| 天天色天天噜| 亚洲综合五月天婷婷| 天堂草在线看www| 日日操天天| 天天色综合综合| 亚洲久久婷婷| 婷婷五月天狠狠色| 色爱五月天| 99只有精品| 丁香五月电影| 激情五月婷婷色综合| 玖玖婷婷免费| 五月婷婷AV| 亚洲综合在线伊人婷| 日韩999| 超碰人人干| 亚洲成人在线播放| 天天碰天天插天天操| 九九色插| 激情床戏| 激情狠狠丁香月| 中文乱子伦视频| www.五月丁香| 天天日天天爽夜夜爽| 久久a热| 九热视频| 蜜乳人妻一区二区三区| 久久这里只有国产| 婷婷五月激情在线视频| 97人人干| 婷婷天天五月天| 97碰人人操| 国产亚洲99| 天天日人人| 99爱精品视频| 五月天色社区| 五月婷狠狠| 99热线观看9| 涩综合在线 | 五月婷婷影视| 五月丁香婷婷基地| 欧州色色| 香蕉AV777XXX色综合一区| 一区操| 婷婷色丁香五月| 成人婷婷深爱综合网| 婷婷自拍| 日韩按摩二区| 日韩中文欧美| 成人网站高清无码| 玖操97| 色色色综合| 伊人激情| 五月天丁香网站| 九九爱看亚洲| 超碰99在线| 97色精品视频| 色婷綜合网| 五月婷婷六月天| 疯狂做受XXXX高潮A片| 丁香婷婷午夜| 深爱五月最新网址| 天天射影院| 97碰碰视频在线观看免费| 26uuuavcom| 99视频自拍| 日韩1区2区| 99久热| 久久99网址| 99热12| 九九精品热| 99热爱爱干干日| 婷婷五月天激情基地| 九色婷婷| 激情五月开心五月在线视频| 成人婷99最新| 骚五月婷婷| 九九爱精品网站| 青草网在线观看| 欧美色五月| 亚洲午夜成人av电影网| 美女要搞搞天天搞搞搞网站| 91超级碰碰| 五月婷婷深深爱| 激情文学五月丁香六月婷婷| AV片在线观看| 丁香五月天天高清在线| 亚洲av电影网站| 婷婷五月天伦理| 色五月五月婷婷| 97色色婷婷五月天| 91丨九色丨高潮丰满日本| 亚洲欧美国产A片免费观看| 精品九九视频| 丁香五月婷婷免费视频| 区区欧美你爱| 91熟妇大香蕉| 激情综合五月开心狠狠| 大香蕉人在线65| 66成人网| 国产精品久久..4399| 天天综合五月天| 欧美婷婷丁香五月| 日韩精品一品二区三区的使用体验| 淫视馆av三区| 婷婷丁香18| 色色婷婷色色| 久久婷婷热| 午夜一区| 婷婷五月欧美综合| 国成人网| 2020日日干| av国产精品偷| 操骚货在线| 五月丁香 六月婷婷a| 精品人妻一区二区三区四区不卡在| 91丨九色丨丰满人妖| 久99视频在线观看| 五月婷婷就去色| 91av传媒高清在线视频网| 欧美丁香六月在线观看视频| 色五月综合网站| 天天干天天操天天拍| 91精品综合久久久久久五月天| 99日韩网站| 韩日AV片| 久久精品这里只有精品免费首页| www.婷婷五月天啪啪| 五月天丁香婷婷久久九| 99福利导航| 色性综合| 天天日P天天射P| 99这里只有精品| www婷婷| 丁香六月综合激情| 这里只有精品无码| 青青夜夜狠狠夜夜狠狠| 狠狠色丁香久久综合婷婷亚洲成人福利| 国产亚洲色婷婷久久99精品91 www.riverspirits.org www.hnnun.com www.changh | 色噜噜五月天| 欧美黑人巨大猛烈cuckold| 久久五月婷婷综合网| 婷婷五月天免费视频| www.婷婷六月天| 久久久五月天| 丁香五月婷婷偷拍| 丁香五月综合图片在线观看| Www99热| 婷婷成人基地| VA色婷婷| 99爱视频在线播放| 色黑鬼导航| 久久五月情| 99久久综合| 亚洲视色| 激情黄色五月天| 大香蕉人人人| 影音先锋秋秋五月婷婷| 天天操综合网| 婷婷刺激综合| www.av骚货| 婷香五月| 熟女91九色| 精品国产一区二区三区四区阿崩 | 九九99九九精品免费| 五月天色不卡| 9 7总站超级碰免费视频| 色色色干| 九九99久久| 婷婷五月天在线观看av| 99综合免费视频| 99re在线免费视频| 9999热免费视频视频| 九九热免费视频| 色色性爱视频| 色五狠狠| 99re这里有精品手机在线| 五月婷中文字幕| 五月婷婷久久网| 亚洲天堂久久| 欧美婷婷五月丁香| 色情五月丁香| 67194成I人在线观看线路1| 五月婷婷丁香综合网| 九月丁香婷婷综合激情| 大香蕉AV在线| 免费AAAAA网| 99碰网站| 91精品91久久久中77777久久玖玖九九| 婷婷无五月无码视频| 九九aV| 久久五月丁香婷婷| av网址在线| 人人摸人人澡人人| 天天操综合网| 日日夜夜干| 一起草性爱不卡视频| 玖久精品视频9| 九九视频在线观看视频6| 五月丁香成人网| AV九九| 日本超碰在线| 九九色热| 丁香色六月婷婷| 99热这里是精品| 男人操女人高潮91视频| 无码 av电影| 欧美成人猛片AAAAAAA| 狠狠操综合| 性爱视频99| 91狠狠色丁香婷婷综合久久| 丁香六月激情| 国产成人AV| 久在线88综合| 99热久久日本| 天天操无码| 粉嫩av蜜桃av蜜臀av| 五月婷精品| 香蕉久久国产AV一区二区| 九九AV在线| 天天射影| 人人干AV| 婷婷五月天av| 色情五月综合婷婷| 五月天丁香久久综合| 色欲AVV| 91免费试看| 婷婷五月天丁香激情| 蜜桃婷婷狠狠久久| 天天爽成人综合网站| 狠狠狠狠免费| 热婷婷在线视频| 五月天狠狠色| 五月丁香美女| 这里只有精品免费 | 天天干一干| 色碰碰视频| 五月天大香蕉| 五月色丁香婷婷综合| 99色精品| 天天天天天操| 亚洲婷婷欧美婷婷| 五月婷婷六月色| 91丨九色丨老熟女激情| 99黄色性生活| 五月丁香黄色视频| 能直接看的av网站| 97丁香视频| 欧美精品999| 婷婷五月丁香综合激情小说| 99热久| 婷婷狠狠操| 五月婷婷av在线| www,com,五月色色| 久久精品小视频| 99精品在线| 99这里只有精品| 亚洲热久| 狠狠狠狠狠草| 免费黄色片子| 六月婷婷色色色| 五月情四婷婷| 亚洲激情av| 99热草草| 亚洲avjiujiur91| 九九在线精点品| 99精品偷自拍| 狠狠舔| www五月| 国产精产国品一二三在观看| 五月婷婷av| 看久久性爱视频| 99热亚洲| 国产欧美第五十五页| 色色色国产| 天天操天天干天天日| 亚洲色色五月| 久热这里只有精品99re| 精品少妇人妻AV无码专区偷人| 色婷婷激情| 五月丁香花婷婷玉莉AV| 日韩AV免费电影在线播放| 99色视频| 丁香婷婷基地| 3p久久| 九九99一区| 日日影院 | 色六月丁香婷婷啪啪啪| www.五月婷婷久久.com| 五月婷婷六月丁香首页| 丁香五月天AV| 拍色综合| av性爱网站| 日本精品人妻无码77777| 99热99成人| 夜夜 操无码| 91精品综合久久婷婷九色| 深爱婷婷丁香五月激情| 第四色色色色色丁香五月天| 99爱免费视频| 伦乱人妻| 停婷丁五月在线| Av免费网站在线| 婷婷无码视频| 久久久久久久91| 丁香五月在线视频黑人| 久久五月婷婷综合网| 伊人婷婷激情| 色婷婷狠狠禁18久久| www.久久66| 久久A极片| 亚洲综合视频一下| 婷婷丁香五月天激情四射| 激情亚洲婷婷六月| 大香蕉福利导航| av网站中文| 亚州欧美黄色电影| 青青草成人网| 热99精品视频五月| 五月婷婷婷| 天天舔天天插天天爱| 色婷婷狠狠| 99热这里只有精品10| 极品少妇XXXX精品少妇偷拍| www.五月婷婷久久.com| 极品嫩草| 99九无网码| 99精品久久| 激情婷婷| 色五月影视| 人人干女人| 久久久999精品| 五月丁香日本在线视频观看| 丁香五月影| 激情六月婷| 久9精品| 91狠狠综合久久久| 丁香5月综合啪啪| 色色综合网。| 四虎成人精品永久免费AV九九| 久99| 五月丁香婷婷伊人日韩| 大香蕉99热| 伦乱美欧| 麻豆精品| 91婷婷| 久久人妻伊人| 色综合婷婷| 99人妻碰碰久久久禁片| 婷婷综合五月| 五月丁香拍拍激情综合| 午夜日韩久久久网站| 91精品综合久久久久久五月丁香| 色婷婷丁香中文在线播放| www:99热视频| 粉嫩AV久久一区二区三区| 岛国AV网| 梁铮版《蜘蛛女侠》在线| 天天综合区| 激情五月综合网| 久久九九99亚洲国产久精综合| 久久婷婷丁香视频网| 五月丁香色综合| 五月婷婷 激情五月| 秋霞免费三级片| 九月停停| 99热这里都是精品| 亚洲av日韩无码| 另类小说五月天激情| 99九九视频| 欧美婷婷色| 狠狠色婷婷777| 人人草人人爱手机视频看看| 深爱五月激情网| 一级二级色大片| 成人免费黄色短视频| 色色五月天网站| 婷婷激情啪啪| 亚洲 精品 综合 精品| 色综合色色色色| 色色欧美色色色| 可以看的AV| 婷婷八月丁香激情综合| 5月丁香六月婷婷| 丁香六月天婷婷在线| 久久久久久久久久91| 91大屁股在线| 亚洲熟妇AV乱码在线观看| 五月婷婷啪| 99爱精品| 噜噜在线| 五月婷婷六月丁香综合在线| 天天色天天爱天天爽| 婷激情五月天视频导航| 91综合国免费久入| 六月色播| 亚洲综合五月天婷婷丁香| 91综合视频在线| 欧美性爱专区| 婷婷干| 欧美情色电影一区二区| 亚洲妇女熟BBW| 激情五月影院| 性综合网| 九九99精品视频在线观看| 一起草av| 激情五月综合婷婷| 色婷婷五月天在线观看| www.99热| 婷婷五月天综合网| 禁欲电影完整版在线播放| 五月丁香五月婷婷| 这里只有精品视频在线| 九月丁香| 亚洲经典三级| 成人五月天综合网| 日韩av高清| 另类丁香综合| 久9热视频在线观看| 色五月色图| www狠狠| 成人日韩欧美| 婷婷丁香成人在线视频| 久热这里精品免费| 这里只有精品免费视频在线观看| 五月丁香六月激情啪| 26uuu另类亚洲欧美日本一| 3www激情| 亚洲色色色| 99综合久久| 99精品在线| 国产美女无遮挡裸体毛片A片| 午夜精品久久久久久久爽| 久久婷婷老| 伊人热婷婷| 婷婷欧美综合| 成人超碰AV| 丁香五月天啪啪激情综和网| 五月丁香六月综合激情| 综合色播| 激情98色婷婷五| 色色综合热| 影音先锋一区二区三区| 亚洲 精品 综合 精品| 亚洲激情色色| 97超碰在线免费观看| 五月婷婷天| 一二线视频 另类| 成人片在线免费看| 国产亚洲99久久精品| 婷婷五月天直播| 99国产视频网| 深爱激情五月网| 丁香婷婷欧美综合| 99这里有精品视频| 国产精品久久久久久五月天加勒比| 丁香婷婷影院| 五月婷婷激情综合| 碰超在线九色| 久久五月天精品视频| 伊人五月天婷婷| 99九九在线| 色综啪啪网| a九九热www| 这里只有国产精品在线| 丁香五月AV| 国产精产国品一二三在观看| AV动漫不卡无码免费| 久久99热这里只有精品23| 日本操B视频| 色墦五月丁香| 久久99激情| 日韩精品色| 4399成人黄A片| 五月婷婷黄网站大全| 亚洲欧洲另类| 这里只有精品1| 99热这里有精品| 99男人天堂| 亭亭五月天成人| 热九九精品| 九九av在线| 丁香五月冃欧美| www激情| 国产综合81p| 欧美激情2025| 少妇丁香婷婷| 99狠狠操一| 七七色综合| 色婷婷丁香五月天在线视频| www.婷婷五月天| 熟女国产在线一区二区三区四区| 天天爽人人爽| 丁香五月天啪啪| 日本啪啪网| 天天日夜夜曹| 国产精品A片在线| 激情五月丁香在线观看直播| 这里只有精品视频| 久久丝丝热| 狠狠久久婷五月| 婷婷色色欧美| 人妻精品一区二区三区| 91在线资源| 日日干干天天干| 九九亚洲| 老司机午夜福利视频金瓶梅| 99热这里只有精品在线观看| 亚洲精品99| 婷婷无码视频| 成人av在线网站| 激情五月天啪啪| 狠狠九九婷婷韩| 欧美丁香婷婷五月| 综合网色综合| 成年人丁香五月| 青青草原爱爱网| 日本色色视频| 成人AV网站在线| 欧美日韩五月婷婷| 99热99热| AV网址大全在| 免费精品99| 中文字幕av在线播放| 天天操夜夜操| 激情五婷网| 99碰碰| 天天做综合| 欧美韩国日本| 婷婷日日天天| 九九九AAA热视频| 五月丁香色六月激情干大屄| 大香AV| 五月天成人综合| 超碰人妻在线| 99国产精品久久久久久久久久久| 九九成人精品| 第四色色六月色综合| 丁香午夜天| 色婷婷88| 99热国产| 国产在线另类五月婷婷| 另类图片五月天激情| 五月婷婷九九热| 91天天操天天干天天射| 九月婷婷久久| 综合网五月天123| 婷婷丁香www视频日本韩国| 亚洲人妻Av| 色噜噜狠狠色综| 国产精品日本一区二区在线播放| 日本va欧美va欧美va| 殴美日韩成人| 玖玖伦理电影| 91av视频| 亚洲综合五月天婷婷丁香| 日日操夜夜操狠狠操| 色五月,com| 99这里只有精品| 亚洲性受XXXX五月丁香| 天天综合网~91| 一区二区乱码视频| 丁香婷婷丁香五月欧美人| 五月色情精品| 婷婷大香蕉| 天天色官网| 五月婷婷三级| 婷婷色色亚洲| 天天操无码| 思思re视频在线| 26UUU欧美激情一区二区| 99视频内射三四| 人人草开心五月天| 亭亭丁香久久五月| 都市激情亚洲| 人妻熟人中文字幕一区二区| 天天干一干| 久久五月天激情视频| 亚洲一区二区无遮挡A片| 精品一二三区久久AAA片| 日本色五月| 狠狠操天天操天天操| 亚洲有码在线视频| 日本精品人妻无码77777| 性高潮久久久久久-九九九九九九九九九九热-成人AV | 97色婷婷| 伊人9在线| 91嫩草国产线观看亚洲一区二区| 99热e| 开心激情网在线| 久久aaa| 色综合丁香婷婷| 国产av网| 老师的粉嫩小又紧水又多A片视频| 超碰国产在线观看| 欧美激情凹凸丁香网| 婷婷九月| 人人综合久| 99人人看| 亚洲无码性爱| 国外亚洲成AV人片在线观看 | 熟女91九色| 欧美一级毛卡片无码| 欧美性猛交 XXXX 乱大交| 超碰在线视屏| 狠狠五月天| 丁香五月网在线观看| 欧美激情 日韩无码 婷婷 五月天| 丁香五月综合激情性爱| 丁香五月婷婷老师网站| www.色五月| 91人妻PORNY九色大屁股| 网色99| 亚洲综合色网| 亚洲日日日| 九九爱激情| 99热这里只是精品| 婷婷永久在线| sisi热国产| 丁香五月亚洲激情婷婷射| 91碰超| 婷婷七月丁香色色| 五月婷婷黄色毛片| 九九久久污| 啪啪色激情五月天| 六月丁香啪| 婷婷干六月综合旧址| 亚洲av另类在线观看| 日韩av手机在线观看| 日本人妻伦在线中文字幕 | 五月香六月婷| www.av骚货| 丁香婷婷六月在线资源观看| 99爱免费在线视频| 五月婷婷我| 色色网五月激情| 影音先锋777xfplay色资源网站| 99思思热只有在这里看| 五月天黄色激情小说| 婷婷色情小说| 天天日,天天射,天天舔| 日日夜夜狠狠操| 久久五月天综合| 综合一区二区三区| 九九综合伊人| 五月天激情婷婷| 色色无码| 狠狠干五月| 久久资源综合| 日本婷婷在线| 亚洲五月天,激情视频| 国产精品久久99| 激情网站综合五月天| 国产精品久久久60086| 亚洲aV写真天天综合网久久| 特级西西4444www无码| 夜色综合网| 丁香五月婷婷影院| 香蕉久久国产AV一区二区| 黄色国久久| www.com在线操视频免费观看| 国产九九一区二区三区| 久热成人| 丁香色啪综合| 六月激情婷婷| 五月天另类小说| 野战J办公桌椅H| jiuse91在线| 97干网站| 五月丁香天天| 丁香五月香蕉| 五月天婷婷激情小说电影| 202丰满熟女妇大| 97在线天堂| AV电影在线播放| 五月丁香婷婷人体| 综合性爱网| 丁香五月天啪啪| 九色视频入口91| 天天色天天射天天日| 久久五月天黄色五月天色网址| 激情亚洲网| 天天干夜夜想| 丁香五月天影院| 99操逼| 99热色在线精品| 九九香蕉网| 91狼友视频在线观看| 91操网| 99色在线观看视频| 五月丁香婷婷色| 亚洲午夜国产成人电影VA国产欧…| 日本成人综合| 婷婷五月激情欧美大胆视频| 97干综合网| 九九9久九9国产视频| 中文精品在| 66精品成人免费网站在线观看| 色五月婷婷在线| 丁香六月丁香婷婷激情| 人妻熟妇国产精品| 婷婷干五月综合在线播放| 老司机伊人| 婷婷五月天你懂的| 欧美va| 五月丁香六月激情综合| 色香久久| 丁香五月婷婷激情中文| 国产激情视频在线观看| WWW.久久久久久久| 亚美欧色影院| 久久色大香蕉| 热99精品视频观看| www.色综合| 97碰在线免费观看| 婷婷五月丁香网| 欧美内射AAAAAAXXXXX| 色综合婷婷| 九九热精品| a级毛片一区二区免费视频| 婷婷色五月婷婷姐妹| 六月久久婷婷| 超碰激情五月| 五月婷婷综合潮喷| 三男玩一女三A片| 99re6热在线精品视频播放速度| 色五月婷婷小说亚洲中文字幕组| www.seqingwuyuetian| 热的五码久久精品| 激情五月综合网最新| 色婷婷五月影视| 婷婷在线免费| 婷婷丁香日韩五月| 呦呦AV| 97在线观视频免费观看| 五月色情婷婷开心五月天| 色播丁香| www.zbzhongsen.com| 激情综合国产| 在线观看996精品| 中文字幕 中文字幕明步| 伊人大香蕉爱聚| 狠狠狠狠狠操| 色五月婷婷777| 就爱干 在线| 国产精品国产成人国产三级| 欧美群妇大交乱婬网| 激情综合五月| 蜜臀AV在线成人| 九九色综合| 色播五月婷婷| 深爱激情五月网| 久热这里只有精品6官网亚洲| 婷婷97| 五月色视频| 天天插天天射| 26uuu淫色| 日本欧美成人片AAAA| 五月婷婷伊人网| 婷婷D区| 丁香久久久| 婷婷综合偷拍| 国产激情av| 五月婷久久| 色噜噜狠狠色综无码久久合欧美| 婷婷激情五月天网站| 99热在线观看| 五月丁香婷婷伊人| 影院久久久| 丁香 久久| 五月婷婷AV| 来吧亚洲综合网| 夜夜www| 日日夜夜亚洲一区| 久婷五月| 久热精品视频在线观| 五月天开心网| 激情小说 五月天| 一起草aV| 国产99久久久| 久久人妻乱子伦| 婷婷五月激情欧美大胆视频| 99re思思热久久| 五月婷婷综合久久| 婷婷中文字幕| 五月天五月天成人网亭亭成人色网站| 婷婷欧美激情| 久久久久久人妻| www,五月丁,com| 大香蕉欧美在线| 99色视频在线| 开心五月综合| 天天久综合网永久入口17v| 亚洲成人网站在线观看| 欧美天天干天天草| 五月丁香花视频| 97色婷婷| 久久五月天婷婷| 五月丁香美女视频| 婷婷天堂伊人| 最新av在线观看| 色婷婷五月网| 99男人天堂| 无码激情AAAAA片-区区| 精品人妻久久久久久| 丁香五月花婷婷开心| 五月婷婷性爱网| 99婷婷| 六月丁香社区| 99亚色色色| 超碰啪啪网| 色综合五月天| 99久在线精品99re8| 色婷婷丁香网| 丁香婷婷五月人体| 拍真实国产伦偷精品| 丁香五月欧美| 97色伦另类图片小说视频| 大香蕉九九热| 五月天天丁香婷婷| 婷婷精品视频| 玖玖资源站中文| eeuus五月婷| 亭亭五月基地在线| 亚洲视频在线观看| 日本精品99| 亚洲欧美另类在线23p| 亚洲另类婷婷五月丁香在线播放| 五月丁香婷婷色播无码| 亚洲激情四射| 丁香六月激情四射| 噜噜噜噜噜色| 天天婷婷天天| 色色婷婷丁香| 五月天婷综合| 丁香av网| 国产精产国品一二三在观看| 激情婷婷五月色| 级人人91| 欧美韩国日本| 丁香六月色婷婷| 久久婷婷五月综合| 五月天久久丁香| 天天在线久久综合| 四月婷婷五月色综合| 色情婷| 一级七香蕉| 色狠狠婷婷| 色一情一乱一伦一区二区三区| 91一起操| 亚洲婷婷91丁香| www.婷婷五月| 婷婷精品综合| 婷婷五月综合啪| 岛国av网| a69在线视频| 丁香九月综合| 人妻人人操| 国产精品视频免费看| 激情五月婷婷视频一区二区三区| 色噜噜狠狠狠狠色综合久欧美| 八戒青柠影视剧在线观看| 天天干夜夜想| 9999久久久久| 91一起操| 日本九九九九| 成人av在线电影| 中文字幕人妻在线| 九月婷婷激情| 大香蕉久久婷婷| 九九综合| www.maotanji.com| 超碰在线中文字幕| 婷婷五月综合色拍| 欧美精产国品一二三区| 色婷婷超碰| 狠狠色狠狠| 丁香五月久久| 五月丁香综合激情网| 激情色色色| 天天综合网站| 无码日本精品XXXXXXXXX| 婷婷成人基地| 狠狠噪| 操操操91| 五月天社区婷婷丁香社区| 操日视频| 亚洲色啪| 亚洲色色图片| 色综合五月在线| 五月天成人在线播放丁香| 久久视频这里99| 五月天婷婷无码| WWW99热| 亚洲五月天激情| 久久久99精品免费观看| 桃色五月婷婷| 免费操超碰| 99久热在线精品| 人人亚洲| 色婷五月| 五月天偷拍| 久99久视频| 噼里啪啦完整版中文在线观看| aV直接看| 9久9久| 色婷婷丁香网| 日韩成人综合网| 欧美啪啪9| 轮奸综合网| 丁香激情六月天婷婷| 婷婷五月天免费视频| 外国碰视频网站97| 99这里只有精品| 日本英国美国欧美亚洲国产精亚洲日韩精品在线观看 | 综合网天天| 99热综合在线观看| 色婷婷狠| 丁香五月婷婷成人色区| 99精品视频网站| 日本99热| 五月天久久小说| 日韩成人av在线| www.热99热| 97人人操| 婷婷综合丁香| 色琪琪一综合久久激情五月视频| 国产色婷婷亚洲| 色色色网站| 五月婷婷色色| 香蕉乱插| 丁香亚洲婷婷五月| 站长推荐无码播放| 狠狠干最新地址| 狠狠丁香| 婷婷六月激情综合| 日本婷婷五月天| 停停五月色宗合| 色五月天综合| 久久精品4| 香港九九六区八区99| 色优久久| 婷婷性色| 性做爰A片免费视频A片直播| 丁香婷婷色情| 综合五月激情| 久久丁香五月婷婷| 国产婷婷综合| dingxiangtingtingliuyue| 天天干天天操天天爽| 色五月97| 婷婷五月天在婷| 国产亚洲色婷婷久久99精品91| 天天综合五月天| 日韩色色视频www| 五月天婷婷综合网| 另类专区在线| 五月在线| av操逼网| 十月丁香婷婷| 天天天天天日| 日本高清久| 婷婷色五月在线视频| 99ER热精品视频| 亚洲色婷婷色| 久久99网站| 91肏| 丁香六月色婷婷| 九九九九九999999| 九九热在视频| 婷婷六月丁香五月| 久操福利| 婷婷五月色| 丁香青青五月天| 五月天黄色激情小说| 第九色区av天堂| 99热只有精品在线播放| 五月婷婷啪啪啪| 青996青| 99色在线视频| 欧美久久久久久久久中文字幕| 综合色综合| 日韩ww| 99热这里只有精品一| 国产肥白大熟妇BBBB视频 | 伊人天堂婷婷| 五月婷婷激清网| 天天躁日日躁狠狠躁日日躁2022年5月9日 | 色色a| 婷婷丁香色五月亚洲| 婷婷激情综合网| 婷婷天堂综合| 二色AV| 91婷婷丁香五月天免费视频网站| 色欲天天综合| 成人av在线网站| 超碰人妻在线| 99精品在线观看| 婷婷欧美| 99热6这里之有精品| 国产亚洲精品久久久久久郑州| 丁香香五月激情免费视频| 激情综合五月| 就爱操www com| 91嫩草国产线观看亚洲一区二区| 天天日天天干天天插天天射|