Добро пожаловать на Wargaming.net Wiki!
/
ModsettingsAPI

ModsettingsAPI

Перейти к: навигация, поиск

version 1.1.2, 2019-01-22
License: CC BY-SA 4.0

Общая информация

modsSettingsApi - это модификация клиента игры World of Tanks, которая предоставляет сторонним разработчикам инструментарий для создания удобного меню настроек.

Основные этапы работы модификации заключается в следующем:

  1. При загрузке клиента игры modsSettingsApi загружает файл сохраненных настроек сторонних модификаций. Если файл отсутствует - будет создан новый.
  2. Затем modsSettingsApi ожидает подключения к себе сторонних модификаций посредством программного интерфейса.
  3. Для генерации меню настроек, сторонняя модификация должна отправить в modsSettingsApi шаблон, содержащий в себе описание необходимых для отображения графических элементов.
  4. Кроме шаблона сторонняя модификация должна отправить ссылку на функцию, которая будет вызываться при любом изменении настроек стороннего мода. При необходимости обработки нажатия дополнительных кнопок модификация должна отправить ссылку на функцию, которая будет вызывается при нажатии на кнопку с передачей текущего значения.
  5. При изменении настроек modsSettingsApi будет вызывать переданный модификацией метод с новыми параметрами. При использовании кнопок, ModSettingsAPI будет вызывать переданный модификацией метод с текущим параметром и его значением.


Процесс подключения модификации к modsSettingsApi выглядит следующим образом:

# Текстовый идентификатор мода.
# ! ДОЛЖЕН быть уникальным для каждого мода
modLinkage = 'myOwnMod'


# Словарь для хранения настроек мода
settings = { ... }


# Словарь с шаблоном стандартных настроек
template = { ... }


# Функция, которая будет вызываться настройщиком при изменении настроек мода.
# linkage - текстовый идентификатор мода,
# settings - словарь с новыми настройками
def onSettingsChanged(linkage, settings):
if linkage == modLinkage:
# ваш обработчик настроек


# Функция, которая будет вызываться настройщиком при клике по доп кнопкам.
# linkage - текстовый идентификатор мода
# varName - имя параметра
# value текущее значение параметра выбранное в интерфейсе
def onButtonClicked(linkage, varName, value):
if linkage == modLinkage:
# ваш обработчик настроек


try:
# Попытка импорта общей точки входа настройщика
from gui.modsSettingsApi import g_modsSettingsApi
# сначала необходимо запросить у настройщика сохраненные настройки
savedSettings = g_modsSettingsApi.getModSettings((modLinkage, ), template)
# если настройки имеются
if savedSettings:
# Применим их
settings = savedSettings
# Зарегистрируем функцию-обработчик новых настроек, и функцию-обработчик нажатий (если таковая имеется)
g_modsSettingsApi.registerCallback((modLinkage, ), onSettingsChanged, onButtonClicked)
# если настроек нет
else:
# Отправим в настройщик шаблон стандартных настроек, функцию-обработчик новых настроек, и функцию-обработчик нажатий (если таковая имеется)
settings = g_modsSettingsApi.setModTemplate((modLinkage, ), template, onSettingsChanged, onButtonClicked)
except:
# Если попытка импорта не удалась
# Используем стандартные настройки мода или загружаем их из самописного конфига
pass

При изменении настроек в функцию-обработчик новых настроек отправляются текстовый идентификатор мода и его новые настройки в виде словаря. Названия переменных (varName) указываются в шаблоне.

onSettingsChanged(linkage, settings)
linkage # 'myOwnMod'
settings # { 'varName': 'varValue', 'varName1': 'varValue1' }

При использовании дополнительного обработчика нажатий в функцию-обработчик будет отправляться текстовый идентификатор мода, название переменной и ее текущее значение. Названия переменных (varName) указываются в шаблоне.

onButtonClicked(linkage, varName, value)
linkage # 'myOwnMod'
varName # 'varName'
value # 'varValue'

Общие положения при создании шаблона

Каждый шаблон - это словарь с обязательными полями. В чистом виде он выглядит так:

template = {


# Отображаемое имя модификации
'modDisplayName': 'Название модификации',


# Версия шаблона. При любых изменениях нуждается в изменении
'settingsVersion': 0,


# Статус модификации. Активирована она в настройщике или нет
'enabled': True,


# Первая колонка отображаемых элементов.
# Отрисовка графических элементов начинается с X = 0
'column1': [ ],


# Вторая колонка отображаемых элементов.
# Отрисовка графических элементов начинается с X = ШИРИНА_ОКНА / 2
'column2': [ ]
}

