Toolshed

В процессе

Эта страница находится в стадии разработки! Некоторая информация может быть неполной или неактуальной.

Toolshed является одним из трёх основных встроенных инструментов отладки (наряду с scsi и View Variables.) в RobustToolbox и выполняет роль консоли разработчика игры. Чтобы использовать Toolshed, откройте консоль отладки или воспользуйтесь консолью отладки в devwindow.

Warning

Toolshed пока недоступен на клиенте, поэтому для запуска его команд на стороне сервера на клиенте нужно использовать команду-префикс >. Если её пропустить, часто будет возникать ошибка о том, что у вас нет разрешения на выполнение команды, даже если это не так.

Toolshed представляет собой конвейерную оболочку, а основной метод выполнения сложных действий заключается в композиции команд. Вы можете просто писать несколько команд одну за другой, и пока они совместимы, их входные данные будут последовательно передаваться от одной к другой. Тем, кто знаком с такими оболочками, как bash, это обычно делается с помощью явного символа конвейера, например ‘|’. Однако в Toolshed оператор конвейера необязателен.

Например, возьмём следующий прогон команд:

entities with Item count

который также можно записать с явными операторами конвейера:

entities | with Item | count

Здесь три команды: entities, with и count. Вместе они образуют прогон команд, то есть набор последовательных команд. В данном случае совокупный эффект заключается в возврате общего числа сущностей, имеющих ItemComponent.

Warning

Для удобства некоторые примеры, используемые в документации, могут задействовать типы или команды, специфичные для SS14 (например, ItemComponent), хотя Toolshed является частью RobustToolbox и не привязан к SS14.

Подкоманды

Некоторые команды объединены в «команду» с «подкомандами». Это просто наборы связанных команд, имена которых состоят из двух частей, разделённых двоеточием: имени команды и имени подкоманды. Например, есть команды для добавления, удаления, обеспечения и проверки наличия компонентов, и все они сгруппированы как часть команды «comp»:

  • comp:get
  • comp:has
  • comp:add
  • comp:rm
  • comp:ensure

В настоящее время это в основном организационное соглашение. Для пользователей подкоманды ведут себя как обычные команды. Они никак особо не связаны друг с другом, и команды «comp» на самом деле не существует.

Справка

Команда help позволяет показать описание и обобщённые сигнатуры команд. Например:

> help count

count - Counts the amount of entries in it's input, returning an integer.
Usage:
  <input (IEnumerable<T>)> → count → Int32

Блок usage показывает синтаксис для всех реализаций этой команды. В данном случае она всего одна. Синтаксис usage состоит из максимум трёх частей на реализацию:

  • Имя и тип аргумента конвейерного ввода. Здесь это часть <input (IEnumerable<T>)> → . Она опускается, если конвейерного ввода нет.
  • Сама команда со всеми префиксами и аргументами. Поскольку у команды count нет аргументов, здесь это просто count.
  • Тип вывода, который можно передать по конвейеру в другие команды. Здесь это часть → Int32. Она опускается, если команда ничего не возвращает.

Синтаксис конвейерных и командных аргументов имеет вид <Name (Type)>, где имя и тип аргумента берутся из метода C#, связанного с этой командой. Если аргумент команды необязателен, вместо этого используются квадратные скобки (то есть [Name (Type)]). Некоторые команды также принимают бесконечно повторяемые аргументы, которые обозначаются многоточием (то есть [Name (Type)]...). Такие аргументы всегда идут последними и означают, что команду нужно завершить явным символом конвейера |, если вы хотите передать вывод команды по конвейеру в другую команду.

Для более сложного примера рассмотрим команду with, которая использовалась в предыдущем разделе. Она может принимать либо сущность, либо прототип сущности, поэтому у неё несколько реализаций. Она также требует один аргумент и поддерживает префиксы:

> help with

with - Filters the input entities by whether or not they have the given component.
The behaviour of this command can be inverted using the "not" prefix.
Usage:
  <input (IEnumerable<EntityUid>)> → [not] with <component (Type)> → IEnumerable<EntityUid>
  <input (IEnumerable<EntityPrototype>)> → [not] with <component (Type)> → IEnumerable<EntityPrototype>
  <input (IEnumerable<ProtoId<T>>)> → [not] with <protoId (ProtoId<T>)> → IEnumerable<ProtoId<T>>

Обратите внимание, что в общем случае каждая реализация может иметь разное количество и типы аргументов, хотя в данном случае у каждой реализации ровно один аргумент. Как поясняет приведённый выше вывод help, команде with можно передать необязательный префикс “not”, чтобы инвертировать её поведение. Так, если бы мы захотели получить количество всех сущностей, у которых нет компонента item, мы могли бы использовать entities not with Item count. Если команда поддерживает префиксы, страница справки должна об этом сообщать.

