Это большое обновление. Ядро переписано почти с нуля, API для модулей сделано заново, а все модули из комплекта обновлены и заодно избавлены от кучи старых багов.
Сделайте копию конфигов — папки addons/counterstrikesharp/configs/plugins/VIPCore/. На всякий случай, обычно она не понадобится.
Замените всё целиком: plugins/VIPCore, shared/VipCoreApi и все модули из VIP_Modules.zip. Старые модули от 1.x с новым ядром работать не будут, обновлять нужно всё сразу.
Сторонние модули, написанные под 1.x, тоже перестанут работать, пока их авторы не обновят их под новое API. Пример нового модуля есть в README.
Конфиги переносить не нужно
При первом запуске ядро само переведёт старые конфиги в новый формат:
в vip.json группы переедут из Groups / Values прямо в корень файла;
Delay переедет из vip.json в vip_core.json;
вместо UseCenterHtmlMenu теперь MenuType: center — меню по центру экрана, chat — в чате, console — в консоли;
старые файлы останутся рядом как vip.json.old и vip_core.json.old, если захотите сравнить.
База данных не меняется, все VIP-игроки сохраняют свой статус и срок.
Что появилось
Наследование групп. Больше не нужно копировать одни и те же фичи из группы в группу. Пишете в группе "$inherit": "VIP", и она получает всё, что есть у VIP, а сверху можно переопределить нужное. Если какая-то унаследованная фича не нужна, поставьте ей false или "", и в этой группе её не будет.
Админ-меню !vip_admin. Выдать VIP (на готовый срок или на своё время через чат), забрать VIP, перезагрузить конфиги и игроков — без консоли. Кому доступно меню, настраивается в vip_core.json → AdminMenuPermission.
В VIP-меню видны значения фич. Игрок сразу понимает, что у него есть: Деньги [+3000$], Скорость [+15%], Гравитация [-25%], Возрождение [1/2] (сколько осталось в раунде), Анти-Флеш [Все]. Включено/выключено теперь показывается коротко и цветом — зелёный ВКЛ, красный ВЫКЛ, и строки больше не переносятся.
Сообщения игроку, когда админ выдаёт, меняет или забирает его VIP.
Переводы всех модулей теперь в ядре. Раньше при установке модуля нужно было вручную дописывать строки в языковые файлы, теперь ничего добавлять не надо.
Новые команды: css_vip_admin (админ-меню), css_reload_vip_player <steamid> (перечитать VIP игрока из базы), css_vip_help (список всех команд).
Недоступную фичу больше нельзя получить никак. Раньше в некоторых модулях можно было пользоваться фичей, которой нет в группе или которую игрок сам выключил в меню (например, возрождение, сброс смертей, лечение союзников, меню оружия). Теперь это закрыто везде.
Эффекты снимаются сразу, когда VIP забрали или она закончилась: FOV, тег, гравитация, цветная модель, админ-флаги, множитель опыта. Раньше они могли висеть до перезахода.
VIP_Flags при смене группы снимает права старой группы, а не копит их.
VIP_Gifts: закрыта дыра, через которую ником игрока можно было выполнить любую консольную команду на сервере. И подарок больше не перезаписывает уже купленную VIP.
VIP_FastReload больше не даёт бесконечные патроны.
VIP_Gravity больше не ломается после лестницы.
VIP_Bhop плавно ограничивает скорость, без рывков.
VIP_Money больше не спамит ошибками в консоль.
Регенерация работает с первой карты, а не только после смены карты.
Модули нормально работают после перезагрузки (hot reload), исправлена куча вылетов из-за null.
Меньше нагрузка на сервер: модули, которые работают каждый тик (Bhop, прыжки, гравитация, скорость, выносливость), теперь обрабатывают только VIP-игроков, а не всех подряд.
Для разработчиков модулей
API переделано, полный пример есть в README. Коротко:
фича объявляется через VipFeature<T> — она сама регистрируется в ядре, а при выгрузке модуля достаточно вызвать Dispose();
OnPlayerSpawn(player, vip) теперь вызывается для всех игроков, VIP это или нет — смотрите параметр vip;
IsFeatureEnabled(player) — одна проверка вместо трёх: игрок VIP, у группы есть фича и она включена;
новые события: OnPlayerAuthorized, OnPlayerRemoved, OnPlayerDisconnect, OnFeatureDisplay (свой текст в меню);
методы переименованы: IsClientVip → IsPlayerVip, GiveClientVip → GivePlayerVip и так далее.
C#:
public class Armor(IVipCoreApi api) : VipFeature<int>("Armor", api)
{
public override void OnPlayerSpawn(CCSPlayerController player, bool vip)
{
if (!vip || !IsFeatureEnabled(player)) return;
var pawn = player.PlayerPawn.Value;
if (pawn == null) return;
pawn.ArmorValue = GetValue(player);
}
public override void OnFeatureDisplay(FeatureDisplayArgs args)
{
if (args.State == FeatureState.Enabled)
args.Display = $"[{GetValue(args.Controller)}]";
}
}