• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    Ошибка: Ваша версия Grand Theft Auto V не поддерживается RAGE Multiplayer.
    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

MiNT Multiplayer v0.6.0-dev

Кликни, чтобы узнать больше!

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
  • RoflanEbalo
Реакции: mishamap и fivepkost

Farko

nc -lvnp 4444
28 Окт 2025
621
125
77
с версии 0.1.0 на версию 1.0 за 4 дня? эх мне бы так
1789468147853.png
 

sonnyk

Участник портала
26 Ноя 2022
145
21
73
по канону версионирования, нужно остановиться на 1.1-beta. Через 3 года выйти из беты, а на следующий год закрыть платформу
 

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
Обновление 0.3.0 — большое обновление C#, этап второй.

Добавлены короткий серверный API, поддержка асинхронных обработчиков, перехват урона, огня и взрывов. Расширено событие отключения игрока и управление отображением интерфейсов.

Добавлен класс Api — аналог Alt в alt:V по назначению.
Это короткая точка доступа к серверному C# SDK: создание и поиск сущностей, события, метаданные, ресурсы, RPC и другие операции.
В классе 215 публичных методов с учётом перегрузок, 49 событий и 11 свойств. Группированный API через Server также остаётся доступен.
C#:
using System.Threading;
using System.Threading.Tasks;
using Mint.Server;
using Mint.Server.Events;
using Mint.Server.Players;
using Mint.Server.Shared;

// Создание транспорта.
var vehicle = Api.CreateVehicle("sultan", new Vector3(100, 200, 30));

// Поиск игрока и отправка клиентского события.
var player = Api.GetPlayerById(1);
if (player is not null)
    Api.EmitClient(player, "notification", "Привет!");

// Событие всем игрокам.
Api.EmitAllClients("announcement", "Сервер обновлён!");

// Типизированные метаданные.
Api.SetMeta("weather", "CLEAR");
var weather = Api.GetMeta<string>("weather");

// Экспорт функции для других ресурсов.
Api.Export("sum", (int a, int b) => a + b);
Примеры подписок ниже размещаются в OnStart() ресурса.
Добавлена поддержка асинхронного выполнения в C#.
Она встроена в основной SDK: отдельная библиотека и классы вроде AsyncPlayer не требуются.
Обработчики могут возвращать Task или ValueTask, ожидать запрос к БД, HTTP или другую асинхронную операцию. После обычного await выполнение продолжается в контексте ресурса, где снова доступна работа с SDK.
C#:
Api.OnClientAsync("request", async (IPlayer player, string message) =>
{
    await Task.Delay(1000); // Например, ожидание запроса к БД.

    if (!player.Valid) return;
    Api.EmitClient(player, "response", $"Получено: {message}");
});

Для отмены ожидания при остановке ресурса можно добавить CancellationToken. Runtime передаёт его автоматически — отправлять токен с клиента не нужно.
C#:
Api.OnClientAsync("request", async (
    IPlayer player, string message, CancellationToken token) =>
{
    await Task.Delay(1000, token);

    if (!player.Valid) return;
    Api.EmitClient(player, "response", message);
});
Для запуска отдельной асинхронной операции доступен dispatcher:
C#:
_ = Api.Dispatcher.RunAsync(async token =>
{
    await Task.Delay(5000, token);
    Api.EmitAllClients("announcement", "Прошло пять секунд!");
});
Поддерживаются асинхронные серверные и клиентские события, одноразовые подписки, обработчики через атрибуты и RPC. Для обращения к SDK из стороннего потока используется Api.Dispatcher.InvokeAsync(...).
Ограничения:
  • async void не поддерживается.
  • OnStart, OnTick, OnStop и хуки IModule остаются синхронными.
  • RunAsync не переносит вычисления в отдельный поток. Для тяжёлых вычислений используется Task.Run, внутри которого нельзя напрямую обращаться к живым сущностям.
  • После await сущность могла быть удалена или игрок мог отключиться — проверяйте Valid.
  • События, требующие немедленного решения, обрабатываются синхронно.
  • Асинхронные результаты межресурсных exports пока не поддерживаются.