Имена аргументов

Имя аргумента в синтаксисе команды также может помочь разрешить некоторые неоднозначности в порядке указания аргументов. Например, команда tp:to телепортирует одну сущность к другой. Если вы не уверены, является ли целевая сущность конвейерным вводом или первым аргументом, можно проверить имя аргумента, выводимое командой help.

> help tp:to

tp:to - Teleports the given entities to the target entity.
Usage:
  <teleporter (EntityUid)> → tp:to <target (EntityUid)> → EntityUid
  <teleporters (IEnumerable<EntityUid>)> → tp:to <target (EntityUid)> → IEnumerable<EntityUid> 

Warning

Обратите внимание, что использование имён аргументов C# для автоматической генерации строк справки является относительно новым, и у некоторых команд могут быть неудачно названные аргументы.

Пояснение

С помощью команды explain можно получить информацию о потоке выполнения прогона команд. Настоятельно рекомендуется применять explain к непонятным вам прогонам команд, чтобы понять их поток. Она разбивает любой допустимый прогон команд на составляющие его команды и для каждой команды выдаёт:

  • Краткое описание команды
  • Конкретные типы входа и выхода в контексте данного прогона команд.
  • Сигнатуру команды, включая имя и тип всех разобранных аргументов.

Warning

Обратите внимание, что команда explain работает только с допустимыми командами. Её нельзя использовать для диагностики недопустимых команд. Если вы не уверены, как использовать команду, возможно, лучше воспользоваться командой help.

Сгенерированное пояснение может быть полезно для понимания того, как каждая команда в прогоне преобразует данные, передаваемые по конвейеру, а сигнатура команды, будем надеяться, яснее показывает, что делает каждый аргумент. Например, пояснение команды из предыдущего раздела даёт:

> explain entities with Item count

entities - Returns all entities on the server.
Pipe input: [none]
Pipe output: IEnumerable<EntityUid>
Signature:
  entities

with - Filters the input entities by whether or not they have the given component.
Pipe input: IEnumerable<EntityUid>
Pipe output: IEnumerable<EntityUid>
Signature:
  <input> → with <component (Type)>

count - Counts the amount of entries in it's input, returning an integer.
Pipe input: IEnumerable<EntityUid>
Pipe output: Int32
Signature:
  <input> → count

Обратите внимание, что здесь тип конвейерного входного аргумента для команды count равен IEnumerable<EntityUid>, в отличие от примера с help, где использовался обобщённый тип (IEnumerable<T>). Команда explain всегда показывает только тип и синтаксис той конкретной реализации команды, которая относится к поясняемому прогону команд.

Часто используемые команды

В этом разделе кратко описаны некоторые простые команды, которые часто используются для построения более сложных прогонов команд. Они могут встречаться по всей документации в примерах использования других команд.

Для описания некоторых других часто полезных команд см. раздел команд. Несколько примеров того, как соединять команды Toolshed в цепочки, см. в примерах Toolshed

Константы

Эти команды часто используются в начале прогона команд, чтобы задать начальное значение, которое передаётся по конвейеру в другие команды:

  • i, возвращает целое число. Например, i 2.
  • f, возвращает float. Например, f 2.1.
  • b, возвращает bool. Например, b true.
  • s, возвращает строку. Например, s "foo".
  • ent, возвращает EntityUid. Например, ent 123.
  • fpi, dpi возвращает Pi с плавающей или двойной точностью.

Математика

Toolshed поддерживает множество видов математических операций, включая, но не ограничиваясь:

  • Простые операции: +, -, \*, /, %
  • Обычные функции: sin, abs, min, pow, ceil
  • Векторные операции (то есть умножение списка на число): +/, -/, \*/, //, %/
  • Побитовые операции: &, ^, bitor, ~, &~ ^~, bitornot (обратите внимание, что | является явным символом конвейера, поэтому он не используется для команд побитового ИЛИ)

Диапазоны и последовательности

Есть несколько команд, полезных для создания списков/последовательностей или работы с ними:

  • count возвращает общее число элементов в последовательности
  • to используется для создания диапазона чисел. Например, i 3 to 5 возвращает [3,4,5]
  • iota используется для создания диапазона чисел до некоторого значения. Например, i 3 iota возвращает [1, 2, 3].
  • rep повторяет входное значение. Например, i 5 rep 3 возвращает [5, 5, 5].
  • append добавляет число в конец последовательности.
  • join объединяет две последовательности (или строки). Также может использоваться для добавления одного элемента в начало.
  • first выбирает первый элемент последовательности
  • take берёт первые N элементов последовательности
  • select случайным образом выбирает N элементов или процент элементов из последовательности

