From 06558415daef14b4e775e5e64c1da39be5017a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=B5=E5=AE=9D=E4=BB=99=E5=B0=8A?= Date: Thu, 5 Nov 2026 14:15:41 +0800 Subject: [PATCH] =?UTF-8?q?GM=20=E9=A1=B5=E6=94=B9=E7=89=88=EF=BC=9A?= =?UTF-8?q?=E5=8A=A0=E5=9B=9E=E6=BB=A1=E7=96=B2=E5=8A=B3/=E8=B5=9E?= =?UTF-8?q?=E5=8A=A9=E9=A1=B5=EF=BC=8C=E5=8E=BB=E6=8E=89=E8=83=8C=E5=8C=85?= =?UTF-8?q?=E4=B8=8E=E9=82=AE=E4=BB=B6=E9=A1=B5=E5=92=8C=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 角色页新增「回满疲劳」,走 POST /dnf/gm/characters/{id}/fatigue/refill(需角色下线) - 新增「赞助」页:支付宝 / 微信收款码占位,图放 gmweb/qr/ 下即显示 - 删除背包页与邮件页(发到邮箱按钮保留在发物品页) - 去掉页头「GM 控制台」文字(窗口标题栏已画标题,重复),页头只留连接状态 - serve.py 补 jpg/jpeg/gif/webp/bmp/svg 的 MIME - 控制台宽度 1040 -> 920 --- client-patch/90CN_web.ini | 2 +- gmweb/app.js | 110 ++++++++++-------------------------- gmweb/index.html | 42 +++++++------- gmweb/qr/放收款码到这里.txt | 11 ++++ gmweb/serve.py | 6 ++ gmweb/style.css | 23 ++++++-- 6 files changed, 91 insertions(+), 103 deletions(-) create mode 100644 gmweb/qr/放收款码到这里.txt diff --git a/client-patch/90CN_web.ini b/client-patch/90CN_web.ini index 09e7023..b22d94d 100644 --- a/client-patch/90CN_web.ini +++ b/client-patch/90CN_web.ini @@ -15,7 +15,7 @@ minimize_game=0 ; (推荐,原面板不会残留、也不会再露面);0 = 把面板放回去(老行为,会看到旧 IE 页面) close_action=1 ; 我们自己的窗口尺寸 -width=1040 +width=920 height=720 ; 目标页面。必须是本地 http,避免浏览器弹证书提示。 url=http://127.0.0.1:18112/ diff --git a/gmweb/app.js b/gmweb/app.js index 1e6ba5a..f248463 100644 --- a/gmweb/app.js +++ b/gmweb/app.js @@ -4,7 +4,7 @@ 'use strict'; var S = { - charId: '', charName: '', chars: [], bagRows: [], + charId: '', charName: '', chars: [], itemId: 0, itemName: '', picked: null, items: [], page: 1, pageSize: 20, total: 0 }; @@ -66,7 +66,6 @@ for (var j = 0; j < panes.length; j++) { panes[j].className = 'pane' + (panes[j].id === 'pane-' + name ? ' on' : ''); } - if (name === 'bag') { loadBag(0); } } function bindTabs() { @@ -156,6 +155,17 @@ return true; } + /* 一键回满疲劳:直接把库里 fatigue 写回上限。 + 服务端要求角色已下线(在线时写库会被下一个存档覆盖),所以在线角色会报错。 */ + function refillFatigue() { + if (!requireChar()) { return; } + api('/dnf/gm/characters/' + S.charId + '/fatigue/refill', 'POST', {}, function (d) { + if (!d) { return; } + log('已回满 ' + S.charName + ' 的疲劳值', 'ok'); + loadChars(); + }); + } + /* ---------------------------------------------------------------- 物品 */ /* 装备类型标签:PVF 里是 "[weapon]" 这种,去掉括号后映射成中文。 */ @@ -384,10 +394,7 @@ var data = d.data || {}; log('已发 ' + S.itemName + ' ×' + n + optText(o) + (data.slot != null ? ',格位 ' + data.list_type + ':' + data.slot : ''), 'ok'); - // 发完立刻切到背包页并高亮这一行:到底有没有进包,玩家要看得见 - switchTab('bag'); - loadBag(S.itemId); - setTimeout(function () { loadBag(S.itemId); }, 600); + // 回游戏里看背包即可(客户端会自动刷新),这里不再切页打断操作 }); } @@ -406,78 +413,22 @@ }); } - /* ---------------------------------------------------------------- 背包 */ + /* ---------------------------------------------------------------- 赞助 */ - /* 背包 / 穿戴的实时快照。GM 发完东西,玩家第一件事就是看它到底进没进包, - 所以这里按服务端实际存的行来列,不做任何本地猜测。 */ - function loadBag(highlightItemId) { - if (!S.charId) { - $('bag-list').innerHTML = '
先在「角色」页选一个角色
'; - $('bag-info').innerHTML = '-'; - return; - } - api('/local/dnf-gm/inventory/list?character_id=' + encodeURIComponent(S.charId), - 'GET', null, function (d) { - if (!d) { return; } - var data = d.data || {}; - S.bagRows = data.rows || []; - renderBag(highlightItemId || 0); - }); - } - - function renderBag(highlightItemId) { - var box = $('bag-list'); - var rows = S.bagRows || []; - var bagCount = 0, wearCount = 0, i; - for (i = 0; i < rows.length; i++) { - if (rows[i].collection === 'wear') { wearCount++; } else { bagCount++; } - } - $('bag-info').innerHTML = '背包 ' + bagCount + ' 件 · 穿戴 ' + wearCount + ' 件'; - - if (!rows.length) { - box.innerHTML = '
背包是空的
'; - return; - } - - // 刚发进去的排在最前面,其余保持服务端顺序 - var ordered = []; - if (highlightItemId) { - for (i = 0; i < rows.length; i++) { - if (rows[i].item_id === highlightItemId) { ordered.push(rows[i]); } - } - } - for (i = 0; i < rows.length; i++) { - if (!highlightItemId || rows[i].item_id !== highlightItemId) { ordered.push(rows[i]); } - } - - var h = []; - for (i = 0; i < ordered.length; i++) { - var r = ordered[i]; - var isNew = highlightItemId && r.item_id === highlightItemId; - h.push('
' + - '' + esc(r.item_name || ('物品 ' + r.item_id)) + - (isNew ? ' 新' : '') + '' + - '' + (r.collection === 'wear' ? '穿戴' : '背包') + - ' · ' + esc(r.entry_key) + ' · id ' + esc(r.item_id) + - (r.count > 1 ? ' ×' + esc(r.count) : '') + '
'); - } - box.innerHTML = h.join(''); - } - - /* ---------------------------------------------------------------- 邮件 */ - - function sendMail() { - if (!requireChar()) { return; } - var gold = parseInt($('in-goldmail').value, 10) || 0; - api('/local/dnf-gm/mail', 'POST', { - character_name: S.charName, - title: $('in-title').value || 'GM 邮件', - body: $('in-body').value || '', - gold: gold, - attachments: [] - }, function (d) { - if (d) { log('邮件已发送给 ' + S.charName, 'ok'); } - }); + /* 收款码图片是可选的:放了就显示,没放(404)就把占位提示顶上来。 */ + function bindQr(id) { + var img = $(id); + if (!img) { return; } + img.onerror = function () { + var box = this.parentNode; + if (box) { box.className = 'qr-box miss'; } + this.style.display = 'none'; + }; + img.onload = function () { + var box = this.parentNode; + if (box) { box.className = 'qr-box'; } + this.style.display = ''; + }; } /* ---------------------------------------------------------------- 启动 */ @@ -515,9 +466,8 @@ bind('btn-prev', function () { if (S.page > 1) { loadItems(S.page - 1); } }); bind('btn-next', function () { loadItems(S.page + 1); }); bind('btn-grant', grantItem); - bind('btn-bag', function () { loadBag(0); }); bind('btn-mailitem', mailItem); - bind('btn-mail', sendMail); + bind('btn-fatigue', refillFatigue); $('in-page-size').onchange = function () { loadItems(1); }; $('in-group').onchange = function () { fillTypeOptions(); loadItems(1); }; @@ -549,6 +499,8 @@ }; fillTypeOptions(); + bindQr('qr-alipay'); + bindQr('qr-wechat'); renderPicked(); forceIME(); diff --git a/gmweb/index.html b/gmweb/index.html index ea78a0f..3f4057d 100644 --- a/gmweb/index.html +++ b/gmweb/index.html @@ -8,7 +8,6 @@
-
GM 控制台
连接中…
@@ -16,8 +15,7 @@ 状态 角色 发物品 - 背包 - 邮件 + 赞助
@@ -53,6 +51,11 @@
+
疲劳
+
+ + 角色需先在游戏里下线(回到角色选择)才能写库 +
@@ -127,23 +130,24 @@
强化 0-31、增幅等级 0-31、锻造 0-8。增幅填了就直接覆盖强化(红字装不能同时白字强化),非装备行忽略这些值。
-
-
- - - +
+
赞助支持
+
服务器长期免费维护。如果玩得开心,可以扫码赞助一点,金额随意,感谢支持。
+
+
+
支付宝
+
支付宝收款码 +
二维码未配置
gmweb\qr\alipay.png
+
+
+
+
微信
+
微信收款码 +
二维码未配置
gmweb\qr\wechat.png
+
+
-
-
发到背包的物品会自动跳到这一页并高亮(标「新」)。列表里没有,就说明没进背包:可能是格位满了,或者这个物品类型不能直接进背包(该走邮箱)。
-
- -
-
-
-
-
- -
-
收件人取「角色」页选中的角色;未选中会提示。
+
把收款码图片按上面的文件名放进 gmweb\qr\ 目录,刷新这一页就会显示;换成 jpg 也可以,改一下上面的文件名后缀即可。
diff --git a/gmweb/qr/放收款码到这里.txt b/gmweb/qr/放收款码到这里.txt new file mode 100644 index 0000000..0844e0f --- /dev/null +++ b/gmweb/qr/放收款码到这里.txt @@ -0,0 +1,11 @@ +把收款码图片放到这个目录,文件名固定为: + + alipay.png 支付宝收款码 + wechat.png 微信收款码 + +说明: +- 建议正方形图片(页面按 194x194 显示,非正方形会被拉伸) +- 支持 png / jpg / jpeg / gif / bmp / webp / svg +- 用 jpg 的话,把 gmweb\index.html 里对应 的后缀改成 .jpg 即可 +- 换图后刷新控制台页面(标题栏的刷新按钮)就能看到,不用重启服务 +- 图片没放时,赞助页显示「二维码未配置」占位,不影响其他功能 diff --git a/gmweb/serve.py b/gmweb/serve.py index 7acdd9a..aa46237 100644 --- a/gmweb/serve.py +++ b/gmweb/serve.py @@ -32,6 +32,12 @@ MIME = { ".js": "application/javascript; charset=utf-8", ".css": "text/css; charset=utf-8", ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", + ".webp": "image/webp", + ".bmp": "image/bmp", + ".svg": "image/svg+xml", ".ico": "image/x-icon", } diff --git a/gmweb/style.css b/gmweb/style.css index 35ea91f..689c18d 100644 --- a/gmweb/style.css +++ b/gmweb/style.css @@ -6,11 +6,10 @@ html, body { overflow: hidden; } #hd { - height: 30px; padding: 0 10px; + height: 26px; padding: 0 10px; background: #1d2029; border-bottom: 1px solid #2b3040; - line-height: 30px; + line-height: 26px; } -#hd-t { float: left; font-weight: bold; color: #e8c979; letter-spacing: 1px; } #hd-s { float: right; color: #8d94a6; } .dot { display: inline-block; width: 7px; height: 7px; border-radius: 4px; margin-right: 6px; } .dot.on { background: #4ec46a; } @@ -24,7 +23,7 @@ html, body { .tab:hover { color: #d8dbe2; } .tab.on { color: #e8c979; border-bottom-color: #e8c979; background: #20242e; } -#body { position: absolute; top: 59px; bottom: 62px; left: 0; right: 0; overflow: auto; } +#body { position: absolute; top: 55px; bottom: 62px; left: 0; right: 0; overflow: auto; } .pane { display: none; padding: 10px; } .pane.on { display: block; } @@ -111,3 +110,19 @@ select.inp { padding: 3px 2px; } font-style: normal; font-size: 11px; padding: 0 4px; margin-left: 4px; background: #e8c979; color: #1a1e27; border-radius: 2px; } + +/* 赞助页:收款码(IE11 不支持 flex,用 float 排两列) */ +.qr-wrap { overflow: hidden; margin-top: 10px; } +.qr-card { + float: left; width: 216px; margin: 0 14px 10px 0; + background: #1a1e27; border: 1px solid #2b3040; padding: 10px; +} +.qr-title { color: #e8c979; letter-spacing: 1px; margin-bottom: 8px; } +.qr-box { + width: 194px; height: 194px; position: relative; overflow: hidden; + background: #0f1116; border: 1px dashed #3a4154; text-align: center; +} +.qr-box img { display: block; width: 194px; height: 194px; } +.qr-miss { display: none; padding-top: 72px; color: #666e80; line-height: 1.8; } +.qr-box.miss .qr-miss { display: block; } +.qr-path { color: #4c5365; font-size: 11px; margin-top: 2px; }