Добавлены серверные события fire, explosion и weaponDamage.
Они доступны в C# и JavaScript.
fire позволяет разрешить или запретить создание пожара. Обработчик получает отправителя запроса, позицию и сущность, к которой привязан огонь. Для огня на земле сущность равна null.
explosion позволяет разрешить или запретить взрыв. Передаются отправитель запроса, тип взрыва, позиция и множитель урона.
У обоих событий false запрещает эффект. Отправитель запроса не обязательно является виновником; для серверного источника он может быть null. Изменение урона через эти два события пока не поддерживается. Отмена fire не тушит уже существующий пожар.
Примеры на C#:
C#:
// Разрешить огонь на сущностях, запретить отдельные пожары на земле.
Api.OnFire += (reporter, position, entity) =>
{
    Api.Log($"Пожар: {position}, сущность: {entity?.Id}");
    return entity is not null;
};

// Запретить взрывы ракет.
Api.OnExplosion += (reporter, type, position, damageScale) =>
{
    Api.Log($"Взрыв: {type}, множитель урона: {damageScale}");
    return type != ExplosionType.Rocket;
};

Примеры на серверном JS:

JavaScript:
import * as mint from 'mint-server';

mint.on('fire', (reporter, position, entity) => {
    return entity != null;
});

mint.on('explosion', (reporter, type, position, damageScale) => {
    return type !== 4; // 4 — взрыв ракеты.
});

Также можно поджечь колесо автомобиля или запустить таймер его взрыва. Создаваемые эффекты проходят соответствующие серверные проверки.
C#:
// vehicle и player — действующие сущности.
vehicle.Wheels.SetWheelOnFire((byte)0, true);
vehicle.Weapons.SetTimedExplosion(true, player, 3000);
JavaScript:
vehicle.setWheelOnFire(0, true);
vehicle.setTimedExplosion(true, player, 3000);

weaponDamage позволяет отменить попадание или изменить величину урона.
Добавлена обработка обычных ударов ближнего боя, включая кулаки и холодное оружие.
Обработчик получает атакующего, цель, хеш оружия, урон, смещение точки попадания относительно цели и идентификатор кости GTA.
Пример на C#: запрет ударов кулаками и уменьшение остального поддерживаемого урона вдвое.
C#:
Api.OnWeaponDamage += (source, target, weapon, damage, offset, bone) =>
{
    if (weapon == Api.Hash("WEAPON_UNARMED"))
        return WeaponDamageResult.Cancel;

    return WeaponDamageResult.WithDamage(damage * 0.5f);
};
Для сохранения исходного урона возвращается WeaponDamageResult.Allow.
Аналогичный пример на серверном JS:
JavaScript:
mint.on('weaponDamage', (source, target, weapon, damage, offset, bone) => {
    if (weapon === mint.hash('WEAPON_UNARMED'))
        return false;

    return damage * 0.5;
});
В JS false отменяет попадание, число заменяет урон, true или отсутствие возвращаемого значения сохраняет его.
Перехват охватывает поддерживаемые попадания из ручного огнестрельного оружия и обычные melee-удары по игрокам и динамическим серверным педам с назначенным владельцем. Транспорт и объекты как цели, урон взрывов и парные добивания пока не входят в это покрытие.
Величина damage передаётся в расчёт GTA: итоговая потеря HP также зависит от брони и других игровых модификаторов.
Все три события требуют синхронного решения — async и await в их обработчиках не поддерживаются.
В событие playerDisconnect добавлен снимок последних известных серверу данных игрока.
Теперь параметры события:
Код:
player, reason, snapshot
  • player — уже недействительная сущность отключившегося игрока.
  • reason — причина отключения.
  • snapshot — неизменяемый снимок данных, сохранённый до очистки сессии.
