config.ini 設定系統
本篇定位
這是 Phase 7「配置系統與 WZ 資源」的第一篇。
dinput8.ini(有時命名為config.ini)是玩家唯一需要手動編輯的檔案,它讓使用者不需要重新編譯 DLL 就能調整伺服器 IP、解析度、偵錯選項等設定。
一、設定檔的設計理念
早期私服登入器把伺服器 IP 和解析度直接寫死在 DLL 裡,每次換伺服器或換解析度都要重新編譯。dinput8.ini 解決了這個問題:
使用者只需要修改一個純文字檔案 → 重新啟動遊戲 → 設定生效
設定檔放在和 MapleStory.exe 同一個資料夾(和 dinput8.dll 並排),DLL 啟動時讀取。
二、dinput8.ini 的完整格式
; MapleEzorsia-v2 設定檔
; 分號開頭的行是注釋,不會被讀取
[Connection]
; 私服伺服器的 IP 位址或網域名稱
ServerIP = 127.0.0.1
; 私服伺服器的連線 Port(MapleStory 預設 8484)
Port = 8484
[Display]
; 遊戲視窗寬度(像素)
; 建議值:800, 1024, 1280, 1366, 1920
Width = 1280
; 遊戲視窗高度(像素)
; 建議值:600, 768, 720, 768, 1080
Height = 720
; 視窗模式:true = 視窗,false = 全螢幕
Windowed = true
[Debug]
; 顯示 Debug 控制台視窗(開發時用)
ShowConsole = false
; 輸出詳細的 Hook 安裝日誌
VerboseLog = false
[EXP]
; EXP 倍率(1 = 原始倍率,2 = 雙倍,以此類推)
; 需要配合私服伺服器端的設定,純客戶端設定無效
ExpRate = 1三、各設定項說明
Connection 區段
| 鍵名 | 型別 | 預設值 | 說明 |
|---|---|---|---|
ServerIP | 字串 | 127.0.0.1 | 支援 IPv4 或 domain name(如 play.example.com) |
Port | 整數 | 8484 | 大多數 MapleStory v83 私服使用 8484 |
使用 domain name 的注意事項
如果填入 domain name(如
maple.myserver.com),Hook_WSPStartup的 IP 替換邏輯需要先做 DNS 解析(gethostbyname)才能取得實際 IP。如果直接填 domain name 而 Hook 只處理 IPv4 字串格式,連線可能失敗。建議直接填 IP 位址。
Display 區段
| 鍵名 | 型別 | 預設值 | 說明 |
|---|---|---|---|
Width | 整數 | 1280 | 建議使用 16:9 比例(1280/1366/1920) |
Height | 整數 | 720 | 避免奇數值,某些 D3D 紋理要求偶數大小 |
Windowed | 布林 | true | 全螢幕模式(false)在多螢幕環境下容易出問題 |
不支援的解析度組合
太小的解析度(如 640×480)可能讓某些 UI 元素超出可見範圍。 太大的解析度(超過螢幕原生解析度)可能讓字型模糊,因為遊戲的 DirectDraw 字型渲染不支援超解析度。 建議使用螢幕原生解析度或比它小的標準比例。
Debug 區段
| 鍵名 | 型別 | 預設值 | 說明 |
|---|---|---|---|
ShowConsole | 布林 | false | true 時,DLL 載入後會開一個 cmd 視窗顯示日誌 |
VerboseLog | 布林 | false | 顯示每個 Hook 的安裝確認訊息 |
ShowConsole 的實作:
if (config.ShowConsole) {
AllocConsole(); // 建立新的控制台視窗
freopen("CONOUT$", "w", stdout); // 把 stdout 重導向到控制台
freopen("CONOUT$", "w", stderr);
SetConsoleTitleA("MapleEzorsia-v2 Debug");
}四、設定檔的讀取時機
flowchart LR A[DllMain 載入] --> B[MainProc 執行緒啟動] B --> C[MainMain::CreateInstance] C --> D[MainMain::LoadConfig 讀取 dinput8.ini] D --> E{ShowConsole?} E -->|true| F[AllocConsole 開控制台] E -->|false| G[靜默模式] F --> H[同步設定到 Client / Hook] G --> H H --> I[WaitForThemida] I --> J[MainFunc 安裝 Hook]
設定檔在哪個路徑讀取?
INIReader("dinput8.ini")使用相對路徑,以遊戲的工作目錄(Working Directory)為基準,通常就是MapleStory.exe所在的資料夾。如果遊戲是從桌面捷徑啟動且捷徑有設定不同的「起始位置」,可能會找不到設定檔。建議用絕對路徑或GetModuleFileName取得 DLL 所在目錄。
五、常見問題
Q:修改了 dinput8.ini 但設定沒有生效?
設定檔在 DLL 載入時只讀取一次,遊戲執行中修改不會即時生效。必須完全關閉遊戲並重新啟動。
Q:ini 檔案的編碼需要注意嗎?
INIReader使用std::ifstream讀取,預設處理 ANSI / UTF-8 編碼。如果ServerIP或路徑中有中文(如伺服器.example.com),建議確認檔案以 UTF-8 無 BOM 格式儲存。中文 IP domain 在實務上很少見,一般不需要擔心。
Q:
Width = 0或負數會怎樣?
INIReader::GetInteger回傳原始整數,不做範圍驗證。MainMain::LoadConfig讀入後直接存進成員變數,0 或負數會在後續Client::UpdateResolution()寫入遊戲,造成 Direct3D 建立 Back Buffer 失敗,遊戲閃退。應在LoadConfig加入範圍驗證(if (w < 640) w = 1280)。
延伸閱讀
- 02_INIReader.h解析 — 下一篇:INIReader 如何解析 ini 格式
- 03_MainMain.cpp_初始化流程解析 — LoadConfig 在初始化流程中的位置
- 02_解析度修改原理與實作 — Width/Height 設定如何被使用