Начало работы

Команда amxts

amxts — команда, которой пользуется проект: создаёт проекты и модули, добавляет модули, собирает, выкладывает, проверяет типы и запускает тесты. Это пакет @amxts/cli, от которого зависит @amxts/core, поэтому она есть в каждом проекте и проект запускает её через свой менеджер пакетов:

npx amxts <команда>

Команда работает с собственным ядром проекта — @amxts/core из его node_modules: ядро старше или новее, чем команда знает, — это ошибка, которая говорит, что из двух обновить. Установленная глобально (npm install -g @amxts/cli), amxts так же работает в любом проекте, а init — где угодно.

amxts --help перечисляет команды, amxts <команда> --help показывает параметры команды с примерами. На опечатку команда подсказывает:

$ npx amxts buidl
✖ Unknown command buidl
  Did you mean amxts build?

Ошибка — одна строка и подсказка под ней. --debug добавляет, где она случилась, — для отчёта об ошибке.

Команды

командачто делает
initсоздаёт проект, а с --module — пакет модуля
devсобирает, выкладывает на сервер и снова — на каждое сохранение
buildсобирает плагины и модули в dist/
typecheckпроверяет плагины и amxts.config.ts так же, как редактор
testзапускает тесты проекта на поддельном сервере
modulemodule add ставит модуль и вписывает его в конфиг; module list показывает модули
checkв пакете модуля: проверяет, что он готов к публикации
prepareполучает include сервера и пишет .amxts/ для редактора
upgradeпереводит проект на другой выпуск amxts: пакеты, код, сборку и сервер
infoверсии и настройки — для отчёта об ошибке

init

Создаёт проект. Спрашивает по порядку: менеджер пакетов (выбран тот, что запустил команду), папку, модули (из каталога модулей), oxlint и oxfmt, git, папку сервера для dev и — когда этого не говорят include сервера — для какого сервера проект. Потом пишет файлы, ставит зависимости, получает include сервера и говорит, что запускать дальше:

npm create amxts@latest

npm create amxts и npx amxts init — одна и та же команда. Вопросы выглядят так:

┌  amxts 0.2.0 · a new project
│
◇  Which package manager?
│  npm
│
◇  Where should the project go?
│  my-server
│
◇  Which modules? (space to pick, enter to go on)
│  menu-core
│
◇  Add oxlint and oxfmt? (lint and format)
│  Yes
│
◇  Initialize a git repository?
│  Yes
│
◇  Where is the server? its addons/amxts folder, for npm run dev - empty to skip
│  D:/hlds/cstrike/addons/amxts
│
◆  Created my-server in my-server
│
●  config-core is listed too: menu-core needs it
│
◇  Installed dependencies with npm 11.16.0
│
◆  Includes: the server's own (D:/hlds/cstrike/addons/amxmodx/scripting/include)
│
◆  Initialized a git repository
│
◆  Prepared the editor config (.amxts/tsconfig.json)
│
◇  Next steps ──────────────────────────────────────╮
│                                                   │
│  cd my-server                                     │
│  npm run dev    # build, deploy, rebuild on save  │
│                                                   │
├───────────────────────────────────────────────────╯
│
└  Docs: https://amxts.github.io/docs/getting-started/quick-start

У каждого вопроса есть флаг, а --yes берёт значения по умолчанию для остального — для скрипта или CI:

npx amxts init my-server --modules menu-core,config-core --no-git --server D:/hlds/cstrike/addons/amxts --yes
параметрчто делает
[папка]куда положить проект; по умолчанию my-server
--pm <npm|pnpm|yarn|bun>менеджер пакетов; по умолчанию тот, что запустил команду
--modules <список>модули через запятую, по именам в каталоге или как пакеты npm: menu-core,config-core; "" — без модулей
--no-lintбез oxlint и oxfmt (по умолчанию они добавляются)
--no-gitбез git init
--server <путь>сервер: его папка, его cstrike или его addons/amxts; в .env как AMXTS_SERVER пишется addons/amxts, а сборка берёт include, которые стоят на нём
--target <rehlds|hlds>для какого сервера проект, когда этого не говорят include сервера: rehlds — ReHLDS, ReGameDLL и ReAPI (по умолчанию) — или hlds, обычный HLDS
--os <windows|linux>система сервера, когда её не видно по его папке: пишется в .env как AMXTS_SERVER_OS (система сервера)
--no-installзаписать файлы, но не ставить зависимости
--yes, -yничего не спрашивать
--forceписать в непустую папку
--localподключить ядро и официальные модули ссылками на их папки на этой машине, а не ставить из npm, — для работы над самим amxts; AMXTS_CORE задаёт папку ядра