Снимок можно читать после await, например при сохранении персонажа.
| C# | JS | Данные |
|---|---|---|
| Id | id | ID игрока |
| Name | name | Имя |
| Position | position | Позиция |
| Rotation | rotation | Поворот в радианах |
| Velocity | velocity | Скорость |
| Dimension | dimension | Измерение |
| Model | model | Хеш модели |
| Health, MaxHealth | health, maxHealth | Здоровье и его максимум |
| Armor, MaxArmor | armour, maxArmour | Броня и её максимум |
| CurrentWeapon | currentWeapon | Хеш текущего оружия |
| VehicleId | vehicleId | ID транспорта либо null |
| Seat | seat | Место в транспорте либо null; водитель — 1 |
| Interior | interior | Интерьер |
| IsDead | isDead | Состояние смерти |
Пример на C#:
C#:
Api.OnPlayerDisconnect += (player, reason, snapshot) =>
{
    Api.Log($"{snapshot.Name} отключился: {reason}");
    Api.Log($"Последняя позиция: {snapshot.Position}");
};
Пример на серверном JS:
JavaScript:
mint.on('playerDisconnect', (player, reason, snapshot) => {
    mint.log(`${snapshot.name} отключился: ${reason}`);
    mint.log(`Последнее здоровье: ${snapshot.health}`);
});
Существующие C#-обработчики необходимо обновить с учётом третьего параметра.
Для CEF WebView, RmlDocument и TextLabel добавлено свойство showOnPauseMenu.
Оно определяет, продолжит ли объект отображаться при открытой игровой карте или меню паузы. По умолчанию — false.
JavaScript:
webView.showOnPauseMenu = true;
rmlDocument.showOnPauseMenu = true;
textLabel.showOnPauseMenu = true;
Для серверного TextLabel в C#:
C#:
textLabel.ShowOnPauseMenu = true;
Исправления:
  • Исправлен краш клиента при выполнении clear в консоли с большим количеством сообщений и появившейся полосой прокрутки.
  • Исправлена ошибка времени жизни C#-сущностей, из-за которой действующий TextLabel мог ошибочно считаться удалённым.
  • Исправлено нанесение урона и добивание обычными melee-ударами: цель больше не остаётся с 1 HP при достаточном разрешённом уроне.
  • Увеличен лимит всплеска пакетов который генерируется при блокировке мейнпотока сложными задачами и защиты от флуда
  • Увеличен размер максимального размера одного dlc.rpf до 5 гиг
MiNT Multiplayer v0.3.0-dev Git
 
Последнее редактирование:

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
Обновление 0.4.0

Переход на нативную синхронизацию.
Переход проводился точечно, что бы избежать переноса всей нативной сети. Основной акцент был сделан именно на синхронизации между игроками и игровыми сущностями.
Из-за технических ограничений максимальное количество игроков в зоне стрима было временно уменьшено до 64, а онлайна до 1000.
Старая система синхронизации была удалена, но ещё не полностью. В связи с этим после обновления могут встречаться отдельные баги и нестандартное поведение.

Исправления:
  • Исправлены призрачные авто.
  • Исправлен туман войны.
  • Исправлена проблема с weaponDamage, из-за которой урон в некоторых случаях не проходил.

MiNT Multiplayer v0.4.0-dev Git
 

Walter

Начинающий специалист
15 Сен 2020
326
65
89

syavaqq

Новый участник
21 Май 2023
71
1
65
Обновление 0.4.0

Переход на нативную синхронизацию.
Переход проводился точечно, что бы избежать переноса всей нативной сети. Основной акцент был сделан именно на синхронизации между игроками и игровыми сущностями.
Из-за технических ограничений максимальное количество игроков в зоне стрима было временно уменьшено до 64, а онлайна до 1000.
Старая система синхронизации была удалена, но ещё не полностью. В связи с этим после обновления могут встречаться отдельные баги и нестандартное поведение.

Исправления:
  • Исправлены призрачные авто.
  • Исправлен туман войны.
  • Исправлена проблема с weaponDamage, из-за которой урон в некоторых случаях не проходил.

MiNT Multiplayer v0.4.0-dev Git
не запускается launcher.exe
 

Вложения

  • 1790464944763.png
    1790464944763.png
    30.2 KB · Просмотры: 146

TTox421

Участник портала
23 Май 2021
67
19
65
А че не сделаешь свой сайт, где можно будет выкачать клиент для игроков и сервер для разрабов, как у altv, глядишь возможно пойдет в гору дела)


