feat: add comprehensive diagnostic logging subsystem and UI controls
This commit is contained in:
1 parent
517436321b
commit
5f45841936
15 files changed
+495
-23
No files matched your search
@@ -2,6 +2,7 @@ import { CheckUpdateLauncher } from "@/helper"
|
||||
import useModalStore from "@/stores/modalStore"
|
||||
import useSettingStore from "@/stores/settingStore"
|
||||
import useLauncherStore from "@/stores/launcherStore"
|
||||
import { FSService } from "@bindings/g-launcher/internal/fs-service"
|
||||
import { toast } from "react-toastify"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
@@ -91,8 +92,47 @@ export default function SettingModal({
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Section 3: Diagnostic Logs */}
|
||||
<div className="p-4 bg-base-200 rounded-xl border border-cyan-500/40 shadow-sm">
|
||||
<h4 className="font-bold text-lg mb-1 flex items-center gap-2">
|
||||
<span>📋</span>
|
||||
<span>Diagnostic Logs</span>
|
||||
</h4>
|
||||
<p className="text-xs text-white/70 mb-3">
|
||||
เปิดโฟลเดอร์หรือคัดลอก Log เพื่อส่งให้ทีมพัฒนาช่วยวิเคราะห์ปัญหาการเข้าเกม
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
className="btn btn-sm btn-info text-white shadow"
|
||||
onClick={async () => {
|
||||
const [ok, err] = await FSService.OpenLogsFolder()
|
||||
if (!ok) toast.error("Failed to open logs: " + err)
|
||||
}}
|
||||
>
|
||||
📂 เปิดโฟลเดอร์ Log
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-sm btn-outline btn-secondary"
|
||||
onClick={async () => {
|
||||
try {
|
||||
const [logs, err] = await FSService.ReadLogs(200)
|
||||
if (err) {
|
||||
toast.error("Failed to read logs: " + err)
|
||||
return
|
||||
}
|
||||
await navigator.clipboard.writeText(logs)
|
||||
toast.success("คัดลอก Log 200 บรรทัดล่าสุดเรียบร้อย!")
|
||||
} catch (e: any) {
|
||||
toast.error("Cannot copy logs: " + e)
|
||||
}
|
||||
}}
|
||||
>
|
||||
📋 คัดลอก Log ล่าสุด
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Section 3: Launcher Version */}
|
||||
{/* Section 4: Launcher Version */}
|
||||
<div className="p-4 bg-base-200 rounded-xl border border-purple-300 shadow-sm">
|
||||
<h4 className="font-bold text-lg mb-2">{t("setting.version_label")}</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
|
||||
@@ -158,22 +158,29 @@ export default function LauncherPage() {
|
||||
try {
|
||||
setIsLoading(true)
|
||||
const basePath = await FSService.PickFile("exe")
|
||||
await FSService.LogMessage("INFO", "handlePickFile: selected file=" + basePath)
|
||||
if (basePath.endsWith("StarRail.exe") || basePath.endsWith("launcher.exe")) {
|
||||
const normalized = basePath.replace(/\\/g, '/')
|
||||
const normalized = basePath.replace(/\\/g, "/")
|
||||
const folderPath = path.dirname(normalized)
|
||||
const fullPath = `${folderPath}/StarRail_Data/StreamingAssets/DesignData/Windows`
|
||||
const fullPath = folderPath + "/StarRail_Data/StreamingAssets/DesignData/Windows"
|
||||
const exists = await FSService.DirExists(fullPath)
|
||||
await FSService.LogMessage("INFO", "handlePickFile: folderPath=" + folderPath + ", DesignData exists=" + exists)
|
||||
if (!exists) {
|
||||
await FSService.LogMessage("WARN", "handlePickFile: DesignData not found at " + fullPath)
|
||||
toast.error(t("home.error_game_dir"))
|
||||
} else {
|
||||
setGamePath(basePath)
|
||||
setGameDir(folderPath)
|
||||
await FSService.SaveGameSelection(basePath, folderPath)
|
||||
toast.success(t("home.game_path_success"))
|
||||
}
|
||||
} else {
|
||||
await FSService.LogMessage("WARN", "handlePickFile: invalid file type: " + basePath)
|
||||
toast.error(t("home.error_file_type"))
|
||||
}
|
||||
} catch (err: any) {
|
||||
const errStr = err?.stack || err?.message || String(err)
|
||||
await FSService.LogMessage("ERROR", "handlePickFile error: " + errStr)
|
||||
toast.error(t("home.toast_pick_folder_error"), err)
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
@@ -181,21 +188,27 @@ export default function LauncherPage() {
|
||||
}
|
||||
|
||||
const handleStartGame = async () => {
|
||||
await FSService.LogMessage("INFO", "handleStartGame initiated: selectedServer=" + selectedServer + ", gamePath=" + gamePath + ", serverPath=" + serverPath + ", proxyPath=" + proxyPath)
|
||||
if (!gamePath) {
|
||||
await FSService.LogMessage("WARN", "handleStartGame aborted: gamePath is empty")
|
||||
toast.info("Please select the game executable first")
|
||||
return
|
||||
}
|
||||
if (gameRunning) {
|
||||
await FSService.LogMessage("WARN", "handleStartGame aborted: game is already marked as running")
|
||||
return
|
||||
}
|
||||
try {
|
||||
setIsLoading(true)
|
||||
|
||||
if (selectedServer === "gacy-ps") {
|
||||
await FSService.LogMessage("INFO", "handleStartGame: querying GaCy PS server executables...")
|
||||
const [gameServer, sdkServer] = await GitService.FindServerExecutables()
|
||||
const activeServer = gameServer || serverPath
|
||||
await FSService.LogMessage("INFO", "handleStartGame: found gameServer=" + gameServer + ", sdkServer=" + sdkServer + ", activeServer=" + activeServer)
|
||||
|
||||
if (!activeServer) {
|
||||
await FSService.LogMessage("ERROR", "handleStartGame: activeServer missing. Opening download modal.")
|
||||
toast.error("Please download GaCy PS server files first")
|
||||
setIsOpenDownloadDataModal(true)
|
||||
return
|
||||
@@ -203,12 +216,16 @@ export default function LauncherPage() {
|
||||
|
||||
// 1. Start Proxy
|
||||
const activeProxy = proxyPath || "./proxy/firefly-go-proxy.exe"
|
||||
await FSService.LogMessage("INFO", "handleStartGame: activeProxy=" + activeProxy + ", proxyRunning=" + proxyRunning)
|
||||
if (!proxyRunning && !gamePath.endsWith("launcher.exe")) {
|
||||
await FSService.LogMessage("INFO", "handleStartGame: starting proxy via StartWithConsole(" + activeProxy + ")")
|
||||
const [resultProxy, error] = await FSService.StartWithConsole(activeProxy)
|
||||
if (!resultProxy) {
|
||||
await FSService.LogMessage("ERROR", "handleStartGame: proxy start failed: " + error)
|
||||
toast.error(t("home.toast_start_proxy_failed") + ": " + error)
|
||||
return
|
||||
}
|
||||
await FSService.LogMessage("INFO", "handleStartGame: proxy started successfully")
|
||||
setProxyRunning(true)
|
||||
}
|
||||
await sleep(500)
|
||||
@@ -216,39 +233,56 @@ export default function LauncherPage() {
|
||||
// 2. Start SDK Server if exists
|
||||
const activeSdk = sdkServer || sdkServerPath
|
||||
if (activeSdk) {
|
||||
await FSService.StartWithConsole(activeSdk)
|
||||
await FSService.LogMessage("INFO", "handleStartGame: starting SDK server via StartWithConsole(" + activeSdk + ")")
|
||||
const [resultSdk, sdkErr] = await FSService.StartWithConsole(activeSdk)
|
||||
if (!resultSdk) {
|
||||
await FSService.LogMessage("WARN", "handleStartGame: SDK server start warning: " + sdkErr)
|
||||
} else {
|
||||
await FSService.LogMessage("INFO", "handleStartGame: SDK server started successfully")
|
||||
}
|
||||
await sleep(400)
|
||||
}
|
||||
|
||||
// 3. Start Game Server
|
||||
if (!serverRunning) {
|
||||
await FSService.LogMessage("INFO", "handleStartGame: starting Game server via StartWithConsole(" + activeServer + ")")
|
||||
const [resultServer, error] = await FSService.StartWithConsole(activeServer)
|
||||
if (!resultServer) {
|
||||
await FSService.LogMessage("ERROR", "handleStartGame: Game server start failed: " + error)
|
||||
toast.error(t("home.toast_start_server_failed") + ": " + error)
|
||||
return
|
||||
}
|
||||
await FSService.LogMessage("INFO", "handleStartGame: Game server started successfully")
|
||||
setServerRunning(true)
|
||||
}
|
||||
await sleep(1000)
|
||||
} else {
|
||||
await FSService.LogMessage("INFO", "handleStartGame: running in Official Server mode (no proxy/PS)")
|
||||
}
|
||||
|
||||
// 4. Start Game
|
||||
await FSService.LogMessage("INFO", "handleStartGame: starting game binary: " + gamePath)
|
||||
if (gamePath.endsWith("launcher.exe")) {
|
||||
const [resultGame, error] = await FSService.StartWithConsole(gamePath)
|
||||
if (!resultGame) {
|
||||
await FSService.LogMessage("ERROR", "handleStartGame: StartWithConsole game failed: " + error)
|
||||
toast.error(t("home.toast_start_game_failed") + ": " + error)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
const [resultGame, error] = await FSService.StartApp(gamePath)
|
||||
if (!resultGame) {
|
||||
await FSService.LogMessage("ERROR", "handleStartGame: StartApp game failed: " + error)
|
||||
toast.error(t("home.toast_start_game_failed") + ": " + error)
|
||||
return
|
||||
}
|
||||
}
|
||||
await FSService.LogMessage("INFO", "handleStartGame: Game process started successfully!")
|
||||
setGameRunning(true)
|
||||
|
||||
} catch (err: any) {
|
||||
const errStr = err?.stack || err?.message || String(err)
|
||||
await FSService.LogMessage("ERROR", "handleStartGame uncaught exception: " + errStr)
|
||||
console.log(err)
|
||||
toast.error(t("home.toast_start_game_error"), err)
|
||||
} finally {
|
||||
@@ -256,7 +290,6 @@ export default function LauncherPage() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handlerUpdateData = async () => {
|
||||
setIsDownloading(true)
|
||||
if (updateData.launcher.isUpdate) {
|
||||
@@ -486,6 +519,17 @@ export default function LauncherPage() {
|
||||
{t("home.menu_open_voice")}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button onClick={async () => {
|
||||
const [ok, err] = await FSService.OpenLogsFolder()
|
||||
if (!ok) {
|
||||
toast.error("Failed to open logs: " + err)
|
||||
}
|
||||
}}
|
||||
>
|
||||
📋 {t("home.menu_open_logs") || "Open Logs"}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user