Команда это то, что игрок пишет в чат с точкой в начале: .help, .py list. Скрипт может добавить свою, и она будет работать наравне со встроенными: попадёт в .help и в подсказки чата.
@command("hello")
def hello(ctx):
"""Здоровается"""
ctx.msg("Привет!")Теперь .hello в чате пишет приветствие. Первая строчка описания в тройных кавычках попадает в .help, так что отдельно её задавать не нужно. Если хочется, есть и явный способ, вместе с короткими именами:
@command("hello", desc="Здоровается", aliases=["hi", "привет"])
def hello(ctx):
ctx.msg("Привет!")Аргумент ctx это то, с чем команду вызвали, и заодно быстрый ответ в чат. Если он не нужен, функцию можно объявить совсем без аргументов.
| Что у ctx | Что это |
|---|---|
ctx.msg(text) | Ответить игроку в чат |
ctx.warn(text) / ctx.error(text) | То же самое, но жёлтым и красным |
ctx.overlay(text) | Надпись над панелью быстрого доступа |
ctx.name | Имя команды, которую вызвали |
ctx.args | Список аргументов, как их разобрал клиент |
ctx.get(i, default) | Аргумент по номеру, с запасным значением |
Аргументы команды это обычные аргументы функции. Клиент сам разберёт то, что игрок написал в чате, и передаст в том же порядке.
@command("tp")
def tp(ctx, x: int, y: int, z: int):
"""Телепорт по координатам"""
ctx.msg("Иду в %d %d %d" % (x, y, z))
newton.goto(x, y, z, radius=1)Тип пишется как подсказка после двоеточия. Он решает две вещи: во что превратится текст из чата и что скажут игроку, если он ошибся. На .tp сюда 64 0 команда не выполнится, а в чат придёт понятная ошибка про первый аргумент.
| Тип | Что приходит в функцию |
|---|---|
без типа или str | Строка как есть |
int | Целое число |
float | Дробное число |
bool | Да или нет. Понимает true/false, on/off, да/нет, 1/0 |
"player" | Ник строкой, в подсказках игроки рядом |
"module" | Имя модуля клиента, с проверкой что такой есть |
"block" | Имя блока, с проверкой и подсказками |
Значение по умолчанию делает аргумент необязательным, а звёздочка перед именем собирает весь остаток строки.
@command("stay")
def stay(ctx, seconds: int = 10):
"""Стоять на месте, по умолчанию 10 секунд"""
ctx.msg("Стою %d сек" % seconds)
@command("say")
def say(ctx, *words):
"""Повторяет всё, что написали после команды"""
if not words:
ctx.warn("Нечего повторять")
return
ctx.msg(" ".join(words))Пока игрок печатает команду, клиент показывает варианты. У типов "player", "module" и "block" они уже есть. Свои задают через suggests: имя аргумента и список вариантов.
@command("mode", suggests={"value": ["fast", "slow", "off"]})
def mode(ctx, value="fast"):
"""Переключает режим"""
ctx.msg("Режим: " + value)Список может быть не готовым заранее, а считаться в момент ввода. Тогда вместо списка передают функцию: ей приходит то, что игрок успел набрать, а вернуть она должна список вариантов.
db = Storage("warps")
@command("warp", suggests={"name": lambda partial: list(db.all().keys())})
def warp(ctx, name):
"""Идёт к сохранённой точке"""
point = db.get(name)
if point is None:
ctx.error("Точки '%s' нет" % name)
return
newton.goto(point, radius=1)Когда действий несколько, их вешают на одну команду: .warps add, .warps del. Подкоманду объявляют декоратором sub у уже созданной команды.
db = Storage("warps")
@command("warps")
def warps(ctx):
"""Список сохранённых точек"""
names = list(db.all().keys())
ctx.msg("Точки: " + (", ".join(names) if names else "пусто"))
@warps.sub("add")
def warps_add(ctx, name):
"""Сохранить текущую позицию"""
p = world.self()
if p is None:
return
db.set(name, [p.getX(), p.getY(), p.getZ()]).save()
ctx.msg("Точка '%s' сохранена" % name)
@warps.sub("del", aliases=["remove"])
def warps_del(ctx, name):
"""Удалить точку"""
db.remove(name).save()
ctx.msg("Точка '%s' удалена" % name)Голое .warps вызовет саму команду, а .warps add дом уже подкоманду. Своя подкоманда может быть и у подкоманды, глубина не ограничена.
Объект commands отвечает за всё остальное: запустить команду из кода, проверить занятость имени, снять свою команду досрочно.
| Метод | Что делает |
|---|---|
commands.run(".help") | Выполнить команду, как будто её написали в чат. Точку можно не писать |
commands.exists("hello") | Занято ли такое имя |
commands.all() | Имена всех команд клиента |
commands.prefix() | Текущий префикс, обычно точка |
commands.remove("hello") | Снять свою команду. Чужую не снимет |
commands.add("hello", fn, desc=..., aliases=..., suggests=...) | То же, что декоратор, но без него |