правда потом придут тейк ту)
 

Minotheo

Активный участник
28 Сен 2021
40
26
79
А че не сделаешь свой сайт, где можно будет выкачать клиент для игроков и сервер для разрабов, как у altv, глядишь возможно пойдет в гору дела)


правда потом придут тейк ту)
В сказки про T2 веришь, им поебать конкретно на СНГ.
 

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
А че не сделаешь свой сайт, где можно будет выкачать клиент для игроков и сервер для разрабов, как у altv, глядишь возможно пойдет в гору дела)


правда потом придут тейк ту)
я б уже выкатил, работы с мультом много, не успеваю делать все
 

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
Обновление 0.5.0

Параметр resourcesPath заменён на resources для явного указания загружаемых ресурсов. Ресурсы размещаются в постоянной папке resources рядом с серверным TOML.
Код:
resources = ["chat", "npc", "core"]
Отсутствующий или пустой список означает запуск без ресурсов.

Добавлен параметр dlcWhitelist, который задаётся в корне серверного TOML.
Пустой список или отсутствие настройки сохраняет штатный выбор DLC GTA. Непустой список разрешает только перечисленные штатные DLC; пользовательские DLC добавляются отдельно.
Указываются имена папок DLC без префикса dlc_, суффикса CRC и полного пути.
Код:
dlcWhitelist = ["mpheist", "mpapartment"]
Добавлена секция [pools] в клиентском client.toml — ограниченный аналог настройки пулов через gameconfig. Пока настраивается только на стороне клиента.
Значения задают количество элементов пула. Ниже приведён пример настройки, а не значения по умолчанию:
Код:
[pools]
# Записи метаданных игровых ресурсов
MetaDataStore = 7000

# Словари текстур
TxdStore = 110000

# Фрагментные модели, включая модели с разрушаемыми частями
FragmentStore = 62000

# Словари анимаций
AnimStore = 22000

# Ресурсы интерфейса Scaleform
ScaleformStore = 1200

# Данные подбираемых предметов
CPickupData = 1100
Изменять настройки нужно при закрытой GTA. Они применяются при следующем запуске игры; переподключения к серверу недостаточно.

Добавлен параметр cdnEnabled, включающий загрузку клиентских ресурсов с CDN. Для включения нужны корректный cdnUrl и заранее подготовленная публикация ресурсов. При cdnEnabled = false ресурсы собирает и раздаёт сервер.
Добавлен параметр encryptResources, управляющий шифрованием публикуемых клиентских ресурсов: stream/DLC, клиентских скриптов и UI.
Оба параметра задаются в корне серверного TOML и по умолчанию выключены:
Код:
cdnEnabled = false
encryptResources = false
При debug = true настройки CDN и шифрования игнорируются.
Добавлена секция [overrides] в stream-манифесте для замены файлов GTA по виртуальному пути. Формат: MOUNT_PATH = REPLACEMENT_PATH.
Код:
[overrides]
"commoncrc:/data/levels/gta5/water.xml" = "replaces/water.xml"
"dlc_mpApartmentCRC:/content.xml" = "replaces/mpapartment/content.xml"
"dlcMPHeistCRC:/content.xml" = "replaces/mpheist/content.xml"
Путь к файлу замены указывается относительно корня ресурса. Файл должен входить в client-files, например:
Код:
client-files = ["replaces/**"]
Поддерживаются XML, META, DAT, YTD, YDR, YFT, YDD и YMT. Расширения исходного и заменяемого файлов должны совпадать.
Один и тот же файл замены нельзя одновременно объявлять в [meta]: он уже обслуживается через boot override.
Overrides пока несовместимы с включённым шифрованием ресурсов: при encryptResources = true и debug = false сервер отклоняет такую публикацию.
Изменение dlcWhitelist или [overrides] требует перезапуска GTA.
Поддержка [pools], dlcWhitelist и [overrides] реализована для GTA 3889.

Добавлены консольные команды:
  • quit — закрывает GTA/клиент.
  • disconnect — отключается от сервера или отменяет текущее подключение.

Оптимизировано появление сущностей в зоне стриминга: создание распределяется по кадрам, устранена повторная переустановка хуков при появлении и удалении сущностей.