Для добавления полей для отображения в списки 'column1' и 'column2' добавляются словари, содержащие в себе описания элементов для отображения.
Для добавления динамических кнопок к элементам используются настройки внутри параметра "button". Динамические кнопки можно добавлять только к элементам с пометкой "Возможность добавления кнопки с действием". Более детальный разбор смотрите после списка элементов.
Для добавления всплывающих подсказок к элементам используется параметр "tooltip". Всплывающие подсказки можно добавлять только к элементам с пометкой "Возможность добавления подсказки". Более детальный разбор смотрите после списка элементов.

Список элементов для отображения

Надпись

  • Возможность добавления подсказки.
{
# Тип элемента
'type': 'Label',
# Отображаемый текст
'text': 'My Label'
}

Флажок

  • Возможность добавления подсказки
  • Возможность добавления кнопки с действием
{
# Тип элемента
'type': 'CheckBox',
# Текст, отображаемый рядом с чекбоксом
'text': 'My CheckBox',
# Стандартное значение. True - галочка стоит, False - отсутствует
'value': True,
# Имя переменной, соответствующей значению данного элемента
'varName': 'CheckBox1'
}

Горячая клавиша

  • Возможность добавления подсказки
{
# Тип элемента
'type': 'HotKey',
# Текст, отображаемый слева от элемента ввода
'text': 'My HotKey',
# Стандартное значение. Число обозначающее кнопку (смотрите дополнение с кнопками)
'value': [Keys.KEY_Q],
# Имя переменной, соответствующей значению данного элемента
'varName': 'HotKey1'
}

Ползунок

  • Возможность добавления подсказки
  • Возможность добавления кнопки с действием
{
# Тип элемента
'type': 'Slider',
# Заголовок, отображаемый над слайдером
'text': 'My Slider',
# Минимальное значение слайдера
'minimum': 1,
# Максимальное значение слайдера
'maximum': 15,
# Шаг слайдера
'snapInterval': 1,
# Стандартное значение. Minimum - ползунок слайдера вначале, Maximum - ползунок слайдера в конце
'value': 5,
# Формат строки, отображаемой рядом со слайдером и показывающей его значение. {{{1}}} - заменяется на значение слайдера
'format': '{{{1}}}',
# Имя переменной, соответствующей значению данного элемента
'varName': 'Slider1'
}

Выпадающий список

  • Возможность добавления подсказки
  • Возможность добавления кнопки с действием
{
# Тип элемента
'type': 'Dropdown',
# Заголовок, отображаемый над выпадающим списком
'text': 'My Dropdown',
# Пункты меню
'options': [
# Пункт меню с индексом 0
{ 'label': 'Dropdown 1' },
# Пункт меню с индексом 1
{ 'label': 'Dropdown 2' }
],
# Ширина выпадающего списка
'width': 200,
# Индекс выбранного элемента. 0 - выбран первый элемент списка
'value': 0,
# Имя переменной, соответствующей значению данного элемента
'varName': 'Dropdown1'
}

Группа радио-кнопок

  • Возможность добавления подсказки
  • Возможность добавления кнопки с действием
{
# Тип элемента
'type': 'RadioButtonGroup',
# Заголовок, отображаемый над группой элементов
'text': 'My RadioButtonGroup',
# Список кнопок
'options': [
# Пункт группы с индексом 0
{ 'label': 'RadioButton 1' },
# Пункт группы с индексом 1
{ 'label': 'RadioButton 2' }
],
# Стандартное значение. 0 - выбран первый элемент списка кнопок
'value': 0,
# Имя переменной, соответствующей значению данного элемента
'varName': 'RadioButtonGroup1'
}

Поле ввода текста

  • Возможность добавления подсказки
{
# Тип элемента
'type': 'TextInput',
# Заголовок, отображаемый над полем ввода
'text': 'My TextInput',
# Ширина поля ввода
'width': 200,
# Стандартное значение. Любой текст
'value': 'any text',
# Имя переменной, соответствующей значению данного элемента
'varName': 'TextInput1'
}

Пустой элемент

  • Необходим для логического разделения блоков элементов
  • Высота 20 пикселей
{
# Тип элемента
'type': 'Empty'
}

Динамическая кнопка

  • Прикрепляется к элементам
  • По нажатию передает в Python текущее значение элемента
  • Может быть как текстовой так и с иконкой
  • Поддерживает изменение положения и размера
{
# Параметры вашего элемента
...
# Динамическая кнопка
'button': {
# Ширина кнопки. Можно не указывать. Стандартно 60 пикселей
'width': 60,
# Высота кнопки. Можно не указывать. Стандартно 24 пикселей
'height': 24,
# Смещение положения по вертикали. Можно не указывать
'offsetTop': 0,
# Смещение положения по горизонтали. Можно не указывать
'offsetLeft': 0,
# Текст кнопки. Если используете иконку оставьте пустым
'text': 'Button Text',
# Путь к иконке. Если используете текст оставьте пустым
'iconSource': '../maps/icons/buttons/sound.png',
# Смещение иконки по вертикали. Можно не указывать
'iconOffsetTop': 0,
# Смещение иконки по горизонтали. Можно не указывать
'iconOffsetLeft': 1
}
}

