amxts - плагины AMX Mod X на TypeScript

amxts - плагины AMX Mod X на TypeScript 0.3.3

Нет прав для скачивания
Версия Дата выпуска Скачивания Рейтинг
0.3.3 2 0,00 звёзд Оценок: 0
0.3.2 10 0,00 звёзд Оценок: 0
0.3.1 1 0,00 звёзд Оценок: 0
amxts 0.3.3 — семиклип в самом ядре, что видит каждый игрок, ошибка слушателя больше не теряется.

Плагины, собранные под 0.3.0, 0.3.1 и 0.3.2, работают на модуле 0.3.3 как есть. Для нового нужен модуль 0.3.3 — npx amxts upgrade ставит его на сервер.

🚶 Игроки проходят друг сквозь друга — без других модулей
Для семиклипа был нужен модуль ReSemiclip. Теперь это делает само ядро: два игрока, которых вы связали, проходят друг сквозь друга, клиент предсказывает это без рывков, а близкий партнёр может стать прозрачным или пропасть из вида. Всё работает внутри модуля, без вызова плагина на каждую пару, и сервер без пар ничего за это не платит:
JavaScript:
game.addEventListener("spawn", ({ player }) => {
    for (const mate of server.players) if (mate.team == player.team) player.walksThrough.add(mate);
}, true);

server.walkThroughLook = {
    fadeDistance: 250,   // ближе — партнёр прозрачный...
    opacity: 0.4,        // ...вот настолько вплотную
    hideDistance: 48,    // а ближе этого не рисуется вовсе
};
Невидимый вблизи партнёр не мешает и прицелу: ник под прицелом, выстрелы и +use проходят сквозь него. А на ReGameDLL партнёр не закрывает вас от флешки.

Официальный модуль resemiclip теперь называется semiclip (@amxts/semiclip 0.2.0) и работает на парах ядра — модуль ReSemiclip в Metamod ему больше не нужен. Без своего правила союзники проходят друг сквозь друга, вблизи полупрозрачны, а вплотную пропадают. Правило задаётся одной строкой в любом плагине, например все сквозь всех на KZ: semiclip.rule = () => true. npx amxts upgrade сам заменит старый пакет на новый.

👁️ Что получает каждый игрок
К entityState добавились clientData — что клиенту игрока сообщают о нём самом, visibility — откуда сервер смотрит, выбирая, что ему послать, и cmdStart — команда движения от его клиента. Каждое пишется для одного игрока, а сервер без слушателей за это не платит:
JavaScript:
game.addEventListener("clientData", (event) => {
    if (event.player.flags.includes("onGround")) return;
    event.maxSpeed = 200;   // в воздухе клиент предсказывает его медленнее
});
Повтор, перемотка, камера: плагин может послать игроку место, далёкое от его глаз, и заморозить или замедлить то, что он там видит, не трогая остальных.

🧯 Ошибка не теряется
throw в слушателе, до которого дошёл ваш код из try или async-функции, молча обрывал слушателя и попадал в ваш код. Теперь слушатель — отдельный вызов, откуда бы он ни начался: его ошибка заканчивает только его, консоль называет его, а ваш код идёт дальше. Каждая ошибка плагина теперь пишется и в лог AMX Mod X (addons/amxmodx/logs), не только в консоль.

👀 Ещё
  • weapon.viewBody — какой вид оружия из моделей с несколькими body group показывают руки игрока, и зритель от первого лица видит то же
  • entityState: анимация модели — sequence, frame, frameRate и другие, для одного игрока
  • new UserMessage("MyJump") — своё сообщение по имени, например для клиентского мода; Pawn-плагины видят его тоже
  • tempEntity — спреи, искры, лучи; recipients — любое сообщение только части игроков
  • Сборка быстрее, и нужен только Node 24: все задачи amxts идут на Node, Bun проект больше не ставит. Сохранение в amxts dev пересобирает большой плагин в разы быстрее
  • Загрузка .aot на работающий сервер перезапускает только этот плагин, а server.keep / server.kept переносят его данные через перезапуск
  • Строка в plugins.ini загружает или выгружает плагин без перезапуска сервера; словарь читается заново, как только загружен
  • Слушатель, таймер или команда дольше amxts_slow_ms называются в консоли и в логе — с плагином, временем и самым медленным в этом вызове
  • server.precached и предупреждение, когда прекеш подходит к пределу движка в 512
  • Строки запроса к базе приходят в несколько раз быстрее: JSON.parse читает текст сразу в нужный тип
  • amxts build --against amxts_amxx_i386.so — загрузит ли модуль сервера собранные плагины, ещё до загрузки на сервер
  • for...of и [...] обходят любой класс с values(), как Set: for (const partner of player.walksThrough)