MiNT Multiplayer v0.5.0-dev
 

Walter

Начинающий специалист
15 Сен 2020
326
65
89

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128
Обновление 0.6.0

Браузер лаунчера был вынесен из ядра клиента в угоду более удобного расширения функционала клиента игры.

Добавлен API лаунчеру для пользовательских приложений.
Обмен данными происходит через stdin/stdout в формате JSON, а активация использования апи происходит передачей параметра лаунчеру Launcher.exe --api,
после чего лаунчер запустится скрытно и будет ждать команд.

После запуска лаунчер сообщает о готовности:
{"event":"ready","commands":["settings.get","settings.set","servers.list","update","prepare","launch","cancel","trust.confirm","shutdown"]}

Каждый запрос содержит:
id - положительное целое число, уникальное для запроса;
command - название команды;
остальные поля - параметры команды.

Команды:
settings.get - получить настройки client.toml.
{"id":1,"command":"settings.get"}

settings.set - изменить переданные настройки.
Доступные поля: playerName, gameDirectory, voiceVolume, microphoneVolume, microphoneEnabled, discordEnabled.
Громкость задаётся целым числом от 0 до 100.
{"id":2,"command":"settings.set","settings":{"playerName":"Player","voiceVolume":80}}

servers.list - получить список серверов в result.servers.
{"id":3,"command":"servers.list"}

update - проверить и установить обновления MiNT без запуска GTA.
{"id":4,"command":"update"}

prepare - проверить и загрузить ресурсы выбранного сервера.
Не обновляет MiNT, не требует установленной GTA и не запускает игру.
{"id":5,"command":"prepare","server":"127.0.0.1:22005"}

launch - обновить MiNT, подготовить ресурсы сервера и запустить GTA.
Предварительный prepare необязателен. Если ресурсы уже подготовлены, используется подходящий кеш.
{"id":6,"command":"launch","server":"127.0.0.1:22005"}

Дополнительные поля launch:
--gameDirectory - папка игры. Без неё используется сохранённый путь и автопоиск. Если GTA не найдена, возвращается ошибка без диалога выбора папки.
--offline - пропустить обновление MiNT. Проверка ресурсов сервера выполняется.
{"id":7,"command":"launch","server":"127.0.0.1:22005","gameDirectory":"D:\\Games\\GTA V","offline":true}

cancel - запросить отмену активной операции по id.
{"id":8,"command":"cancel","targetId":7}

trust.confirm - ответить на запрос подтверждения изменения ключа сервера.
targetId - id операции, requestId - строка из события trust.required.
{"id":9,"command":"trust.confirm","targetId":7,"requestId":"1","accepted":true}

shutdown - отменить активную операцию, дождаться очистки и завершить API.
{"id":10,"command":"shutdown"}

Ответы и события:

Каждый запрос получает один итоговый ответ с тем же id.
Успешный ответ:
{"id":5,"ok":true,"result":{"status":"ready"}}

Ошибка:
{"id":5,"ok":false,"error":{"code":"PREPARATION_FAILED","message":"Описание ошибки"}}

error.code предназначен для обработки в программе, error.message - сообщение.

Основные результаты:
update - status: ready либо skipped при offline: true;
prepare - status: ready;
launch - status: handedOff после первого успешного подключения;
cancel - status: cancelling; итог отменяемой операции приходит отдельно после очистки;
trust.confirm - status: accepted, решение принято в обработку;
shutdown - status: stopped, затем процесс завершается.

Промежуточные события содержат event и id соответствующего запроса.

progress - прогресс обновления, подготовки ресурсов или запуска.
stage: update, prepare или launch.
phase уточняет текущую работу.
completedBytes и totalBytes показывают прогресс текущей фазы, totalBytes: null - неизвестный объём.
События запуска могут содержать message вместо счётчиков.
{"id":5,"event":"progress","stage":"prepare","phase":"resources","completedBytes":5000,"totalBytes":10000}

trust.required - требуется решение пользователя о смене ключа сервера.
Содержит requestId, server, previousKey и candidateKey.
Покажите пользователю сервер и оба ключа, затем отправьте trust.confirm с accepted: true или false.