Всплывающая подсказка

  • Прикрепляется к элементам
  • По наведению отображает подсказку
{
# Параметры вашего элемента
...
# Подсказка (при наведении на иконку)
'tooltip': '{HEADER}Tooltip header{/HEADER}{BODY}Tooltip body{/BODY}'
}

Для корректного отображения всплывающих подсказок "tooltip" поля с их текстом должны иметь следующий формат: {HEADER}Заголовок подсказки{/HEADER}{BODY}Текст подсказки{/BODY} Для отображения подсказки без заголовка достаточно просто не указывать тег {HEADER}, т.е текст подсказки должен выглядеть следующим образом: {BODY}Текст подсказки{/BODY}

Пример шаблона настроек модификации

template = {
'modDisplayName': 'Мод «Я обнаружен»',
'settingsVersion': 0,
'enabled': True,
'column1': [
{
'type': 'CheckBox',
'text': 'Показать на миникарте квадрат засвета',
'value': True,
'tooltip': '{HEADER}Показать на миникарте квадрат засвета{/HEADER}{BODY}При вашем обнаружении мод автоматические кликнет на миникарте в квадрат где вы находитесь{/BODY}',
'varName': 'minimapClick'
},
{
'type': 'CheckBox',
'text': 'Сообщить в командный чат «Нужна помощь!»',
'value': True,
'tooltip': '{HEADER}Сообщить в командный чат «Нужна помощь!»{/HEADER}{BODY}При вашем обнаружении мод автоматически отправит команду «Нужна помощь!» вашим союзникам{/BODY}',
'varName': 'neadHelp'
},
{
'type': 'Dropdown',
'text': 'Озвучка «Шестого чувства»',
'tooltip': '{HEADER}Озвучка «Шестого чувства»{/HEADER}{BODY}При срабатывании навыка «Шестого чувства» будет воспроизводиться один из нескольких вариантов озвучки{/BODY}',
'options': [
{ 'label': 'Стандартная' },
{ 'label': 'Тихая' },
{ 'label': 'Громкая' }
],
'button': {
'width': 30,
'height': 23,
'iconSource': '../maps/icons/buttons/sound.png',
'iconOffsetLeft': 1,
},
'width': 200,
'value': 0,
'varName': 'sixthSenseSound'
}
],
'column2': [
{
'type': 'Slider',
'text': 'Число живых союзников для активации мода',
'minimum': 1,
'maximum': 15,
'snapInterval': 1,
'value': 5,
'format': '{{{1}}}',
'varName': 'aliveCounter'
},
{
'type': 'CheckBox',
'text': 'Всегда оповещать о засвете при игре на артиллерии',
'tooltip': '{HEADER}Всегда оповещать о засвете при игре на артиллерии{/HEADER}{BODY}Если вы вышли в бой на артиллерии, мод будет всегда оповещать о вашем засвете независимо от выставленного лимита на число оставшихся в живых союзниках{/BODY}',
'value': True,
'varName': 'alwaysOnArty'
},
{
'type': 'HotKey',
'text': 'Включение/отключение по кнопке',
'tooltip': '{HEADER}Включение/отключение по кнопке{/HEADER}{BODY}Активирует либо деактивирует модификацию при нажатии кнопки/комбинации кнопок{/BODY}',
'value': [Keys.KEY_J],
'varName': 'stateKeySet'
}
]
}

В результате отправки такого шаблона в настройщик и последующего запроса настроек или при их изменении в функцию-обработчик поступит словарь следующего вида:

{
'sixthSenseSound' : 0,
'stateKeySet' : [36],
'alwaysOnArty' : True,
'neadHelp' : True,
'enabled' : True,
'minimapClick' : True,
'aliveCounter' : 5
}

Такой вариант настроек в игре будет выглядеть следующим образом:

ModsettingsAPI.png


Полный пример реализации настроек посредством ModsettingsApi представлен ниже:

import Keys


modLinkage = 'test_iamspotted'


