小井盖改为自绘 GM 窗口(WebView2)+ 背包可见 + 启动器互斥
- 90CN.dll:新增 90CN_gm_window.cpp,自绘标题栏/边框的置顶窗口,内嵌 WebView2 承载 gmweb 页面 - 点小井盖时隐藏游戏内嵌 IE 面板、弹出控制台;关掉后还原,独占全屏压不住时可选 minimize_game - 窗口每轮确认置顶,避免游戏抢窗口栈后消失 - gmweb:新增背包页,发放后自动跳转并高亮新入包的行(GET /local/dnf-gm/inventory/list) - 启动器:新增 /console-status,控制台运行时置灰 GM 工具入口并阻止进入 - 服务端指纹回绑新 DLL(1258496 / 7A179B1B…)
This commit is contained in:
1 parent
e9a3952a9d
commit
b22579658e
10 files changed
+1246
-97
No files matched your search
+75
-2
@@ -4,7 +4,7 @@
|
||||
'use strict';
|
||||
|
||||
var S = {
|
||||
charId: '', charName: '', chars: [],
|
||||
charId: '', charName: '', chars: [], bagRows: [],
|
||||
itemId: 0, itemName: '', picked: null, items: [],
|
||||
page: 1, pageSize: 20, total: 0
|
||||
};
|
||||
@@ -66,6 +66,7 @@
|
||||
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() {
|
||||
@@ -383,6 +384,10 @@
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -401,6 +406,64 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 背包 */
|
||||
|
||||
/* 背包 / 穿戴的实时快照。GM 发完东西,玩家第一件事就是看它到底进没进包,
|
||||
所以这里按服务端实际存的行来列,不做任何本地猜测。 */
|
||||
function loadBag(highlightItemId) {
|
||||
if (!S.charId) {
|
||||
$('bag-list').innerHTML = '<div class="empty">先在「角色」页选一个角色</div>';
|
||||
$('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 = '<div class="empty">背包是空的</div>';
|
||||
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('<div class="li' + (isNew ? ' on' : '') + '">' +
|
||||
'<span class="nm">' + esc(r.item_name || ('物品 ' + r.item_id)) +
|
||||
(isNew ? ' <em class="new">新</em>' : '') + '</span>' +
|
||||
'<span class="meta">' + (r.collection === 'wear' ? '穿戴' : '背包') +
|
||||
' · ' + esc(r.entry_key) + ' · id ' + esc(r.item_id) +
|
||||
(r.count > 1 ? ' ×' + esc(r.count) : '') + '</span></div>');
|
||||
}
|
||||
box.innerHTML = h.join('');
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- 邮件 */
|
||||
|
||||
function sendMail() {
|
||||
@@ -452,6 +515,7 @@
|
||||
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);
|
||||
|
||||
@@ -473,7 +537,16 @@
|
||||
}
|
||||
|
||||
$('q-char').onkeydown = function (e) { if ((e || window.event).keyCode === 13) { loadChars(); } };
|
||||
$('q-item').onkeydown = function (e) { if ((e || window.event).keyCode === 13) { loadItems(1); } };
|
||||
$('q-item').onkeydown = function (e) {
|
||||
e = e || window.event;
|
||||
// 229 是输入法组合中的键码,这时候的回车是上屏,不能抢。
|
||||
if (e.keyCode === 229) { return; }
|
||||
if (e.keyCode === 13) {
|
||||
if (e.preventDefault) { e.preventDefault(); }
|
||||
loadItems(1);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
fillTypeOptions();
|
||||
|
||||
|
||||
+11
-1
@@ -16,6 +16,7 @@
|
||||
<a class="tab on" data-tab="home" href="javascript:void(0)">状态</a>
|
||||
<a class="tab" data-tab="char" href="javascript:void(0)">角色</a>
|
||||
<a class="tab" data-tab="item" href="javascript:void(0)">发物品</a>
|
||||
<a class="tab" data-tab="bag" href="javascript:void(0)">背包</a>
|
||||
<a class="tab" data-tab="mail" href="javascript:void(0)">邮件</a>
|
||||
</div>
|
||||
|
||||
@@ -79,7 +80,7 @@
|
||||
<button class="btn sm" data-lv="61-90">61-90</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<input id="q-item" class="inp" placeholder="物品名关键字(可留空,用上面分类浏览)">
|
||||
<textarea id="q-item" class="inp ta" rows="1" placeholder="物品名关键字(可留空,用上面分类浏览)"></textarea>
|
||||
<select id="in-page-size" class="inp sm">
|
||||
<option value="10">每页 10 行</option>
|
||||
<option value="20" selected>每页 20 行</option>
|
||||
@@ -126,6 +127,15 @@
|
||||
<div class="hint">强化 0-31、增幅等级 0-31、锻造 0-8。增幅填了就直接覆盖强化(红字装不能同时白字强化),非装备行忽略这些值。</div>
|
||||
</div>
|
||||
|
||||
<div class="pane" id="pane-bag">
|
||||
<div class="row">
|
||||
<button id="btn-bag" class="btn">刷新背包</button>
|
||||
<span id="bag-info" class="pg">-</span>
|
||||
</div>
|
||||
<div id="bag-list" class="list fixed"></div>
|
||||
<div class="hint">发到背包的物品会自动跳到这一页并高亮(标「新」)。列表里没有,就说明没进背包:可能是格位满了,或者这个物品类型不能直接进背包(该走邮箱)。</div>
|
||||
</div>
|
||||
|
||||
<div class="pane" id="pane-mail">
|
||||
<div class="row"><label class="lb">标题</label><input id="in-title" class="inp" value="GM 邮件"></div>
|
||||
<div class="row"><label class="lb">内容</label><input id="in-body" class="inp" value="来自 GM 的问候"></div>
|
||||
|
||||
@@ -53,6 +53,12 @@ table.kv td { padding: 4px 0; border-bottom: 1px solid #232734; color: #dfe3ea;
|
||||
}
|
||||
.inp:focus { border-color: #e8c979; ime-mode: active; }
|
||||
input[type="text"], textarea { ime-mode: active; }
|
||||
/* 搜索框用 textarea:MSHTML 里它的 IME 走编辑引擎,比 input 更容易触发候选框。
|
||||
单行用法,所以要自己压高度、禁掉拉伸和平滚动条。 */
|
||||
.inp.ta {
|
||||
height: 26px; line-height: 18px; resize: none; overflow: hidden;
|
||||
padding: 3px 6px; vertical-align: middle;
|
||||
}
|
||||
.inp.sm { width: 110px; }
|
||||
.inp.xs { width: 60px; }
|
||||
.inp.xs2 { width: 84px; }
|
||||
@@ -99,3 +105,9 @@ select.inp { padding: 3px 2px; }
|
||||
#log .err { color: #e07070; }
|
||||
#log .tip { color: #e8c979; }
|
||||
.hint { color: #666e80; font-size: 11px; margin-top: 6px; }
|
||||
|
||||
/* 背包页:刚发进去那一行的「新」标记 */
|
||||
.li .new {
|
||||
font-style: normal; font-size: 11px; padding: 0 4px; margin-left: 4px;
|
||||
background: #e8c979; color: #1a1e27; border-radius: 2px;
|
||||
}
|
||||
Reference in new issue
Block a user