現代、可自定、開源的自動更新方案 —— NekoLauncher

183天前 · 程式設計 · c++ · 481次阅读

什麼是 NekoLauncher(NekoLc)

Neko Launcher(簡稱 NekoLc)是一個現代化、跨平台、多語言的啟動器,內建自動更新與 UI 系統。
它的主要目標是:讓你的遊戲或應用(例如 Minecraft 客戶端)能夠自動保持最新版本同時盡量減少玩家使用者需要操作的步驟

過去你可能常常遇到這些問題:

  • 使用者懶得更新或不會更新,導致版本參差不齊、客服負擔加重。
  • 每次發布新版本,都要重打安裝包、重寫教學、反覆回答「為什麼進不去?」。
  • 花費太多時間在自動更新系統的設計與維護上,無法專心在遊戲/軟體本身的開發。

Neko Launcher 正是處理這些的良藥

它提供一個統一的「啟動入口」,並且負責下載與更新流程;完成後再讓玩家進入主畫面或直接啟動目標。

在這篇文章中,我們會一步步帶你:

  1. 了解 NekoLauncher 的模組與整體架構。
  2. 在本機抓取原始碼並完成構建。
  3. 使用 config.ini 做最小可用設定。
  4. 大致理解與 Minecraft 整合的方向。
  5. 知道如何客製 UI、佈署與發佈給玩家。

一、核心概念與模組架構