Модуль, которому нужен другой, приводит его с собой: с menu-core ставится и config-core, а modules перечисляет его сразу за menu-core, с комментарием, какому модулю он нужен. Сборка загружает его первым:

// amxts.config.ts
export default 
defineConfig
({
modules
: [
"@amxts/menu-core", "@amxts/config-core", // needed by menu-core ],
target
: "rehlds",
});

Проект получается такой:

my-server/
├── package.json        скрипты: dev, build, typecheck, test, lint
├── amxts.config.ts     выбранные модули и те, что им нужны
├── tsconfig.json       { "extends": "./.amxts/tsconfig.json" }
├── .oxlintrc.json      правила линтера: @antfu/eslint-config, для oxlint
├── .oxfmtrc.json       oxfmt, для файлов JSON и YAML
├── knip.json           точки входа для knip: плагины, конфиг, тесты
├── .env                AMXTS_SERVER, если папка сервера указана; AMXTS_SERVER_OS
├── pnpm-workspace.yaml с pnpm: скрипт установки bun не нужен
├── .gitignore
├── .gitattributes      LF для файлов, которые форматирует oxfmt
├── .vscode/            настройки и рекомендуемые расширения
├── README.md
├── plugins/
│   └── hello.ts        плагин, который пользуется выбранными модулями
└── test/
    ├── hello.test.ts   его тесты на поддельном сервере
    └── tsconfig.json   свой у тестов: типы Bun, а не плагинов

Include сервера

Там, где плагину нужен Pawn-include, — include, который он реализует, нативы или форварды Pawn-плагина, Pawn-тест — сборка ищет сначала в includes/ проекта, потом среди include сервера, потом среди тех, что идут с amxts (там и собственные include AMX Mod X). Include сервера — это:

  • с AMXTS_SERVER — собственная addons/amxmodx/scripting/include сервера, ровно то, что на нём стоит;
  • без сервера — include того сервера, который называет target в amxts.config.ts: для "rehlds" — ReHLDS, ReGameDLL и ReAPI, по умолчанию — amxts скачивает include ReAPI в .amxts/include, из того выпуска, из которого сделан его API; "hlds" — обычному HLDS — ничего, кроме собственных include AMX Mod X, не нужно.
// amxts.config.ts
export default 
defineConfig
({
modules
: [],
target
: "hlds",
});

init спрашивает target, когда сервера нет или в его папке нет include; --target отвечает на вопрос. prepare — после каждой установки — и каждая сборка скачивают include, если их ещё нет.

Без сети include не скачать: команда говорит об этом и идёт дальше, а сборка останавливается, только если плагин называет include, которого нет. Подключитесь и запустите npx amxts prepare или укажите в AMXTS_SERVER сервер с его include.

lint проверяет код oxlint'ом по правилам @antfu/eslint-config, а файлы JSON и YAML — oxfmt; lint:fix исправляет, что может, — TypeScript форматируют эти же правила. В VS Code то же при наборе и сохранении делает расширение oxc, которое советует .vscode/extensions.json.

Пакет модуля

С --module создаётся пакет модуля — работающий модуль с проектом-песочницей и тестом, — см. свой модуль:

npx amxts init --module @you/greeter               # ./greeter
npx amxts init --module @you/greeter --natives     # с нативами для Pawn-плагинов
npx amxts init --module greeter --dir my-greeter   # в ./my-greeter

dev

npx amxts dev

Собирает все плагины и модули, копирует их на сервер из AMXTS_SERVER, перезагружает его, а потом следит за папкой плагинов и модулями проекта: сохранение пересобирает плагины, которые импортируют сохранённый файл.

amxts 0.2.0 · dev

  Core      @amxts/core 0.2.0
  Modules   menu-core 0.2.0 · config-core 0.1.1
  Server    D:/hlds/cstrike/addons/amxts · Windows · ReHLDS · running
  Plugins   1 in plugins/

✔ hello · 6.2s
✔ 14:02:11 deployed, the server reloaded config-core, menu-core, hello (7.1s)
◇ watching plugins - save a plugin and it goes to the server (Ctrl+C stops)
✔ hello · 4.1s
✔ 14:03:40 plugins/hello.ts changed: deployed, the server reloaded hello (4.2s)

Сначала — с чем она работает: ядро и модули с версиями — модуль, которым не пользуется ни один плагин, — так и говорит (no plugin uses it), модуль из папки на этой машине, а не из npm, — local; затем сервер — его папка, система (ниже), ReHLDS или обычный HLDS и запущен ли он; и сколько плагинов.

Каждый плагин и модуль виден, пока компилируется: ◇ compiling hello 1/1, пока идёт, ✔ hello · 6.2s, когда готов, — в терминале одна строка сменяет другую, в логе (CI) остаются обе. Плагин проходит два компилятора, в WebAssembly и затем в машинный код, — на это сборка и тратит время. Поэтому:

  • официальные модули приходят из npm уже скомпилированными для Windows и Linux, и сборка берёт их как есть, ничего не компилируя. Если проект скомпилировал бы модуль иначе — его настройки заданы в amxts.config.ts, ядро другой версии, — сборка говорит почему (menu-core 0.2.0 was built for @amxts/core 0.2.0, the project has 0.2.1 - compiling it here) и компилирует его, один раз. Плагин, который пользуется модулем, тоже компилируется по тому, с чем модуль пришёл, а не разбирает модуль сначала сам;
  • плагин, для которого с прошлой сборки ничего не изменилось — ни его файл, ни то, что он импортирует, — заново не компилируется: он берётся готовым из node_modules/.cache/amxts. dev, запущенный снова, выкладывает плагины на сервер за секунды;
  • несколько плагинов компилируются сразу, каждый в своём процессе: столько, сколько помещается в 3 ГБ памяти — одной компиляции нужен примерно гигабайт, — и не больше, чем у машины ядер процессора. В терминале строка называет их все: ◇ compiling hello, shop 2/3. AMXTS_BUILD_MEMORY в .env или в окружении задаёт память в мегабайтах (AMXTS_BUILD_MEMORY=6144), AMXTS_BUILD_JOBS — прямо число компиляций (1 — по одной). Плагин получается одинаковым в любом случае.

Сохранение пересобирает, только когда в файле что-то изменилось: редактор, сохранивший файл без изменений, или менеджер пакетов, заново записавший модуль, — не изменение, — и строка называет файл.

dev компилирует на скорость: маленький плагин — за несколько секунд, там где build тратит около десяти. Его плагины делают то же самое, чуть медленнее, — на сервер, где играют, выкладывайте npx amxts build --deploy.

AMXTS_SERVER — папка addons/amxts сервера с amxts (установка на сервер), в .env проекта:

AMXTS_SERVER=D:/hlds/cstrike/addons/amxts

Можно указать и папку самого сервера (D:/hlds), его cstrike или cstrike/addons: сборка берёт cstrike/addons/amxts внутри неё, а строка Server говорит, какая это папка. Папка, которая не подходит ни под один вариант, останавливает сборку одной строкой о том, где она искала.

Без него dev и build --deploy спрашивают папку, как init, и записывают её в .env. В CI или когда вывод идёт в конвейер ничего не спрашивается: сборка останавливается и говорит, что AMXTS_SERVER не задан.

Когда модуль сервера из другого выпуска, чем ядро проекта, dev и build сначала говорят об этом — плагины, которые собирает проект, загружаются только модулем его выпуска:

▲ the server runs amxts 0.1.0, this project 0.2.0 - run amxts upgrade

upgrade обновляет и сервер. Выпуск читается из файла модуля, а не у запущенного сервера.

Перезагрузка идёт через rcon на 127.0.0.1:27015 (другой порт задаёт AMXTS_PORT), с rcon_password из cstrike/server.cfg сервера. См. горячую перезагрузку. --os — как у build.

npx amxts dev --docker

То же для сервера в Docker, который монтирует проект: собирает для Linux в dist/ и снова при каждом сохранении, ничего не выкладывает — сервер читает dist/ и перезагружает плагин, файл которого изменился, — и показывает под сборкой строки amxts из консоли этого сервера. AMXTS_SERVER не используется.

build

npx amxts build              # dist/: файлы .aot и plugins.ini
npx amxts build --deploy     # и копирует их в AMXTS_SERVER, перезагружая сервер
npx amxts build --os linux   # для сервера на Linux
npx amxts build --watch      # и снова при каждом сохранении, без выкладки

plugins.ini перечисляет сначала модули, каждый после тех, что ему нужны, потом плагины проекта. Модуль, которым не пользуется ни один плагин, в сборку не попадает, если его не оставляет pawn (собирается только то, чем пользуются). Куда писать, меняет outDir в amxts.config.ts. Плагин, для которого с прошлой build ничего не изменилось, берётся готовым, официальный модуль — каким пришёл (dev); без node_modules/.cache/amxts все компилируются заново.

Система сервера

Плагин компилируется в машинный код под систему своего сервера, Windows или Linux, и .aot, собранный под одну, не загрузится на другой. Систему сборка берёт, по порядку:

  1. --os windows или --os linux у build или dev;
  2. AMXTS_SERVER_OS в окружении или .env;
  3. папку AMXTS_SERVER: hlds_linux или hlds.exe рядом с папкой игры, иначе файлы в её addons/amxmodx/modules;
  4. систему машины, на которой идёт сборка.

Какую именно, говорит строка Server у dev и build: Linux. Так проект, собранный на Windows, выкладывается на сервер на Linux как есть — когда AMXTS_SERVER указывает на него (например, на подключённую сетевую папку) или в .env есть AMXTS_SERVER_OS=linux. init спрашивает систему, когда её не видно по папке сервера, а info показывает, какую выберет сборка.

Плагин под другую систему
.aot, собранный под другую систему, не загрузится, и консоль об этом скажет: was compiled for a Linux server, and this one runs Windows (или наоборот). .ts, который сервер компилирует сам, всегда собран под него.

typecheck

npx amxts typecheck

Проверяет плагины и amxts.config.ts TypeScript'ом, так же, как редактор: опечатку в настройке модуля, неверное имя события, поле, которого нет.

test

npx amxts test           # все тесты проекта
npx amxts test hello     # файлы, в имени которых есть "hello"
npx amxts test --watch   # и снова на каждое сохранение

Запускает bun test: его параметры передаются как есть. Тест кладёт проект на поддельный сервер через setup() — см. тесты.

module

npx amxts module add menu-core      # @amxts/menu-core
npx amxts module add @you/greeter   # любой пакет-модуль из npm
npx amxts module add ../greeter     # модуль из папки
npx amxts module list

module add ставит пакет менеджером пакетов проекта (его узнаёт по lock-файлу) и добавляет в modules в amxts.config.ts, а за ним — модули, которые ему нужны и которых в списке ещё нет, каждый с комментарием // needed by menu-core; меняется только список, остальной файл остаётся как вы его написали. Короткое имя — имя модуля в каталоге модулей: menu-core — это @amxts/menu-core. Пакет, которого нет в каталоге, всё равно ставится из npm, но с предупреждением; пакет, который не модуль amxts, ставится, но в конфиг не добавляется. Модуль из npm приходит в своей новейшей версии, которая работает с ядром проекта. Каталог команда читает из реестра на GitHub, а без сети берёт копию, с которой была опубликована.

параметрчто делает
--skip-installтолько добавить в amxts.config.ts
--skip-configтолько поставить
--localофициальный модуль из его папки на этой машине, ссылкой, — для работы над самим amxts

module list показывает модули из конфига и стоят ли они, стоящие модули, которых нет в конфиге, и модули каталога, которых у проекта ещё нет, — модуль сообщества помечен (community):

In amxts.config.ts
  ✔ @amxts/menu-core    0.2.0  An opinionated way to create menus
  ✔ @amxts/config-core  0.1.1  Configs in INI, YAML or JSON, read into typed objects and written back

In the amxts catalog
  ○ resemiclip          Semiclip over the ReSemiclip module - who walks through whom, as a rule over two players - npx amxts module add resemiclip
  ○ ftp                 FTP, FTPS and SFTP - upload, download and list files on another server, every call a promise - npx amxts module add ftp

check

npx amxts check

В папке модуля, перед публикацией: поле amxts указывает на существующие файлы, у файла модуля есть defineModule с meta.name, есть README.md и LICENSE, а include/<имя>.inc совпадает с тем, что сборка пишет из нативов. Ничего не записывает. См. свой модуль.

prepare

npx amxts prepare

Получает include сервера, если их ещё нет, и пишет в .amxts/ то, что читает редактор:

  • .amxts/tsconfig.json, который расширяет tsconfig.json проекта: ~/ — папка плагинов, @amxts/core и его точки входа — API ядра, модули находятся по именам, а amxts.config.ts получает типы из них;
  • .amxts/imports.d.ts — то, чем плагины пользуются без импорта, глобальными именами для редактора (автоимпорты);
  • .amxts/api/ — только когда AMXTS_DOCS_LANG выбирает не английский: копия API ядра и модулей с подсказками на этом языке, которую редактор читает вместо установленных пакетов. Пакеты в node_modules не меняются никогда, а собирает сборка именно их, поэтому плагины выходят одинаковыми на любом языке.

build, dev и typecheck делают это первым шагом, init — после установки. .amxts/ принадлежит команде: она в .gitignore и пишется заново, когда устарела.

upgrade с v0.2

npx amxts upgrade              # до последнего выпуска
npx amxts upgrade --to 0.2.0   # до выпуска на ваш выбор
npx amxts upgrade --dry-run    # что изменилось бы, ничего не меняя

::: warning Сначала сама команда upgrade — команда пакета @amxts/cli, и проект запускает ту его версию, с которой пришло его ядро, или ту, что названа в его собственном package.json. Если в команде проекта ещё нет upgrade, сначала добавьте новейшую команду тем менеджером пакетов, что у проекта:

npm i @amxts/cli@latest   # или: bun add @amxts/cli@latest, pnpm add @amxts/cli@latest, yarn add @amxts/cli@latest
npx amxts upgrade

:::

Переводит проект на другой выпуск amxts за один раз:

  1. Пакеты. @amxts/core переходит на последнюю версию в реестре или на --to. У каждого другого пакета @amxts/ в package.json — официальных модулей, команды — своя версия, и он переходит на свою новейшую версию, которая работает с этим ядром: модуль называет ядра, с которыми работает, в своих peerDependencies. Каждая записывается так, как её пишет проект: ^0.1.0 становится ^0.2.0, 0.1.0 — 0.2.0. Пакет из папки (file:) остаётся как есть; модуль, у которого ещё нет версии для этого ядра, останавливает перевод до любых изменений. Ставит их пакетный менеджер проекта — тот, чей lock-файл в проекте, — из реестра, на который настроен npm (.npmrc, NPM_CONFIG_REGISTRY).
  2. Код переписывается под новый API новым ядром, каждое изменение перечисляется: код, ниже.
  3. Сборка — как её делает amxts build.
  4. Сервер из AMXTS_SERVER: его модуль — и компилятор .ts, написанных на сервере, если он там есть, — из GitHub Release новой версии, каждый файл сверяется с sha256 из списка выпуска. Заменённый файл остаётся рядом со своей версией: amxts_amxx.dll.0.1.0. Строка amxts_host.amxx в plugins.ini AMX Mod X убирается: модуль загружает свой host-плагин сам. Без AMXTS_SERVER — для сервера в Docker — говорит, какой образ скачать.
  5. Итог: версии, переписанные файлы, что проверить вручную и что стало с сервером.
amxts 0.2.0 · upgrade
◇ Packages: amxts 0.2.0 (latest)
i @amxts/core  ^0.1.0 → ^0.2.0
i @amxts/cli  ^0.1.0 → ^0.2.0
i @amxts/menu-core  ^0.1.0 → ^0.2.0
i @amxts/config-core  ^0.1.0 → ^0.1.1
◇ Installing with npm
✔ Installed with npm
◇ Code
  plugins/hello.ts:1  ~/natives → @amxts/core/natives
  plugins/hello.ts:9  player.account → player.money
◇ Build
  ...
✔ built hello into dist (11.4s)
◇ Server: D:/hlds/cstrike (windows)
✔ amxts_amxx.dll 0.1.0 → 0.2.0 (the old one: amxts_amxx.dll.0.1.0)
✔ Took amxts_host.amxx out of D:/hlds/cstrike/addons/amxmodx/configs/plugins.ini: the module loads it itself

Upgraded to amxts 0.2.0
  @amxts/core         0.1.0 → 0.2.0
  @amxts/cli          0.1.0 → 0.2.0
  @amxts/menu-core    0.1.0 → 0.2.0
  @amxts/config-core  0.1.0 → 0.1.1
  ✔ rewritten: plugins/hello.ts
  ▲ to check by hand:
      plugins/shop.ts:14  it reads the words after the name: write them in the usage, "/give <amount>", and take them by name, ({ player, amount })
  ✔ built
  ✔ server: amxts_amxx.dll 0.1.0 → 0.2.0 - restart the server to load it
параметрчто делает
--to <version>выпуск, на который перейти, вместо последнего
--no-serverне трогать сервер
--server-onlyтолько шаг сервера — для сервера, который был запущен
--dry-runвывести, что было бы сделано: ничего не ставится и не пишется, из выпуска читается только список файлов

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

Проект запускает ту команду, с которой пришло его ядро. amxts более старого выпуска ставит новые пакеты, а остальное — код, сборку, сервер — передаёт новой команде проекта.

Запущенный сервер
Сервер на Windows держит свой модуль, пока работает, и заменить файл тогда нельзя. upgrade ничего не меняет на сервере, говорит об этом и делает остальное: остановите сервер и запустите npx amxts upgrade --server-only. На любой системе новый модуль загружается при следующем старте.

Код

Новое ядро приводит код проекта к своему API и перечисляет каждую изменённую строку. Импорт API ядра через ~/ становится импортом по имени пакета, а импорт пакета модуля по его месту в сборке (~/modules/menu-core) — импортом по имени модуля:

import { 
user_slap
} from "~/natives"; // было
import {
user_slap
} from "@amxts/core/natives"; // стало

Код читается парсером TypeScript: меняются импорты, экспорты, import() и declare module; строка или комментарий, которые только похожи на импорт, — нет. Ваши собственные файлы через ~/ остаются как есть. Второй запуск ничего не меняет. Команда проходит все .ts проекта — плагины, тесты, исходники модуля, — но не node_modules и dist/.

Обработчик команды получает один объект (команды): (player) => становится ({ player }) =>, а функция, переданная по имени и принимающая игрока, вызывается из ({ player }) => name(player); (player, args) =>, который не читает args, тоже становится ({ player }) =>. Обработчик, который читает слова после имени команды, выводится в список со строкой — его переписывают руками: слова идут в использование, "/give <amount>", а обработчик берёт их по имени.

Код menu-core приводится к контексту меню (меню): addItem("text", options) становится addItem({ title: "text", ... }), и так же addFixedItem; (player) => и (player, target) => становятся ({ player }) => и ({ player, target }) => — в пункте, в настройках меню, в фильтре, в источнике списка и в том, что регистрируется по имени. Функция, переданная по имени и объявленная в файле, вызывается из стрелки, которая передаёт ей то, что она принимала. В список — переписать руками — попадают функция, объявленная в другом файле, имя меню, прочитанное как текст, цель, переданная числом, и menus.runActions — это метод меню (menu.runActions).

Имена следуют API: Player.all() становится server.players, а его поля — filter: Player.all({ alive: true, team: "CT" }) — это server.players.filter(player => player.isAlive && player.team === "CT"); там, где в коде уже есть player, как в обработчике команды, игрок фильтра зовётся other (или p), чтобы ничего не скрыть. Поле, метод или событие игры, названные словами движка, получают слова игрока: player.account становится player.money, player.authid — player.steamId, game.numCtWins — game.ctWins, weapon.inReload — weapon.isReloading, событие restartRound — newRound, а класс события следует за его именем. Значение считается игроком, оружием или игрой там, где файл это говорит, — event.player, аннотация Player, Client или Weapon, { player } из события или команды, первый параметр обработчика команды, элемент server.players, player.activeItem, game. В список, чтобы поправить руками, выводятся: старое имя у любого другого значения, поля, записанные не литералами, и поле или событие, которых в API нет, — до них по-прежнему достают нативы @amxts/core/natives (get_member, RegisterHookChain). Игрок теста тоже заходит со steamId: server.join("Alice", { authid }) становится server.join("Alice", { steamId: authid }).

Событие сервера называется словами автора плагина (события сервера): server.addEventListener("putinserver", ...) становится server.addEventListener("putInServer", ...), "cfg" — "pluginsLoaded", "kill" — "suicide", а собственное имя форварда ("client_putinserver") — именем события. Событие, которое есть событие игры, слушается через game: server.addEventListener("PreThink", ...) становится game.addEventListener("preThink", ...), так же "PostThink", "pfnTouch" ("touch") и "infochanged" ("userInfoChange"). Поле события, названное по параметру Pawn, получает слово автора там, где файл говорит, какое это событие, — в обработчике или у параметра с классом события: event.weapon_entity становится event.weapon, event.authid — event.steamId, event.tracehandle — event.trace, event.infobuffer — event.info, а ({ dir }) — ({ direction: dir }). В список на ручную правку попадают "CS_OnBuy" и "CS_OnBuyAttempt" модуля cstrike: это события игры buyWeapon, buyItem, buyAmmo и itemRestricted.

Сообщение игры слушается своим методом, по имени в словах игрока (сообщения): server.addEventListener("message:DeathMsg", ...) становится server.addMessageListener("death", ...), а removeEventListener — removeMessageListener. Имя сообщения, которого у игры нет, выводится в список.

Имя флага — lowerCamelCase (флаги): player.buttons.includes("Jump") становится player.buttons.includes("jump"), { access: "Kick" } — { access: "kick" }. Строка считается флагом там, где файл это говорит: она присваивается свойству-флагу или опциям buttons и access, передаётся в includes, push или concat такого свойства или в player.screen.hideHud, сравнивается с его элементом — в его filter, for of, switch — или хранится в имени флагового типа (Button, HideHud[]). Имя, переданное туда, где ждут флаги, прослеживается до списка, с которым оно объявлено; то, чего файл не говорит, — параметр без типа, импорт, результат функции — выводится в список.

info

npx amxts info

Всё, что нужно для отчёта об ошибке: система, Node, Bun, менеджер пакетов, команда, ядро и его компиляторы, модули проекта, AMXTS_SERVER и система, под которую компилируются плагины.

amxts info - paste this into a bug report

  Operating system  Windows 10.0.19045 (x64)
  Node.js           24.18.0
  Bun               1.4.2
  Package manager   npm 11.16.0
  @amxts/cli        0.2.0
  @amxts/core       0.2.0
  AssemblyScript    0.28.20 + amxts patch
  WAMR              2.4.5 + amxts patch, wamrc found
  Project           my-server
  Modules           @amxts/menu-core 0.2.0
  AMXTS_SERVER      D:/hlds/cstrike/addons/amxts
  Server system     Windows (hlds.exe)
  AMXTS_DOCS_LANG   en