Одновременно выполняется одна операция. Пока она активна, обычные команды получают BUSY, cancel, trust.confirm и shutdown остаются доступны.
После итогового ответа API продолжает принимать команды. Результат операции определяется её JSON-ответом, а не кодом выхода процесса.
Python:
import itertools
import json
import subprocess


LAUNCHER = r"D:\MiNT\Launcher.exe"


def main():
    with subprocess.Popen(
        [LAUNCHER, "--api"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        creationflags=subprocess.CREATE_NO_WINDOW,
    ) as process:
        ids = itertools.count(1)

        def send(command, **arguments):
            request_id = next(ids)
            payload = {"id": request_id, "command": command, **arguments}
            process.stdin.write((json.dumps(payload, ensure_ascii=False) + "\n").encode("utf-8"))
            process.stdin.flush()
            return request_id

        def receive():
            line = process.stdout.readline()
            if not line:
                raise RuntimeError("MiNT API закрыл соединение до получения ответа")
            return json.loads(line.decode("utf-8"))

        def request(command, **arguments):
            request_id = send(command, **arguments)
            while True:
                message = receive()
                if "ok" in message:
                    if not message["ok"]:
                        error = message["error"]
                        raise RuntimeError(f"{error['code']}: {error['message']}")
                    if message["id"] == request_id:
                        return message["result"]
                    # Ответ trust.confirm тоже проходит через этот цикл.
                elif message.get("event") == "progress":
                    stage = message.get("stage", "")
                    if "message" in message:
                        print(stage, message["message"])
                    else:
                        done = message.get("completedBytes", 0)
                        total = message.get("totalBytes")
                        print(stage, message.get("phase", ""), f"{done}/{total or '?'} байт")
                elif message.get("event") == "trust.required":
                    print("Изменился ключ сервера:", message["server"])
                    print("Предыдущий:", message["previousKey"])
                    print("Новый:", message["candidateKey"])
                    accepted = input("Принять новый ключ? [да/нет]: ").strip().lower() == "да"
                    send("trust.confirm", targetId=message["id"],
                         requestId=message["requestId"], accepted=accepted)

        try:
            ready = receive()
            if ready.get("event") != "ready":
                raise RuntimeError(f"API не готов: {ready}")

            try:
                for server in request("servers.list")["servers"]:
                    host = server["host"]
                    address = f"[{host}]" if ":" in host else host
                    print(f"{server['name']} — {address}:{server['port']}")
            except RuntimeError as error:
                print("Список серверов недоступен:", error)

            endpoint = input("Адрес сервера (host:port): ").strip()
            request("prepare", server=endpoint)
            print("Ресурсы готовы. Запускаю GTA...")
            result = request("launch", server=endpoint)
            print("Результат запуска:", result["status"])
            request("shutdown")
        finally:
            try:
                process.stdin.close()
            except BrokenPipeError:
                pass
            for _ in process.stdout:
                pass
            process.wait()


if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("Операция остановлена.")
    except (OSError, RuntimeError) as error:
        print("Ошибка:", error)
Добавлены консольные команды:
mic-volume - громкость микрофона
voice-volume - громкость микрофона окружающих
netgraph - отображает фпс, пинг и вермя кадра

Расширен [pools](gameConfig) из 6 до 21 свойств и вынесен на сервеную сторону

Добавлена outline система:
JavaScript:
export interface IOutlineOptions {
    /** Стиль. По умолчанию: 'contour'. */
    style?: 'contour' | 'glow' | 'fill';

    /** Режим видимости. По умолчанию: 'xray'. */
    mode?: 'visible' | 'xray';

    /** RGBA: целые значения 0–255. По умолчанию: (0, 255, 255, 230). */
    color?: IRGBA;

    /** Толщина/радиус 1–8 пикселей. По умолчанию: 2. Для fill игнорируется. */
    width?: number;
}

export class Outline {
    constructor(options?: IOutlineOptions);

    readonly valid: boolean;
    readonly size: number;

    /** Присваивание заменяет настройки; пропущенные поля получают defaults. */
    options: IOutlineOptions;

    /** Entity или GTA scriptID, не сетевой ID. */
    add(target: Entity | number): boolean;
    remove(target: Entity | number): boolean;
    has(target: Entity | number): boolean;

    /** Убирает все цели, сохраняя группу и настройки. */
    clear(): void;

    /** Удаляет группу и освобождает слот. */
    destroy(): void;
}

/** Упрощённая подсветка одной цели. Следующий вызов заменяет предыдущую. */
export function setOutline(
    target: Entity | number,
    options?: IOutlineOptions,
): boolean;

/** Очищает одиночную подсветку текущего ресурса. */
export function clearOutline(): void;
На данный момент имеет несколько стилей(style), "contour" - чёткий внешний контур, "glow" - мягкое внешнее свечение и "fill" - заливка силуэта цветом,
mode, "visible" - учитывает глубину и "xray" - рисуется по верх всего
color { r, g, b, a } - цвет, включая прозрачность
width - число от 1–8, толщина контура или радиус свечения в пикселях
JavaScript:
import * as mint from 'mint-client';

const selected = new mint.Outline({
    style: 'glow',
    mode: 'visible',
    width: 6,
    color: new mint.RGBA(0, 255, 180, 220),
});

mint.on('keyup', key => {
    if (key === mint.KeyCode.F6) {
        selected.clear();

        if (!selected.add(mint.Player.local)) {
            mint.logWarning('Не удалось добавить игрока в подсветку.');
        }
        const vehicle = mint.Player.local.vehicle;

        if (vehicle && !selected.add(vehicle)) {
            mint.logWarning('Не удалось добавить машину в подсветку.');
        }
    } else if (key === mint.KeyCode.F9) {
        selected.clear();
    }
});
Настройки можно менять:
JavaScript:
selected.options = {
    ...selected.options,
    mode: 'xray',
};
1791484395803.png

Добавлен функционал в UI3D:
добавлено отображение авто
и добавлена функция snapshot которая возвращает gta - текстуру,
JavaScript:
import * as mint from 'mint-client';

const scene = new mint.Utils.UI3DScene('PAUSE_SINGLE_RIGHT', {
    overlay: true,
});

scene.setPed(0, mint.Player.local, {
    pos: { x: 0, y: 0.1, z: 0 },
    rot: { x: 0, y: 0, z: 15 },
    lightIntensity: 0.8,
});

const tick = mint.everyTick(() => scene.render());

mint.on('resourceStop', name => {
    if (name !== mint.resourceName) return;

    mint.clearEveryTick(tick);
    scene.destroy();
});
JavaScript:
import * as mint from 'mint-client';
import * as native from 'natives';

const scene = new mint.Utils.UI3DScene('PAUSE_SINGLE_RIGHT');

scene.setPed(0, mint.Player.local, {
    rot: { x: 0, y: 0, z: 15 },
    lightIntensity: 0.8,
});

const screen = mint.getScreenResolution();
const scale = Math.min(1, 2048 / Math.max(screen.x, screen.y));

let image;

try {
    image = await scene.snapshot({
        size: {
            x: Math.max(1, Math.round(screen.x * scale)),
            y: Math.max(1, Math.round(screen.y * scale)),
        },
        timeout: 5000,
    });
} finally {
    scene.destroy(); // Готовый снимок продолжает существовать.
}

const tick = mint.everyTick(() => {
    if (!image.valid) return;

    native.drawSprite(
        image.textureDict, image.textureName,
        0.5, 0.5, 1, 1,
        0, 255, 255, 255, 255,
        false, false,
    );
});

mint.on('resourceStop', name => {
    if (name !== mint.resourceName) return;

    mint.clearEveryTick(tick);
    image.destroy();
});
1791484464504.png

Добавлены и доработаны некоторые апи:
Добавлены события метки на карте персонажа
JavaScript:
waypointCreated: (position: Vector3) => void; - создана
waypointRemoved: (position: Vector3) => void; - удалена
waypointReached: (position: Vector3) => void; - игрок достиг точки
Прикрипление сущностей транспорта:
JavaScript:
entityAttached: (
    parent: Entity,
    child: Entity,
    kind: shared.AttachmentKind
) => void;

entityDetached: (
    parent: Entity,
    child: Entity,
    kind: shared.AttachmentKind
) => void;
export enum AttachmentKind {
    GenericPhysical = 0, // Обычное физическое прикрепление
    TrailerHitch = 1,    // Прицеп
    TowArm = 2,          // Эвакуатор
    CargobobHook = 3,    // Крюк Cargobob
    CargobobMagnet = 4,  // Магнит Cargobob
}
Добавлены TS-декларации vehicleAttach: (target: Vehicle, child: Vehicle) => void; и vehicleDetach: (target: Vehicle, child: Vehicle) => void;
Добавлен клиент-сервер ивент смены модели (игрока/педа/предмета/авто?)
JavaScript:
entityModelChange: (
    entity: Entity,
    oldModel: number,
    newModel: number
) => void;
Добавлен клиентский ивент weaponDamage:
JavaScript:
weaponDamage: (
    target: Entity,
    weaponHash: number,
    damage: number,
    offset: Vector3,
    bodyPart: BodyPart,
    sourceEntity: Entity
) => boolean | number | void;
Обновлен серверный ивент weaponDamage:
JavaScript:
weaponDamage: (
    source: Player,
    target: Entity,
    weaponHash: number,
    damage: number,
    shotOffset: shared.IVector3,
    bodyPart: shared.BodyPart,
    sourceEntity: Entity
) => boolean | number | void;
source - Игрок, отправивший серверу запрос попадания
target - Сущность, получающая попадание
weaponHash - Хеш оружия
damage - Входная величина урона; окончательная потеря HP зависит от расчёта GTA
offset / shotOffset - Точка попадания в локальных координатах цели
bodyPart - Область тела из BodyPart, например Head = 20, Unknown = -1
sourceEntity - источник попадани
Изменен серверный контракт: вместо прежнего boneId передаётся BodyPart, также добавлен sourceEntity.
Добавлены серверные ивенты о фактическом нанесении урона:
JavaScript:
playerDamage: (
    victim: Player,
    attacker: Entity | null,
    healthDamage: number,
    armourDamage: number,
    weaponHash: number
) => void;

pedDamage: (
    ped: Ped,
    attacker: Entity | null,
    healthDamage: number,
    armourDamage: number,
    weapon: number
) => void | boolean;

vehicleDamage: (
    vehicle: Vehicle,
    attacker: Entity | null,
    bodyHealthDamage: number,
    additionalBodyHealthDamage: number,
    engineHealthDamage: number,
    petrolTankDamage: number,
    weaponHash: number
) => void;
Добавлена функция вызова нативок по хешу:
JavaScript:
export function invoke(
    hash: string | bigint,
    ...args: unknown[]
): unknown;
JavaScript:
import * as native from 'natives';
const gameTimer = native.invoke('0x9CD27B0045628463');
Добавлен нативный метод statSetInt:
JavaScript:
export function statSetInt(
    statName: number,
    value: number,
    save: boolean
): boolean;
Доработана сборка ресурсов:
самостоятельные streaming-ассеты теперь собираются без фиктивной metadata
фикс маленького размера ресурса
Добавлен и интегрирован game-data.json который содержит информацию о штатных машинах, персонажах, оружии, одежды, скелетах моделей, палитру и категории колёс

Оптимизация клиента и исправления синхронихации:
Убраны лишние чтения состояний сущностей и часть работы на каждом кадре что увеличило фпс
Исправлена причина причина фризов связанная с аудио.
Исправлено зависание при запуске клиента
Исправлен разрыв соединения спавне авто с неверным хешем
Подняты лимиты контроллеров до количества сущностей в зоне стрима
убрана команда disconnect
MiNT Multiplayer v0.6.0-dev
 
Последнее редактирование:
Реакции: m0v1l3 и Inoi

E8ZYZE

Участник портала
10 Апр 2025
31
5
45
Сделай чтобы можно было отключать карту гта 5 и поставить свою
 

DaVilka

Гений
BackEnd developer
16 Сен 2020
848
347
128

Similar threads