template = {
'modDisplayName': 'Мод «Я обнаружен»',
'settingsVersion': 0,
'enabled': True,
'column1': [
{
'type': 'CheckBox',
'text': 'Показать на миникарте квадрат засвета',
'value': True,
'tooltip': '{HEADER}Показать на миникарте квадрат засвета{/HEADER}{BODY}При вашем обнаружении мод автоматические кликнет на миникарте в квадрат где вы находитесь{/BODY}',
'varName': 'minimapClick'
},
{
'type': 'CheckBox',
'text': 'Сообщить в командный чат «Нужна помощь!»',
'value': True,
'tooltip': '{HEADER}Сообщить в командный чат «Нужна помощь!»{/HEADER}{BODY}При вашем обнаружении мод автоматически отправит команду «Нужна помощь!» вашим союзникам{/BODY}',
'varName': 'neadHelp'
},
{
'type': 'Dropdown',
'text': 'Озвучка «Шестого чувства»',
'tooltip': '{HEADER}Озвучка «Шестого чувства»{/HEADER}{BODY}При срабатывании навыка «Шестого чувства» будет воспроизводиться один из нескольких вариантов озвучки{/BODY}',
'options': [
{ 'label': 'Стандартная' },
{ 'label': 'Тихая' },
{ 'label': 'Громкая' }
],
'button': {
'width': 30,
'height': 23,
'iconSource': '../maps/icons/buttons/sound.png',
'iconOffsetLeft': 1,
},
'width': 200,
'value': 0,
'varName': 'sixthSenseSound'
}
],
'column2': [
{
'type': 'Slider',
'text': 'Число живых союзников для активации мода',
'minimum': 1,
'maximum': 15,
'snapInterval': 1,
'value': 5,
'format': '{{{1}}}',
'varName': 'aliveCounter'
},
{
'type': 'CheckBox',
'text': 'Всегда оповещать о засвете при игре на артиллерии',
'tooltip': '{HEADER}Всегда оповещать о засвете при игре на артиллерии{/HEADER}{BODY}Если вы вышли в бой на артиллерии, мод будет всегда оповещать о вашем засвете независимо от выставленного лимита на число оставшихся в живых союзниках{/BODY}',
'value': True,
'varName': 'alwaysOnArty'
},
{
'type': 'HotKey',
'text': 'Включение/отключение по кнопке',
'tooltip': '{HEADER}Включение/отключение по кнопке{/HEADER}{BODY}Активирует либо деактивирует модификацию при нажатии кнопки/комбинации кнопок{/BODY}',
'value': [Keys.KEY_J],
'varName': 'stateKeySet'
}
]
}


settings = {
'sixthSenseSound' : 0,
'stateKeySet' : [Keys.KEY_J],
'alwaysOnArty' : True,
'neadHelp' : True,
'enabled' : True,
'minimapClick' : True,
'aliveCounter' : 5
}


def onModSettingsChanged(linkage, newSettings):
if linkage == modLinkage:
print 'onModSettingsChanged', newSettings


def onButtonClicked(linkage, varName, value):
if linkage == modLinkage:
print 'onButtonClicked', linkage, varName, value


def onGameKeyDown(event):
if g_modsSettingsApi.checkKeySet(settings['stateKeySet']):
print 'onHandleKeyEvent', settings['stateKeySet']


try:
from gui.modsSettingsApi import g_modsSettingsApi
savedSettings = g_modsSettingsApi.getModSettings((modLinkage, ), template)
if savedSettings:
settings = savedSettings
g_modsSettingsApi.registerCallback((modLinkage, ), onModSettingsChanged, onButtonClicked)
else:
settings = g_modsSettingsApi.setModTemplate((modLinkage, ), template, onModSettingsChanged, onButtonClicked)
except:
pass

Дополнительные возможности модификации

Замена надписей в настройщике

Настройщик предоставляет возможность замены некоторых стандартных надписей в окне. Для этого необходимо отредактировать следующий файл:

“<Папка с игрой>\mods\configs\modsSettingsApi.json”

Так например можно задать свой текст для следующих надписей:

{
"modsListApiName": "",
"modsListApiDescription": "",
"modsListApiIcon": "",
"windowTitle": "Настройщик модов от крутого танкиста",
"buttonOK": "",
"buttonCancel": "",
"buttonApply": "",
"enableButtonTooltip": ""
}
  • modsListApiName - название в списке модификаций
  • modsListApiDescription - всплывающая подсказка в списке модификаций
  • modsListApiIcon - путь к иконке в списке модификаций
  • windowTitle - заголовок окна настройщика.
  • buttonOK- текст кнопки “Ок”.
  • buttonCancel - текст кнопки “Отмена”.
  • buttonApply - текст кнопки “Применить”.
  • enableButtonTooltip - текст подсказки для кнопки включения/выключения мода.

Если вы желаете оставить стандартный текст, то достаточно просто оставить эти поля пустыми.

Ручное изменение настроек

Объект g_modsSettingsApi имеет метод для ручного обновления настроек (например для возможности модом считывать настройки из своего конфига и хранить их в настройщике). После вызова данного метода новые настройки через callback (onModSettingsChanged) вернутся в мод.

g_modsSettingsApi.updateModSettings((modLinkage, ), newSettings)

Ссылка на скачивание

Репозиторий модификации на Bitbucket