• Из-за обновления 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.3.0-dev

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

DaVilka

Гений
BackEnd developer
16 Сен 2020
827
328
128
  • RoflanEbalo
Реакции: fivepkost

Farko

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

DaVilka

Гений
BackEnd developer
16 Сен 2020
827
328
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
 

Similar threads