优化斗地主

This commit is contained in:
李琦
2026-08-18 12:29:50 +08:00
parent 2e995a09dc
commit bc73abbd64
11 changed files with 1587 additions and 367 deletions

View File

@@ -1,9 +1,10 @@
// Electron 主进程:窗口生命周期、应用菜单、后端服务器地址配置、外链拦截
// 加载策略:开发模式(未打包)优先连 Vite 开发服务器5173连不上回退到本地 dist 构建产物;
// 打包后固定加载 asar 内的 dist。渲染进程通过 preload 注入的 window.desktop 获取服务器地址
const { app, BrowserWindow, Menu, Tray, nativeImage, ipcMain, shell, dialog, net } = require('electron')
const { app, BrowserWindow, Menu, Tray, nativeImage, ipcMain, shell, dialog } = require('electron')
const path = require('path')
const fs = require('fs')
const updater = require('./update.cjs')
// 后端服务器默认地址(可在「菜单 → 服务器设置」中修改,保存在用户数据目录)
// 生产桌面端默认连线上;本机调试可在菜单里改回 http://127.0.0.1:8080
@@ -62,102 +63,12 @@ ipcMain.handle('nlg:set-server-base', (_e, url) => {
return { ok: true }
})
// ---------------------------------------------------------------------
// 版本检查:拉取后端 /api/version/latest 与本地 app.getVersion() 比较
// 后端返回 { version, download_url, release_notes, force }
// ---------------------------------------------------------------------
// 语义化版本比较:返回 -1/0/1a<b / a==b / a>b非法版本视为 0.0.0
function compareVer(a, b) {
const pa = String(a || '0').split('.').map((n) => parseInt(n, 10) || 0)
const pb = String(b || '0').split('.').map((n) => parseInt(n, 10) || 0)
const len = Math.max(pa.length, pb.length)
for (let i = 0; i < len; i++) {
const va = pa[i] || 0
const vb = pb[i] || 0
if (va > vb) return 1
if (va < vb) return -1
}
return 0
}
// 拉取一次最新版本信息(用 Electron 内置 net自动走系统代理
function fetchLatestVersion() {
return new Promise((resolve) => {
const base = readCfg().serverBase.replace(/\/+$/, '')
if (!base) return resolve({ ok: false, msg: '未配置服务器地址' })
const req = net.request({
method: 'GET',
url: base + '/api/version/latest',
redirect: 'follow',
})
let body = ''
req.on('response', (resp) => {
// 3xx 已由 redirect:'follow' 处理;这里只关心 2xx 最终响应
resp.on('data', (chunk) => (body += chunk.toString('utf8')))
resp.on('end', () => {
try {
const parsed = JSON.parse(body)
// 后端统一返回 { code, msg, data }code=0 表示成功
const data = parsed && parsed.data ? parsed.data : parsed
resolve({ ok: true, data })
} catch {
resolve({ ok: false, msg: '解析版本信息失败' })
}
})
})
req.on('error', (err) => resolve({ ok: false, msg: '网络错误:' + err.message }))
// 超时兜底10s
setTimeout(() => {
try { req.abort() } catch {}
resolve({ ok: false, msg: '请求超时' })
}, 10000)
req.end()
})
}
// 弹出更新对话框silent=true 表示自动检查,已是最新版不弹窗)
async function checkUpdate(silent = false) {
const local = app.getVersion()
const r = await fetchLatestVersion()
if (!r.ok) {
if (!silent) dialog.showErrorBox('检查更新失败', r.msg || '无法连接服务器')
return
}
const { version, download_url: url, release_notes: notes, force } = r.data || {}
if (compareVer(version, local) <= 0) {
if (!silent) {
dialog.showMessageBox(mainWin, {
type: 'info',
title: '已是最新版本',
message: '当前已是最新版本',
detail: `版本 ${local}`,
})
}
return
}
const buttons = url ? ['立即下载', force ? '确定' : '稍后提醒'] : [force ? '确定' : '稍后提醒']
const { response } = await dialog.showMessageBox(mainWin, {
type: force ? 'warning' : 'info',
title: '发现新版本',
message: `发现新版本 ${version}`,
detail: notes || '请下载最新版本安装包覆盖安装。',
buttons,
defaultId: 0,
cancelId: buttons.length - 1,
noLink: true,
})
// 点了「立即下载」(按钮 0 且存在下载链接);相对路径拼服务器基址
if (response === 0 && url) {
const abs = /^https?:\/\//i.test(url)
? url
: readCfg().serverBase.replace(/\/+$/, '') + (url.startsWith('/') ? url : '/' + url)
shell.openExternal(abs)
}
}
// IPC渲染进程可触发检查更新预留菜单按钮 / 页面入口)
ipcMain.handle('nlg:check-update', (_e, silent) => checkUpdate(silent))
// 版本检查 / 应用内下载安装(见 update.cjs
updater.init({
getServerBase: () => readCfg().serverBase,
getMainWindow: () => mainWin,
setQuitting: (v) => { isQuitting = v },
})
// ---------------------------------------------------------------------
// 服务器设置窗口(极简内嵌页面,深色风格与主站一致)
@@ -244,7 +155,7 @@ function createTray() {
tray.setToolTip('像素游戏厅')
tray.setContextMenu(Menu.buildFromTemplate([
{ label: '显示主窗口', click: () => showMainWindow() },
{ label: '检查更新…', click: () => checkUpdate(false) },
{ label: '检查更新…', click: () => updater.checkUpdate(false) },
{ type: 'separator' },
{
label: '退出',
@@ -268,7 +179,7 @@ function buildMenu() {
label: '应用',
submenu: [
{ label: '服务器设置…', accelerator: 'CmdOrCtrl+,', click: openSettings },
{ label: '检查更新…', click: () => checkUpdate(false) },
{ label: '检查更新…', click: () => updater.checkUpdate(false) },
{ type: 'separator' },
{ label: '刷新', role: 'reload' },
{ label: '强制刷新(忽略缓存)', role: 'forceReload' },
@@ -356,7 +267,7 @@ function createWindow() {
if (cfg.winMax) mainWin.maximize()
mainWin.show()
// 启动后 3 秒静默检查一次更新(已是最新版不弹窗,发现新版本才提示)
setTimeout(() => { checkUpdate(true).catch(() => {}) }, 3000)
setTimeout(() => { updater.checkUpdate(true).catch(() => {}) }, 3000)
})
// 点关闭:记住窗口状态并隐藏到托盘(冒烟模式 / 真正退出时直接关)
mainWin.on('close', (e) => {