🩹 Исправления
  • ReHLDS, остановленный панелью, docker stop или systemd, падал при выходе и терял последнюю секунду Storage
  • Ошибка между message_begin и message_end или неудачный message_begin могли уронить сервер
  • Строка чата длиннее сообщения движка (перевод на грузинский, длинный ник) роняла сервер — теперь обрезается
  • Цикл, который хранит индекс лучшего элемента по дробному сравнению, возвращал 0
  • Плагин, которому не хватило памяти, засыпал консоль ошибками — теперь останавливается с одной строкой, а amxts_reload запускает его снова
  • SteamID в команде консоли (amx_ban STEAM_0:1:123) приходил пятью словами
  • player.kill() не убивал добавленного плагином бота на игре Valve; entity.killed(world, 0) ронял такой сервер
  • Запись в Storage, сделанная до нового поля, теряла значения по умолчанию
  • На Windows с незнакомым mp.dll game.restartRound() мог уронить сервер

✅ Как обновиться
C-подобный:
npm install -D @amxts/cli@latest
npx amxts upgrade
Команда и ядро в этот раз обновляются вместе: amxts 0.3.3 работает только с ядром 0.3.3. Сначала команда, потом upgrade. Пересоберите все плагины, чтобы получить исправления компилятора. Если npx amxts upgrade старой командой 0.3.2 остановился с «speaks cli-api 6» — запустите его ещё раз, дальше доделает новая команда.

Полный список изменений: релиз v0.3.3 на GitHub
Документация: amxts.github.io/docs
  • Нравится
Реакции: wopox1337
amxts 0.3.2 — forward'ы C++-модулей в TypeScript, обычный HLDS слышит игру до того, как она действует.

Плагины, собранные под 0.3.0 и 0.3.1, работают на модуле 0.3.2 как есть. Для нового нужен модуль 0.3.2 — npx amxts upgrade ставит его на сервер.

🔌 Forward'ы C++-модулей
Forward, который поднимает модуль AMX Mod X на C++ (MF_ExecuteForward), доходит до Forward.subscribe после Pawn-плагинов — с числами, строками, массивами и значениями по ссылке:
JavaScript:
const jumped = new Forward<Player, number>("mymodule_on_jump");

jumped.subscribe((player, height) => {
    console.log(`${player.name} прыгнул на ${height}`);
});
amxts_amxx должен стоять первой строкой в modules.ini — npx amxts upgrade ставит его туда сам, а консоль сервера называет модули, которые выше.

🎯 Обычный HLDS слышит игру первым
Без ReGameDLL большинство событий правил игры приходили уже после того, как игра действовала, а вопросы (fallDamage, canHaveItem, canRespawn…) не приходили вовсе. Теперь они слышны как на ReGameDLL: до игры, с ответом, записью полей и preventDefault():
JavaScript:
game.addEventListener("addMoney", (event) => {
    if (event.player.isBot) event.amount = 0;
});
Это 21 событие — вопросы, playerSpawn, playerKilled, newRound, deathNotice, gameThink и другие — плюс addMoney и giveDefaultItems. На Linux — с любой сборкой игры, на Windows — со сборками Valve, которые amxts знает: из steam и её ветка steam_legacy.

👀 Ещё
  • Байт — это число: элемент Uint8Array — number, как в JavaScript, и bytes[i] | (bytes[i + 1] << 8) даёт то же, что в JavaScript. Циклы по байтам быстрее того же цикла на Pawn
  • push и unshift принимают сколько угодно значений: names.push("a", "b"), names.push(...others)
  • entity.touch() и действия сущностей стали дешевле — быстрее Pawn на всех машинах, где идут замеры

🩹 Исправления
  • ExecuteHam(Ham_DeathSound, …) и другие функции, которых нет в Counter-Strike, роняли сервер — теперь вызов отвечает 0 и пишет об этом в консоль один раз
  • bytes[i] << 8 обрезался до 8 бит
  • Остановленный Pawn-forward доходил до подписчиков на TypeScript
  • Generic-вызов стрелочной функции, объявленной ниже по файлу, не собирался

