GM 页:修复内嵌 IE 输入法 + 物品分类浏览

- 90CN.dll:给 IE 控件窗口链重新关联 IME 上下文,中文输入不再只能打字母
- gmweb:页面加 ime-mode:active,focus 时再主动要一次
- 物品页加分组/类型/等级筛选,不依赖中文输入也能定位物品
- 服务端指纹回绑新 DLL(1223680 / 26633404…)
This commit is contained in:
hanfuit committed 2026-11-05 12:37:03 +08:00
1 parent c4ffa57bf2
commit e9a3952a9d
5 files changed
+176 -17

No files matched your search

+96 -11
View File
@@ -257,23 +257,79 @@
log('已选物品:' + it.name + '(id ' + it.item_id + ')', 'tip');
}
/* 分组 -> 类型选项。装备/时装/宠物走 tag(PVF 的 equipment type),
道具走 segment(服务端按 stackable type 归类成中文段)。
有了这两级下拉,不敲键盘也能把范围缩到十几页。 */
var TYPE_OPTIONS = {
equipment: [
['tag:weapon', '武器'], ['tag:coat', '上衣'], ['tag:shoulder', '头肩'],
['tag:pants', '下装'], ['tag:shoes', '鞋'], ['tag:waist', '腰带'],
['tag:amulet', '项链'], ['tag:wrist', '手镯'], ['tag:ring', '戒指'],
['tag:support', '辅助装备'], ['tag:magic stone', '魔法石'],
['tag:earring', '耳环'], ['tag:support weapon', '辅助武器'],
['tag:title name', '称号'], ['tag:name tag', '名牌']
],
avatar: [
['tag:hat avatar', '帽子'], ['tag:hair avatar', '头发'], ['tag:face avatar', '脸部'],
['tag:coat avatar', '上衣'], ['tag:breast avatar', '胸部'], ['tag:waist avatar', '腰部'],
['tag:pants avatar', '下装'], ['tag:shoes avatar', '鞋'], ['tag:skin avatar', '皮肤'],
['tag:aurora avatar', '光环'], ['tag:weapon avatar', '武器装扮']
],
pet: [
['tag:creature', '宠物'], ['tag:artifact red', '神器·红'],
['tag:artifact blue', '神器·蓝'], ['tag:artifact green', '神器·绿']
],
stackable: [
['seg:消耗品', '消耗品'], ['seg:材料', '材料'], ['seg:特殊材料', '特殊材料'],
['seg:任务品', '任务品'], ['seg:徽章', '徽章'], ['seg:副职业材料', '副职业材料']
]
};
function fillTypeOptions() {
var opts = TYPE_OPTIONS[$('in-group').value] || [];
var h = ['<option value="">不限</option>'];
for (var i = 0; i < opts.length; i++) {
h.push('<option value="' + esc(opts[i][0]) + '">' + esc(opts[i][1]) + '</option>');
}
$('in-tag').innerHTML = h.join('');
}
function loadItems(page) {
var q = $('q-item').value;
var size = parseInt($('in-page-size').value, 10) || 20;
var p = page || 1;
if (p < 1) { p = 1; }
S.pageSize = size;
var offset = (p - 1) * size;
api('/dnf/gm/items/page?limit=' + size + '&offset=' + offset +
'&q=' + encodeURIComponent(q || ''), 'GET', null, function (d) {
if (!d) { return; }
var pageData = d.data || {};
S.items = pageData.items || [];
S.total = pageData.total || 0;
S.page = p;
renderItems();
log('物品 ' + S.items.length + ' 条 / 共 ' + S.total + ' 条');
});
var group = $('in-group').value;
var picked = $('in-tag').value;
var minLv = parseInt($('in-lv-min').value, 10);
var maxLv = parseInt($('in-lv-max').value, 10);
if (isNaN(minLv)) { minLv = 0; }
if (isNaN(maxLv)) { maxLv = 0; }
var qs = 'limit=' + size + '&offset=' + ((p - 1) * size) +
'&q=' + encodeURIComponent(q || '');
if (group) { qs += '&group=' + encodeURIComponent(group); }
if (picked) {
if (picked.indexOf('tag:') === 0) {
qs += '&tag=' + encodeURIComponent(picked.substring(4));
} else if (picked.indexOf('seg:') === 0) {
qs += '&segment=' + encodeURIComponent(picked.substring(4));
}
}
if (minLv > 0) { qs += '&min_level=' + minLv; }
if (maxLv > 0) { qs += '&max_level=' + maxLv; }
api('/dnf/gm/items/page?' + qs, 'GET', null, function (d) {
if (!d) { return; }
var pageData = d.data || {};
S.items = pageData.items || [];
S.total = pageData.total || 0;
S.page = p;
renderItems();
log('物品 ' + S.items.length + ' 条 / 共 ' + S.total + ' 条');
});
}
/* 组装强化/增幅/锻造/品质:增幅优先,红字装不再叠加白字强化。 */
@@ -368,6 +424,17 @@
if (el) { el.onclick = fn; }
}
/* 内嵌 IE 控件的输入法常被游戏主窗口占着,focus 时再主动要一次。
ime-mode:active 是 IE 私有属性,别的浏览器会忽略,不影响兼容。 */
function forceIME() {
var els = document.getElementsByTagName('input');
for (var i = 0; i < els.length; i++) {
els[i].onfocus = function () {
try { this.style.imeMode = 'active'; } catch (e) { }
};
}
}
function init() {
bindTabs();
@@ -389,11 +456,29 @@
bind('btn-mail', sendMail);
$('in-page-size').onchange = function () { loadItems(1); };
$('in-group').onchange = function () { fillTypeOptions(); loadItems(1); };
$('in-tag').onchange = function () { loadItems(1); };
/* 等级快捷档:点一下就把区间填好并重新查,省得手敲。 */
var lvBtns = document.getElementsByTagName('button');
for (var b = 0; b < lvBtns.length; b++) {
var spec = lvBtns[b].getAttribute('data-lv');
if (!spec) { continue; }
lvBtns[b].onclick = function () {
var pair = this.getAttribute('data-lv').split('-');
$('in-lv-min').value = pair[0];
$('in-lv-max').value = pair[1];
loadItems(1);
};
}
$('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); } };
fillTypeOptions();
renderPicked();
forceIME();
log('GM 控制台已加载', 'tip');
loadStatus();
loadChars();
+24 -1
View File
@@ -56,7 +56,30 @@
<div class="pane" id="pane-item">
<div class="row">
<input id="q-item" class="inp" placeholder="物品名关键字,如 太刀 / 强化">
<label class="lb">分组</label>
<select id="in-group" class="inp sm">
<option value="">全部</option>
<option value="equipment">装备</option>
<option value="avatar">时装</option>
<option value="pet">宠物 / 神器</option>
<option value="stackable">道具</option>
<option value="other">其他</option>
</select>
<label class="lb">类型</label>
<select id="in-tag" class="inp sm"><option value="">不限</option></select>
</div>
<div class="row">
<label class="lb">等级</label>
<input id="in-lv-min" class="inp xs" value="">
<span class="dim">~</span>
<input id="in-lv-max" class="inp xs" value="">
<button class="btn sm" data-lv="1-20">1-20</button>
<button class="btn sm" data-lv="21-40">21-40</button>
<button class="btn sm" data-lv="41-60">41-60</button>
<button class="btn sm" data-lv="61-90">61-90</button>
</div>
<div class="row">
<input id="q-item" class="inp" placeholder="物品名关键字(可留空,用上面分类浏览)">
<select id="in-page-size" class="inp sm">
<option value="10">每页 10 行</option>
<option value="20" selected>每页 20 行</option>
+5 -2
View File
@@ -48,8 +48,11 @@ table.kv td { padding: 4px 0; border-bottom: 1px solid #232734; color: #dfe3ea;
background: #0f1116; border: 1px solid #2f3547; color: #dfe3ea;
padding: 4px 6px; font: 12px "Microsoft YaHei", Tahoma, sans-serif;
width: 240px; outline: none;
/* 内嵌 IE 控件里输入法默认是关的,这里强制激活,否则只能打英文 */
ime-mode: active;
}
.inp:focus { border-color: #e8c979; }
.inp:focus { border-color: #e8c979; ime-mode: active; }
input[type="text"], textarea { ime-mode: active; }
.inp.sm { width: 110px; }
.inp.xs { width: 60px; }
.inp.xs2 { width: 84px; }
@@ -83,7 +86,7 @@ select.inp { padding: 3px 2px; }
.empty { padding: 12px; color: #666e80; text-align: center; }
.dim { color: #7c8496; }
.pager { margin: 6px 0 2px; }
.pager .btn.sm { padding: 3px 10px; }
.btn.sm { padding: 3px 10px; font-size: 11px; }
.pg { color: #8d94a6; font-size: 11px; margin: 0 8px; }
#log {