Neko Launcher 大致可以拆成幾個模組來理解(對應 src/neko/include/neko/):

  1. App 模組(App module)

    • 檔案範例:neko/app/app.hppappinit.hppclientConfig.hppconfigManager.hpp
    • 負責應用程式初始化(語言、設定檔、網路、日誌等)與整體生命週期。
    • 會載入 config.ini、語言檔與遠端設定,並把結果放到 Config Bus 讓其他模組存取。
  2. Core 模組(Core module)

    • 檔案範例:neko/core/update.hppinstall.hpplauncher.hppremoteConfig.hpp
    • 主要處理:

      • 自動安裝/自動更新(autoInstall()autoUpdate())。
      • 啟動外部程式(如遊戲客戶端)。
      • 連線遠端伺服端(例如 NekoLcServer)取得啟動與更新設定。
    • 更新進度、錯誤等事件會透過 Event Bus 丟給 UI 顯示。
  3. Minecraft 模組(Minecraft module)

    • 檔案範例:neko/minecraft/installMinecraft.hpplauncherMinecraft.hpp
    • 專門處理 Minecraft Java 版的下載、安裝與啟動指令組裝。
    • 會根據 config.ini[minecraft] 區塊與遠端設定,下載版本核心、資產與庫,最後呼叫 Java 啟動遊戲。
  4. UI 模組(UI module)與 Bus

    • 檔案範例:neko/ui/windows/nekoWindow.hppthemeIO.hppuiEventDispatcher.hpp
    • UI 採用 Qt Widgets,負責主視窗、載入畫面、通知視窗、輸入視窗等。
    • Bus(neko/bus/*)提供事件與設定的集中管道:程式任一處可以發送「顯示 Loading」「顯示公告」「切換頁面」等事件,UI 會在 Qt 主執行緒中處理。

整體流程(對應 src/neko/main.cpp):

  1. 建立 QApplication
  2. 呼叫 app::init::initialize() 做設定與網路啟動。
  3. 建立 NekoWindow(主視窗)、載入主題與語言。
  4. 在背景工作緒中依序呼叫 core::install::autoInstall()core::update::autoUpdate()
  5. 下載並顯示新聞、更新資訊,再導向首頁或新聞頁。
  6. 玩家在 UI 中啟動目標遊戲(如 Minecraft)。

二、環境要求

作業系統

  • Windows:建議 10及以上版本,需有對應 Qt 工具鏈。
  • Linux:常見發行版(Ubuntu / Debian / Arch / Fedora 等),需有對應 Qt 工具鏈。
  • macOS:建議 12及以上版本,需有對應 Qt 工具鏈。

編譯器與工具鏈

  • CMake 3.20+。
  • C++20 編譯器:MSVC / Clang / GCC 皆可。
  • Qt 6(至少 Widgets + Gui + Core 模組)。
  • Git(含子模組)與可連外的網路,以便在 CMake 時自動抓取依賴(Neko* 系列、GTest、nlohmann_json、SimpleIni 等)。

在 CMake 設定中,若 Qt 或其他函式庫沒有自動被找到,可以透過 NEKO_LC_LIBRARY_DIRS 額外指定搜尋路徑(對應 CMakeLists.txt 內的設定)。


三、取得原始碼

1. Clone 專案

git clone https://github.com/moehoshio/NekoLauncher.git
cd NekoLauncher

或使用 SSH:

git clone [email protected]:moehoshio/NekoLauncher.git
cd NekoLauncher

四、專案實際結構概覽

以下對照目前 repo 實際目錄做說明:

NekoLauncher/
├─ CMakeLists.txt        # 主要 CMake 設定檔(專案名 NekoLc)
├─ src/
│   └─ neko/             # App/Core/Minecraft/UI 等模組的實作
├─ include/
│   └─ neko/             # 對應的標頭檔
├─ langs/                # 語言 JSON 檔(en.json、zh_hant.json…)
├─ themes/               # 主題 JSON(如 Aurora.json)
├─ resource/
│   └─ img/              # 背景圖、loading 圖等 UI 圖像
├─ config.ini.example    # 設定檔範本(INI 格式)
├─ doc/
│   └─ dev.md            # 開發者技術說明
├─ tests/                # 單元測試與 CTest 設定
└─ build/                # 建置輸出(建議 out-of-source 建置)

關鍵檔案對應:

  • CMakeLists.txt:定義專案名稱(NekoLc)、C++ 標準、相依函式庫與目標可執行檔。
  • src/neko/main.cpp:啟動器入口,負責初始化、啟動背景更新流程與建立 Qt 主視窗。
  • config.ini.example:實際使用中的設定格式範本,啟動器會讀取 config.ini

五、使用 CMake 構建 NekoLauncher

以下以桌面環境、Qt 6 為前提以build NekoLauncher:

1. Windows

在專案根目錄執行(PowerShell):

# Clone 後進入專案
git clone https://github.com/moehoshio/NekoLauncher.git
cd NekoLauncher

# Configure:告訴 CMake Qt 與其他套件的安裝路徑
cmake -B build -S . \
  -DNEKO_LC_LIBRARY_DIRS="<Qt_path>;<Other_package_path>" \
  -DNEKO_LC_STATIC_LINK=OFF

# Build(Debug / Release 擇一)
cmake --build build --config Release

# Run
./build/Release/NekoLc.exe

說明:

  • NEKO_LC_LIBRARY_DIRS:加入 Qt 與其他依賴的安裝路徑,CMake 會從中尋找 Qt6, Boost 等。
  • NEKO_LC_STATIC_LINK:在 MSVC 下可選擇靜態連結運行時;如果選擇靜態鏈接,請一定確保所有程式庫和C++ Runtime(CRT)都通過靜態鏈接編譯!
    請不要混用靜態與動態鏈接。
否則你可能遇到莫名其妙的連結錯誤或執行時錯誤。

2. Linux / macOS

依你的工具鏈調整,核心邏輯類似:

git clone https://github.com/moehoshio/NekoLauncher.git
cd NekoLauncher

cmake -B build -S . \
  -DNEKO_LC_LIBRARY_DIRS="<Qt_path>:<Other_package_path>" \
  -DCMAKE_BUILD_TYPE=Release

cmake --build build

./build/NekoLc

實際的 Qt 安裝方式(系統套件 / 自行編譯 / Qt Online Installer)會影響 NEKO_LC_LIBRARY_DIRS 如何填寫,請依你的環境調整。


六、啟動流程與實際行為

當你已經:

  • 使用 CMake 成功構建 NekoLc(例如 build/Release/NekoLc.exe)。
  • 準備好執行目錄(NekoLc.exe + config.ini + langs/ + themes/ + img/)。

就可以嘗試啟動:

1. Windows 啟動範例

cd path\to\runtime
./NekoLc.exe

預設情況下:

  1. 程式會讀取 config.ini,初始化語言、主題、網路與日誌。
  2. 進入背景執行緒,先嘗試 core::install::autoInstall(),若沒有需要安裝的內容再執行 core::update::autoUpdate()
  3. 期間會透過 Bus 觸發 Loading 畫面與進度更新。
  4. 下載並處理遠端啟動設定與新聞(若後端有提供),最後切換到首頁或新聞頁。
  5. 玩家可在 UI 中觸發 Minecraft 安裝/啟動或其他目標行為。

2. 分發與更新

分發你的程式有兩種策略:

  1. 打包所有資源(包括你的程式)和 NekoLauncher,一起發佈給玩家。
記得填寫config.ini的資源版本號(main.resourceVersion),否則可能觸發安裝流程
  1. 只發佈 NekoLauncher,並讓它從遠端伺服器下載你的程式與資源。
  • 第一次啟動時可能需要較久時間下載核心、資源與庫檔。
  • 若過程有錯誤(網路問題、檔案雜湊不一致等),UI 會透過 Notice 對話框顯示錯誤原因。
  • 之後再次啟動時,autoUpdate() 只會處理有變動的部分,而不是整包重下(依據伺服器計算差異)。

七、兩種使用方式(獨立啟動器 vs 嵌入)

目前 NekoLauncher(NekoLc)主要支援兩種整合/使用方式:

1) 透過 shell 啟動目標(NekoLc 與資源獨立)— 所有語言皆可

這是最常見的用法:

  • NekoLc 是獨立的一個程式,負責更新/下載「資源(resource)」。
  • 更新完成後,NekoLc 透過 shell 啟動你的目標程式(遊戲/客戶端/啟動腳本)。
  • 因為「目標」只是被啟動的外部程序,所以你的目標可以是任何語言寫的(C++ / C# / Java / Python / Rust… 都可以)。

如果你要抓目標的標準輸出(stdout/stderr),則使用 core::launcherProcess()pipeStreamCb(本文件「九-4」有更詳細說明)。

2) 直接把 NekoLc 嵌入到你的 C++ 專案 — 僅 C++

這種方式的核心概念是:

  • 把 NekoLauncher 本身當成一套 C++ 模組/程式碼,直接加進你自己的專案中。
  • 你的專案就不需要再「額外啟動一個 NekoLc.exe」;而是由你自己的主程式去呼叫 NekoLc 的初始化與更新流程。

最簡單的嵌入做法(等同把入口搬進你的專案):

  1. 把本 repo 的 include/src/neko/(以及相依的 Neko* 子模組/第三方依賴)加入到你自己的 C++ 專案建置系統(例如 CMake)。
  2. 參考 src/neko/main.cpp,把其中的流程搬到你自己的 main()

    • 建立 QApplication(如果你要用內建 UI/Qt Widgets)
    • 呼叫 app::init::initialize() 完成設定/網路/事件訂閱初始化(此函式會回傳可等待的 network ready)
    • 在背景執行緒中:等待 network ready 後依序呼叫

      • core::install::autoInstall()(resourceVersion 空時做首次安裝)
      • 若已安裝則呼叫 core::update::autoUpdate()(日常更新)
    • 需要的話再接著呼叫 core::fetchNews(...) 等額外功能
  3. 若你不需要 NekoLauncher 的 UI:

    • 你仍可保留「初始化 + install/update」的流程,但 UI 的 event 訂閱與視窗建立就改由你自己的 UI/流程處理。

一句話總結:

  • 獨立啟動器(shell):最通用、可啟動任何語言的目標。
  • 嵌入 C++:把 NekoLc 變成你程式的一部分,直接呼叫初始化與更新方法。

八、與 Minecraft 整合

  • 使用遠端設定與官方/自訂來源下載版本核心、資產與庫。
  • config.ini 裡的 [minecraft] 設定與遠端授權資訊組合啟動指令。
  • 包含 Authlib Injector 等相關欄位(在程式端的結構體中定義)。

伺服端部分官方提供了獨立專案:

  • NekoLcServer:實作遠端設定、更新資訊與新聞等 API。
  • NekoLauncher 會向這個伺服端(或你自己相容的實作)取得「要怎麼更新/啟動」的具體內容。

如果要自行手動編輯更新資訊的檔案,你可能需要:

  1. 訪問 NekoLcApi 的API規範。
  2. 使用或參考 NekoLcServer 專案。
  3. 讓啟動器透過 Core 模組提供的 API 直接與伺服端互動。
  4. 由伺服端負責產生版本清單、檔案列表與下載網址。

九、客製化與佈署建議

1. UI / 主題 / 語言

  • 語言檔:langs/ 目錄內的 .json,可新增自己的語系或修改現有翻譯。
  • 主題:themes/ 目錄(如 Aurora.json),控制顏色、字型等外觀。
預設主題無法在運行時編輯
  • 圖像:resource/img/ 內的背景與 loading 動畫拷貝到運行目錄,可替換成自己的風格。

2. 發佈給玩家時的檔案布局

一個完整的執行目錄通常包含:

  • NekoLc.exe(或對應平台的可執行檔)。
  • config.ini。 (可選的,能夠自動產生)
  • langs/:從 repo 複製過來的語言檔。
  • themes/:主題 JSON。
  • img/loading.gif 等 UI 圖檔(可從 resource/img/ 拷貝或替換)。
  • 若為動態連結,記得放上需要的 .dll(Windows)或對應平台的 shared library。

你可以:

  • Windows:打包成 .zip 或 Installer(NSIS / Inno Setup)。
  • macOS:打包為 .app,必要時簽名。
  • Linux:打包成 .tar.gz、AppImage 或發佈到套件庫。

玩家只要下載一次啟動器,後續更新由 NekoLauncher + 後端流程自動完成。

3. 自定啟動目標(Custom Launcher)

NekoLauncher 的「啟動目標」目前是用編譯期常量決定的(不是 config.ini),主要在 include/neko/app/nekoLc.hpp

  • LauncherMode:目前支援 "minecraft""custom"

流程上,UI 點擊啟動後會呼叫 neko::core::launcher()include/neko/core/launcher.hpp)。

最小做法:直接在 custom 分支寫死你的啟動方式

  1. include/neko/app/nekoLc.hppLauncherMode 改為:
// Options: "custom", "minecraft"
constexpr neko::strview LauncherMode = "custom";
  1. include/neko/core/launcher.hppcustom 分支裡,改成呼叫 core::launcherProcess()core::launcherNewProcess()

概念範例(示意用;你可以改成讀設定檔/遠端設定再組 command):

#include "neko/core/launcherProcess.hpp"

namespace neko::core {
   inline void launcher(std::function<void()> onStart = nullptr,
                   std::function<void(int)> onExit = nullptr,
                   bool detach = false) {
      if constexpr (std::string_view("custom") == lc::LauncherMode) {
         const auto cfg = bus::config::getClientConfig();

         // 例:把工作目錄放到你的資源資料夾/遊戲資料夾
         const std::string workingDir = "./";
         const std::string command = "yourGame.exe --arg1 --arg2";

         if (detach) {
            core::launcherNewProcess(command, workingDir);
            if (onStart) onStart();
            if (onExit) onExit(0);
            return;
         }

         core::ProcessInfo pi{
            .command = command,
            .workingDir = workingDir,
            .onStart = onStart,
            .onExit = onExit,
            // 想要取 stdout/stderr 就在這裡接
            .pipeStreamCb = [](const std::string &line) {
               // 你可以:log::info(line) / bus 發事件到 UI / 寫檔
            },
         };
         core::launcherProcess(pi);
         return;
      }

      // minecraft 分支略
   }
}

進階做法:把「目標命令」做成可設定(推薦)

如果你希望不重編譯就能改啟動目標,建議把欄位加進 config.ini,並在 include/neko/app/clientConfig.hppClientConfig 解析/保存:

  • 新增 [custom] 區塊,例如:
[custom]
command = yourGame.exe --arg1 --arg2
workingDir = ./game
  • ClientConfig 加一個 struct Custom { std::string command; std::string workingDir; } custom;
  • ClientConfig(const CSimpleIniA&) 裡用 cfg.GetValue("custom", ...) 讀進來
  • setToConfig() 裡寫回去

最後在 core::launcher()custom 分支改用 cfg.custom.command / cfg.custom.workingDir

4. 如何取得目標程式的標準輸出(stdout/stderr)

專案已經內建「抓子程序輸出」的工具:neko::core::launcherProcess()(宣告在 include/neko/core/launcherProcess.hpp,實作在 src/neko/core/launcherProcess.cpp)。

你只要在 core::ProcessInfo 填入 pipeStreamCb

  • pipeStreamCb 會以「逐行(line)」的方式回呼:std::function<void(const std::string &)>
  • 如果你不提供 callback,輸出會被寫到 launcher 的 log(預設會 log::info("Launcher output: ...")

重要細節:

  • Windows:launcherProcess 會把 stdout + stderr 合併導到同一個 pipe(所以 callback 會同時收到兩者);並且會額外把完整輸出鏡像到暫存檔 nekolauncher-child.log(方便留存 Java stack trace)。
  • Linux/macOS:目前為了避免某些環境下的 dup2 問題,stderr 會導到 null(所以 callback 只會收到 stdout)。如果你需要 POSIX 的 stderr,也可以調整 src/neko/core/launcherProcess.cpp 的 redirection 策略。
  • Detach(背景啟動)時:launcherNewProcess() 是 fire-and-forget,不會接管輸出;如果你要抓 stdout/stderr,就不要 detach。

5. 大多數「選擇/預設」在哪裡調整?(neko/app/nekoLc.hpp

大多數「偏發行版層級」的選擇,是放在 include/neko/app/nekoLc.hppconstexpr 常量提供,修改後需要重新編譯。

常見會改的項目包含:

  • App:AppNameAppVersionAppIconPathLoadingIconPathThemeFolderNameLanguageFolderNameClientConfigFileName
  • Launcher:LauncherModeminecraft/custom
  • Network:NetworkHostListNetworkAuthlibHost
  • Feature flags:EnableAuthenticationEnableWebSocketEnableStaticDeploymentEnableStaticRemoteConfigNetworkStaticRemoteConfigUrl

相對地,使用者層級的選項(語言、主題、啟動後行為、Minecraft 路徑等)主要在 config.ini / 設定頁裡調整。


十、core version 與 resource version 的不同

NekoLauncher 裡有兩種「版本號」語意不同、用途也不同:

  1. core version(啟動器版本)

    • 代表 NekoLauncher / NekoLc 這個「啟動器本體」的版本。
    • 主要對應 include/neko/app/nekoLc.hppAppVersion,並透過 build time + git hash 組成 buildID()(例如 v0.0.1-<buildtime>-<githash>)。
    • 通常只有在你要更新啟動器本身(修 bug、改協議、增加功能、更新 Qt/依賴、資安修補…)時才需要變更。
  2. resource version(資源/內容版本)

    • 代表「被啟動器管理、會被更新的內容」的版本(例如你的遊戲客戶端、資源包、附加檔案等)。
    • 存在 config.inimain.resourceVersion
    • core::install::autoInstall() 會以「resourceVersion 是否為空」判斷是否需要跑首次安裝流程;而 core::update::autoUpdate() 在更新成功後會保存新的 resourceVersion

實務建議:

  • 使用者要保持更新,多數情況只需要調整 resource version(搭配伺服端/靜態檔案提供對應版本的內容)。
  • core version 通常不常變:除非你真的要更新 NekoLauncher 本體,否則不需要頻繁發新啟動器。

結語

NekoLauncher(NekoLc)是一個以 C++20 + Qt 6 實作的啟動與更新平台:

  • 你不需要在每次發佈新版本時都重做安裝包,只要更新伺服端與版本檔案。
  • 玩家只要維持同一份啟動器,後續更新都會透過 autoInstall() / autoUpdate() 自動處理。
  • UI、語言與主題都可以依你的社群風格客製。

See more:
NekoLcApi
NekoLcServer

👍 0

minecraft neko launcher cpp modern-cpp neko 啓動器

最后修改于111天前

评论

贴吧 狗头 原神 小黄脸
收起

贴吧

  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡

狗头

  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头

原神

  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神

小黄脸

  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸

目录

avatar

Hina

曇花一現

20

文章

98

评论

8

分类

初见

使用C++編寫Java Minecraft Launcher 啓動器 —— 定義

544天前

OwO

33

網站正在更新中...
站點正在更新功能與樣式,如有樣式錯誤,請嘗試刷新緩存