跳到正文
本頁目錄

構建與貢獻

構建

需要 Windows x64、xmake、MSVC 14.4x 或更新的 Visual Studio 生成工具,以及 LLVM(clang-cl)。 tools/build.ps1 會找到它們,缺的用 winget 安裝,然後構建:

powershell
pwsh -NoProfile -File tools/build.ps1   # [-Mode debug]

手動構建:

powershell
xmake f -a x64 -m release -p windows --target_type=client -y
xmake -y        # -> bin\BeDD\(DLL、manifest 以及 client\ 里的所有文件)

模組打包器從 git describe 讀取版本號,所以倉庫至少要有一個提交。

tools\dev.ps1 [-Trace] 是一個試驗場:它拿到共享的 e2e 鎖(%APPDATA%\levilauncher.exe\bei-e2e.lock),把模塊部署進 BeDD 找到的實例 (新電腦上先準備好,見在新電腦上準備),沒有管理窗口時先啟動它,通過 LeviLauncher 啟動遊戲(遊戲顯示在管理窗口裡),並把每次前臺和光標鎖定的變化記錄到 tools\out\desktop-watch.log,直到遊戲退出或 tools\out\dev.stop 存在(tools\out\dev.restart 會重新部署並重啟,不釋放鎖)。 它最後總會關掉遊戲、刪掉模塊並釋放鎖。

文檔與展示素材

docs/ 是文檔站點(https://docs.levimc.org/BeDD/,由 .github/workflows/docs.yml 用 levimc-kit 構建;cd docs; npm ci; npm run build)。 docs/public/showcase/ 存放站點的展示內容和 README 裡的圖片。

tools/showcase/record.ps1 [-KeepOpen] 重新錄製桌面視頻:在共享 e2e 鎖(以及每個克隆的 hi<N>-e2e.lock)下,它準備三個克隆實例 (-hi2..-hi4,其他模組挪開),恢復 tools/showcase/fixtures/Showcase.zip 存檔,在它自己的管理窗口裡啟動遊戲(BEDD_MANAGER_PIPE,這樣別的測試的遊戲不會進畫面) 並進入世界,在屏幕外、不搶焦點的控制台窗口裡運行 demo.ps1,然後用 ffmpeg 的 gfxcapture(Windows.Graphics.Capture:直接錄窗口自己的畫面,被擋住也不影響) 錄下管理窗口和這個控制台,存為 tools/showcase/out/take-<n>-manager.mkv 和 take-<n>-terminal.mkv。不會有窗口挪到你面前,也不會搶焦點。 帶 -KeepOpen 時,創建 tools/showcase/out/take 開始下一次錄製,tools/showcase/out/stop 結束。 tools/showcase/encode.ps1 把一次錄製拼成左邊管理窗口、右邊終端的畫面,剪成 MP4、WebP 和封面圖。

源碼結構

文件
src/BeDD.h共享狀態,以及下面各部分的聲明
src/Mod.cpp入口、配置、虛擬按鍵/光標狀態
src/Window.cpp窗口查找、子類化、合成事件分發、焦點屏蔽、讓窗口留在屏幕外
src/ApiHooks.cppuser32 鉤子(光標、按鍵狀態、前臺、激活、原始輸入)
src/GameInputHooks.cppGameInput v2 鉤子(虛擬鼠標、鍵盤讀數)
src/Audio.cppFMOD 鉤子:靜音遊戲的主通道組(mute)
src/NetHooks.cpp只用本機網絡(loopbackOnly:沒有防火牆提示,不查詢本機以外的服務器)
src/Pipe.cpp控制管道和協議
src/Manager.cpp與會話管理窗口的連接
src/Trace.cpptrace 模式的輸入日誌
src/MoveInput.cppinput 操作:在客戶端的 ClientInputUpdateSystem 裡覆蓋移動,帶死人開關 TTL(gameHooks)
src/Send.cppsend 操作(allowSend):允許列表內的服務端方向數據包,在客戶端線程上由本地玩家發送
src/GameState.cpp、src/Look.cppworld 快照和絕對 look(gameHooks)
src/GameActions.cppslot、action 和按刻計算的 button 操作(gameHooks)
src/Stack.cppstack 操作(allowStack):由本地客戶端發送的物品堆請求
src/TapSink.h所有 tap 發佈者共用的幀類型和 sink 鏈(保持逐字節一致)
src/Tap.cpp、src/Tap.htap 管道:幀格式、標記、寫線程、tap 操作
src/NetTap.cpp遠程服務器連接上的 tap 抓取,以及 blob 緩存開關
src/TapLoopback.cpp單人世界和局域網主機世界裡的 tap 抓取(重新序列化的包)
src/TapJournal.cpptap 的加入日誌(給晚到讀取方的壓縮回放)
src/MemoryOperators.cpp讓 new/delete 走 LeviLamina 的分配器(LeviLamina 要求)
client/PowerShell 客戶端、框架墊片、遊戲啟動(Start-BeDDGame.ps1)、管理窗口(BeDDManager.ps1)、克隆腳本和準備腳本(BeDDSetup.psm1、Initialize-BeDD.ps1:找到遊戲實例並補齊新電腦缺的東西),都和 DLL 放在一起發佈

掛鉤遊戲或 LeviLamina 的符號時,先查 %LOCALAPPDATA%\.xmake\packages\l\levilamina\<version>\<hash>\include 下的 SDK 頭文件。 只調用 MCAPI、MCFOLD 和 MCTAPI 函數。

Pull request

  1. Fork 倉庫,從 main 建分支。
  2. 每個 pull request 只做一件事。說明它做了什麼、你怎麼測試的。
  3. 遵循現有風格:C++20、倉庫裡的 .clang-format 和 .editorconfig,代碼和註釋用英文。
  4. 在遊戲裡測試:tools/dev.ps1 -Trace,然後通過 BeDD.psm1 驅動遊戲,檢查輸入有效、遊戲從不搶前臺(tools/out/desktop-watch.log), 真實輸入也到不了遊戲。
  5. CI 通過後才能合併。

提交信息用祈使語氣("Add wheel tilt",而不是 "Added …")。對用戶可見的改動,在 CHANGELOG.md 的 Unreleased 下記一筆。

另見 CONTRIBUTING.md。參與貢獻即表示你同意你的貢獻以本項目的許可證 LGPL-3.0-or-later 授權。