⚠️ Что поменять в коде
  • В событии use event.activator — тот, кто использует сущность, event.caller — то, что передало использование; раньше было наоборот. npx amxts upgrade покажет такие места

✅ Как обновиться
C-подобный:
npm install -D @amxts/cli@latest
npx amxts upgrade

Полный список изменений: релиз v0.3.2 на GitHub
Документация: amxts.github.io/docs
  • Нравится
Реакции: wopox1337
amxts 0.3.1 — база данных MySQL прямо в плагине, и ничего больше не держит кадр сервера.

Плагины, собранные под 0.3.0, работают на модуле 0.3.1 как есть. Для нового нужен модуль 0.3.1 — npx amxts upgrade ставит его на сервер.

🗄️ MySQL в amxts
Модуль сам говорит с MySQL и MariaDB — без сторонних библиотек, с TLS — и каждый запрос идёт в своём потоке: сервер никогда не ждёт базу. Таблицы описываются на TypeScript, как в Drizzle, строки приходят с типами:
JavaScript:
import { asc, double, eq, int, table, varchar } from "@amxts/core/database";

export const records = table("records", {
    id: int().primaryKey().autoincrement(),
    steamId: varchar(32).notNull(),
    map: varchar(64).notNull(),
    time: double().notNull(),
});

const db = new Database(env("MYPLUGIN_DB"));   // mysql://… или jdbc:mysql://… прямо из панели хостинга
await db.create(records);

const top = await db.select().from(records)
    .where(eq(records.map, server.map))
    .orderBy(asc(records.time))
    .limit(10);
Опечатка в имени колонки видна в редакторе, значения уходят параметрами, а не текстом SQL. Есть транзакции, сырой SQL рядом (db.query), файлы в BLOB-колонках как Uint8Array. Другие базы подключаются провайдерами.

⚡ Ничего не держит кадр
Распаковка скачанной карты больше не даёт лаг: await fs.extract(bytes) работает в потоке модуля. Так же запись и чтение байтов и новое сжатие — @amxts/core/zlib как в Node: gzip, gunzip, deflate, inflate.

👀 Новое в API
  • Своё движение игрока: player.movement.airAccelerate = 100, friction, stopSpeed и другие — сервер двигает его с ними, а игра предсказывает их, на любом сервере
  • Свои поля на сущностях, как у игрока: door.doorSpeed — общие для плагинов, исчезают вместе с сущностью
  • Кто что слышит: звук и выстрел можно отдать только части игроков — event.recipients = [...]; звук одному игроку — door.emitSound(sample, { to: player })
  • HUD без мигания: new HudLine({ priority: 1 }) — строка важнее держит свой канал
  • entity.touch(other), entity.restart(), player.resetMaxSpeed(), player.jumpSlowdown, server.intermission(), fs.existsSync(path, { game: true })
  • На обычном HLDS теперь слышно событие move
Каждый новый вызов проверяется против того же действия на Pawn — и быстрее него.

🩹 Исправления
  • Storage.get терял последний символ у значения длиннее 1 КБ
  • amxclient_cmd из Pawn-плагина доходит до команд на TypeScript
  • Плагин можно назвать как файл ядра (hooks.ts, facade.ts)
  • Infinity | 0 и большие числа считаются как в JavaScript
  • Модуль показывает свою версию в amxx modules

⚠️ Что поменять в коде
  • fs.extract(bytes) теперь промис: await fs.extract(bytes) или синхронный fs.extractSync(bytes) — npx amxts upgrade перепишет сам
  • В событии startSound event.recipients — список игроков, а не число — upgrade покажет такие места

✅ Как обновиться
Нужен Node.js 24 или новее: на Node 22 npm 10 на Linux не может поставить тестовый раннер нового проекта.
C-подобный:
npm install -D @amxts/cli@latest
npx amxts upgrade

Полный список изменений: релиз v0.3.1 на GitHub
Документация: amxts.github.io/docs
  • Нравится
Реакции: wopox1337, WessTorn и RAMA
amxts 0.3.0 — большое обновление: модуль стал один, ReAPI больше не нужен, а плагины на TypeScript работают не медленнее Pawn.

📣 Главное

