Отдельное соединение с клиентом
mod.clientInterface — канал связи Toolbox с клиентской частью, отдельный от потока игровых пакетов. Он предоставляет информацию о процессе, управление окном и чтение DataCenter. Для клиентского модуля событие ready означает готовность интерфейса; готовность игровых справочников других модулей этим событием автоматически не гарантируется.
Информация о клиенте
mod.clientInterface.info содержит:
| Поле | Значение |
|---|---|
pid, arch |
ID процесса и архитектура (x64/ia32) |
publisher, platform, environment |
Издатель, платформа и окружение |
language |
Язык DataCenter |
path |
Путь к папке клиента, предоставленный интерфейсом |
majorPatchVersion, minorPatchVersion |
Части версии патча из ReleaseRevision |
protocolVersion |
Версия протокола/DataCenter, используемая в C_CHECK_VERSION |
protocol |
Карта имен пакетов и opcode |
sysmsg |
Карта имен и ID системных сообщений |
В интерфейсе модуля также есть сокращения mod.publisher, mod.platform, mod.environment, mod.language, mod.majorPatchVersion, mod.minorPatchVersion, mod.clientFolder. Это информация о подключенном клиенте, а не о языке сайта или системной локали.
Окно и камера
| Метод | Назначение |
|---|---|
flashWindow(count = 5, interval = 0, allowFocused = false) |
Мигание окна/кнопки на панели задач; параметры передаются клиенту |
hasFocus() |
Promise с логическим признаком фокуса окна |
configureCameraShake(enabled, power = 1.0, speed = 1.0) |
Включение тряски камеры и ее параметры |
async function notifyIfInactive(mod) {
try {
if (!(await mod.clientInterface.hasFocus())) {
mod.clientInterface.flashWindow();
}
} catch (error) {
mod.error('Unable to query window focus:', error);
}
}
queryData
mod.queryData(query, queryArgs = null, findAll = false, children = true, attributeFilter = null);
Это сокращение для mod.clientInterface.queryData(...). Метод возвращает Promise. findAll: true запрашивает массив узлов, иначе — один результат. Узел содержит attributes и, если запрошены, children; проверяйте наличие результата перед чтением полей.
Путь вида /ItemData/Item@id=?/ выбирает узлы, @ вводит условия, & объединяет условия. Значения ? берутся из queryArgs по порядку. Поддерживаются =, !=, >, >=, <, <=. Массив в параметре равенства означает выбор из набора; в неравенстве — исключение набора. Это язык запросов DataCenter, а не JavaScript или SQL.
Примеры запросов
// A creature name for the current client language.
const creature = await mod.queryData(
'/StrSheet_Creature/HuntingZone@id=?/String@templateId=?',
[huntingZoneId, templateId]
);
if (creature) mod.log(creature.attributes.name);
// Skill data with two conditions on the same node.
const skill = await mod.queryData(
'/SkillData@huntingZoneId=?/Skill@templateId=?&id=?',
[0, 16060, 10100]
);
// Item names, without child nodes.
const names = await mod.queryData('/StrSheet_Item/String/', [], true, false);
const itemNames = new Map(names.map((node) => [node.attributes.id, node.attributes.string]));
// Abnormality effects are child nodes.
const abnormality = await mod.queryData('/Abnormality/Abnormal@id=?/', [701420]);
if (abnormality) {
for (const effect of abnormality.children) mod.log(effect.attributes);
}
// Hunting zones belonging to the current continent.
const zones = await mod.queryData(
'/ContinentData/Continent@id=?/HuntingZone/', [mod.game.me.zone], true
);
// Comparisons and membership.
const ranked = await mod.queryData('/ItemData/Item@rank>=?/', [12], true, false);
const selected = await mod.queryData('/ItemData/Item@rank=?/', [[11, 12, 13]], true, false);
// Only the requested attributes, no children.
const items = await mod.queryData(
'/ItemData/Item/', [], true, false, ['id', 'combatItemType']
);
Эти фрагменты выполняются внутри async-функции после готовности клиента. Названия таблиц, полей и ID зависят от патча. Для последующих сетевых обработчиков сохраните результат заранее; не делайте одинаковый запрос при каждом пакете.
Ошибки и производительность
Обрабатывайте отклонение Promise через try/catch или .catch(...): неверный запрос, параметры или недоступный интерфейс не должны оставлять необработанную ошибку. Не загружайте весь SkillData, если нужен один навык. Запрос выделяет память на стороне игрового клиента; объемные деревья дороги и для 32-, и для 64-битных клиентов. Используйте children: false, фильтр атрибутов и кеш. Для уже доступных предметов и эффектов сначала проверьте mod.game.data.
Источники: doc/mod/client-interface.md, node_modules/tera-client-interface/index.js, bin/mod.js.