Терминаторы

Разбор аргументов команды можно прервать с помощью явного символа конвейера | или символа-терминатора ;. Первый в основном полезен, если у команды есть необязательные или повторяемые аргументы, либо чтобы сделать некоторые команды более удобными для чтения и понимания. Второй главным образом полезен тем, что отбрасывает передаваемое по конвейеру выходное значение, что позволяет соединять в цепочку в остальном несовместимые команды. Например:

> f 2 * 1.5; i 1 + 1
2

Без ; приведённая выше команда не разберётся, так как команда i не принимает никаких переданных по конвейеру значений.

Ошибки и недопустимые команды

Прежде чем Toolshed попытается выполнить прогон команд, он должен сначала успешно его разобрать. Если разобрать команду не удаётся, он должен попытаться вывести полезное сообщение об ошибке, указывающее на конкретную часть команды, которую Toolshed не смог разобрать. Обратите внимание, что команда explain работает только с допустимым прогоном команд и не может использоваться, чтобы выяснить, почему прогон команд не работает.

Note

При неправильном использовании команды Toolshed часто выдаёт длинные трассировки стека. Но обычно над трассировкой стека в вашей консоли есть более понятное сообщение об ошибке, хотя, возможно, придётся прокрутить вверх, чтобы его увидеть.

Например, в одном из предыдущих примеров есть команда with, которая ожидает на входе либо EntityUid, либо прототип. Если вместо этого передать ей целое число, она сообщит, что не существует команды with, принимающей такой тип:

> entities count with Items

entities count with Items
               ^^^^
Could not find an implementation of the 'with' command given the input type 'Int32'.
Accepted types: 'IEnumerable<EntityUid>','IEnumerable<EntityPrototype>','IEnumerable<ProtoId<T>>'.

   at Robust.Shared.Toolshed.ToolshedCommandImplementor.TryParse(ParserContext ctx, Func`2& invocable, Nullable`1& method)
   at Robust.Shared.Toolshed.Syntax.ParsedCommand.TryParseCommand(ParserContext ctx, Func`2& invocable, Nullable`1& method, ToolshedCommandImplementor& implementor)
   at Robust.Shared.Toolshed.Syntax.ParsedCommand.TryParse(ParserContext ctx, Type piped, ParsedCommand& result)
   at Robust.Shared.Toolshed.Syntax.CommandRun.TryParse(ParserContext ctx, Type pipedType, Type targetOutput, CommandRun& expr)
   at Robust.Shared.Toolshed.ToolshedManager.InvokeCommand(IInvocationContext ctx, String command, Object input, Object& result)
   at Robust.Shared.Toolshed.ToolshedManager.InvokeCommand(IConsoleShell session, String command, Object input, Object& result, IInvocationContext& ctx)
   at Robust.Server.Console.ServerConsoleHost.ExecuteInShell(IConsoleShell shell, String command)
   at Robust.Server.Console.ServerConsoleHost.ExecuteCommand(ICommonSession session, String command)
   at Robust.Server.Console.ServerConsoleHost.ProcessCommand(MsgConCmd message)
   at Robust.Shared.Network.NetManager.<>c__DisplayClass109_0`1.<RegisterNetMessage>b__0(NetMessage msg)
   at Robust.Shared.Network.NetManager.DispatchNetMessage(NetIncomingMessage msg)
   at Robust.Shared.Network.NetManager.ProcessPackets()
   at Robust.Server.BaseServer.Input(FrameEventArgs args)
   at Robust.Server.BaseServer.<SetupMainLoop>b__67_0(Object sender, FrameEventArgs args)
   at Robust.Shared.Timing.GameLoop.Run()
   at Robust.Server.BaseServer.MainLoop()

Поиск команд

С помощью команды cmd:list можно получить список всех команд. Затем его можно объединить с командой search, чтобы найти в этом списке нужную вам команду. Например,

> cmd:list search "awn"

spawn:at,
spawn:on,
spawn:attached

Если вы пытаетесь найти команду, которая может принимать вывод другой команды, можно использовать команду types:consumers. Например, ent 1 types:consumers выведет список всех типов, которые могут принимать EntityUid. Обратите внимание, что команда types:consumers в настоящее время несколько несовершенна, особенно когда речь идёт о методах C# с обобщёнными ограничениями. Например, она часто ошибочно сообщает, что различные математические команды принимают любой тип, хотя они принимают только числа.

Subpages