🧱 amxts — теперь один модуль
В 0.2 было две части: модуль amxts_amxx и плагин-хост amxts_host.amxx в plugins.ini, через который события игры шли в TypeScript. В 0.3 хоста нет: модуль сам слушает игру — команды игроков, сообщения, квары, лог, меню и хуки ReGameDLL/ReHLDS. Между игрой и вашим кодом больше нет Pawn.
Заодно amxts стал быстрее: на каждом замере тестового набора плагин на TypeScript работает как минимум так же быстро, как его двойник на Pawn, а на большинстве — быстрее.

🚫 ReAPI не нужен
То, что делали натив ReAPI rg_*, модуль делает сам — через API ReGameDLL, а на чистом HLDS через функции игры. Выдача и отбор оружия, смена команды, возрождение, модели, HUD, текстовые меню, game.restartRound() работают одинаково на:
  • ReHLDS + ReGameDLL, с ReAPI и без;
  • обычном HLDS от Valve с metamod-p.

🖥️ Сервер только загружает, собирает ваш компьютер
Сервер больше ничего не компилирует: он загружает готовые .aot. Собираете npx amxts build и заливаете — или amxts dev / build --deploy делают это сами, как .sma компилируют дома и заливают .amxx. Комплект для сервера стал в разы меньше.

🔗 Одна линия — один ABI
Плагин, собранный под 0.3.0, загружается на любом модуле 0.3: 0.3.1, 0.3.2 и дальше. Патч ядра не заставляет ничего пересобирать.

👀 Что нового

🔐 Секреты через env() — токен или ключ не попадают в код и в .aot, а читаются на сервере из addons/amxts/.env или окружения:
JavaScript:
const token = env("MYPLUGIN_TOKEN");          // обязательный: текст
const maxRecords = env("MYPLUGIN_MAX", 100);  // число
const debug = env("MYPLUGIN_DEBUG", false);   // вкл/выкл

💬 player.print и server.print
JavaScript:
player.print(`С возвращением, ${player.name}!`);
player.print("Раунд перезапущен", "center");
server.print("Смена карты через 30 секунд");

⌨️ Команды с несколькими именами, обработчик получает игрока:
JavaScript:
server.addCommand(["/cp", "cp"], (player) => player.print("Чекпоинт сохранён"));
А каждая команда игрока доходит до события "command", где preventDefault() её останавливает.

👁️ Что видит каждый игрок — событие "entityState": меняете то, что сервер шлёт одному игроку про одну сущность, и изменение видит только он.

🧩 Плагины, управляющие плагинами — server.plugins: список всех плагинов (TypeScript и Pawn), остановка, запуск, перезагрузка, вызов публичной функции Pawn-плагина.

💾 Storage с типами — new Storage<T>(name) хранит любой интерфейс в JSON и один раз забирает nVault-файл с тем же именем, так что при переносе с Pawn ничего не теряется.

📦 Файлы, загрузки и архивы — файлы читаются и пишутся байтами, fs.extract распаковывает zip: плагин может скачать карту и положить её на место.

🏃 Движение игрока — у событий движения есть event.touchCount и event.frameTime: хватает для jump stats без get_pmove из ReAPI.

🛠️ И ещё
  • трассировки: trace.line, player.aim (куда смотрит игрок), canSee;
  • сообщения по имени: player.send и server.send;
  • игрок: player.model, player.info, player.country, player.showMotd;
  • экран: player.screen.hint и HudLine.showAll;
  • выстрелы: остановить выстрел или показать его только части игроков;
  • у amxts dev панель: карта, игроки, FPS, состояние плагинов, клавиши пересборки, смены карты и рестарта раунда; amxts rcon шлёт команду серверу.

✅ Как обновиться
Сначала обновите команду пакетным менеджером проекта:
C-подобный:
npm install -D @amxts/cli@latest
Потом:
C-подобный:
npx amxts upgrade
Он переведёт @amxts/core на 0.3.0 и модули на их версии, перепишет код под изменения API, соберёт проект и поставит модуль 0.3.0 на сервер из AMXTS_SERVER. Что нужно проверить руками, он перечислит в конце. Плагин amxts_host.amxx и папки addons/amxts/tools/ и build/ старого комплекта больше не нужны.

Полный список изменений и таблица несовместимостей: релиз v0.3.0 на GitHub
Документация: amxts.github.io/docs
  • Нравится
Реакции: mIDnight и wopox1337
Назад
Верх