Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
17a5363
Add vip_modules.phrases.txt from 3.1-dev; the core already loads it b…
R1KO Oct 10, 2026
ac12265
Merge branch 'port/modules-phrases' into dev
R1KO Oct 10, 2026
c36ac54
Turn off VIP features when VIP status is removed by a plugin or an ad…
R1KO Oct 10, 2026
c9f9485
Merge branch 'port/turn-off-features' into dev
R1KO Oct 10, 2026
90bb5bc
Add VIP_OnConfigsLoaded forward, VIP_IsGroupExists native (VIP_IsVali…
R1KO Oct 10, 2026
5c3ac10
Merge branch 'port/api-configs-groups' into dev
R1KO Oct 10, 2026
68130b1
Add VIP_AddGroup and VIP_RemoveGroup natives for in-memory VIP groups…
R1KO Oct 10, 2026
a1132c3
Merge branch 'port/runtime-groups' into dev
R1KO Oct 10, 2026
c3742f9
Add per-player storage from 3.1-dev: vip_storage table, sm_vip_storag…
R1KO Oct 10, 2026
6a58769
Merge branch 'port/storage' into dev
R1KO Oct 10, 2026
00db3b5
Store feature toggle statuses in the VIP storage instead of clientpre…
R1KO Oct 10, 2026
6ae617d
Merge branch 'port/feature-status-storage' into dev
R1KO Oct 10, 2026
585cfb6
Document USE_CLIENTPREFS, the vip_storage table and the account_id 0 …
R1KO Oct 10, 2026
a87b269
Merge branch 'docs/agents-storage' into dev
R1KO Oct 10, 2026
3b2afb9
Fix server hang in UTIL_LoadVipCmd when sm_vip_menu_commands is empty…
R1KO Oct 10, 2026
5171d5f
Fix admin menu acting on a previously picked online player after pick…
R1KO Oct 10, 2026
48c0fae
Fix VIP rows being deleted on in-game expiry when sm_vip_delete_expir…
R1KO Oct 10, 2026
8ce899e
Fix every in-game player being loaded twice on start and late load, w…
R1KO Oct 10, 2026
672558e
Fix SQL injection in the admin menu player search: the search text is…
R1KO Oct 10, 2026
30fa721
Fix sm_delvip callback calling FetchRow on a null result after a data…
R1KO Oct 10, 2026
ff38fdc
Add braces to the loop in UTIL_SearchCharInString.
R1KO Oct 10, 2026
66b8057
Brace every single-statement if/for/while body, per the AGENTS.md cod…
R1KO Oct 10, 2026
0e866f8
Fix chat messages, VIP_LogMessage and debug logs breaking on text con…
R1KO Oct 10, 2026
7be38bf
Fix VIP removals not being logged and leaking a DataPack when the adm…
R1KO Oct 10, 2026
8d16bf5
Fix VIP_GiveClientVIP and VIP_RemoveClientVIP2 throwing errors for iA…
R1KO Oct 10, 2026
8f2ced1
Fix VIP_SetClientVIPGroup logging the new group as the old one: the o…
R1KO Oct 10, 2026
27c7f31
Fix the admin menu add flow: after adding a VIP the admin now returns…
R1KO Oct 10, 2026
ac9ec71
Fix the temporary VIP info menu showing the admin's SteamID instead o…
R1KO Oct 10, 2026
779dc49
Merge pull request #150 from R1KO/fix/critical-bugs
R1KO Oct 10, 2026
95b3225
Fix VIP_OnVIPClientLoaded and feature toggles firing twice when the s…
R1KO Oct 10, 2026
aea081c
Merge pull request #151 from R1KO/style/braces
R1KO Oct 10, 2026
ac4921b
Ignore .omc/ (oh-my-claudecode local state).
R1KO Oct 10, 2026
38a6e25
Add code style rules to AGENTS.md, derived from the prevailing style …
R1KO Oct 10, 2026
ebaab41
Merge pull request #152 from R1KO/fix/serious-bugs
R1KO Oct 10, 2026
79a95c0
Fix client reset wiping session flags (spawned, chat input) and VIP_O…
R1KO Oct 10, 2026
c23637c
Fix VIPs who were not yet authorized by Steam on connect never gettin…
R1KO Oct 10, 2026
67ac199
Fix VIP reloads and group changes taking VIP away without toggling fe…
R1KO Oct 10, 2026
bcf6621
Fix storage changes (feature statuses) being lost when the plugin is …
R1KO Oct 10, 2026
9aefd08
Fix VIP_RegisterFeature throwing for modules built against an older i…
R1KO Oct 10, 2026
4a8f53f
Fix sm_addvip accepting durations that overflow an int (e.g. 99999 da…
R1KO Oct 10, 2026
70e41d8
Fix VIP_GetClientFeatureBool returning true for a BOOL feature given …
R1KO Oct 10, 2026
bf8aec7
Fix the 3-second flood guard on the VIP menu command never triggering…
R1KO Oct 10, 2026
0f2de4d
Fix a KeyValues handle leaking each time a module blocks an info mess…
R1KO Oct 10, 2026
f5735e6
Fix https:// info URLs being turned into http://https://... in the MO…
R1KO Oct 10, 2026
f552bc7
Fix the cookie handle of a SELECTABLE feature registered with bCookie…
R1KO Oct 10, 2026
0e4573c
Fix UTIL_GetAccountIDFromSteamID turning malformed STEAM_ ids (STEAM_…
R1KO Oct 10, 2026
7f59152
Fix VIP_GetDatabase throwing when called before the core has connecte…
R1KO Oct 10, 2026
281c7b6
Re-check VIP access from OnClientAuthorized only for players that wer…
R1KO Oct 10, 2026
3dba0f4
Document that VIP_TimeToSeconds returns -1 for an unknown time mode o…
R1KO Oct 10, 2026
4c5b43f
Add comment rules to AGENTS.md, based on the Stack Overflow blog's be…
R1KO Oct 10, 2026
fbbf801
Remove or trim comments that only restated the code, per the new comm…
R1KO Oct 10, 2026
a64b95a
Merge pull request #153 from R1KO/fix/minor-bugs
R1KO Oct 10, 2026
12554db
Replace the hardcoded Russian "Show more" item in the admin VIP list …
R1KO Oct 10, 2026
613e80c
Translate all Russian comments, cvar descriptions, error/log messages…
R1KO Oct 10, 2026
4bdd257
Move the module update guide and issue labels guide to docs/, transla…
R1KO Oct 10, 2026
ce2a33f
Merge pull request #154 from R1KO/chore/english-only
R1KO Oct 10, 2026
dbf776a
Bump version to 3.1.0 R.
R1KO Oct 10, 2026
5674971
Merge branch 'release/3.1.0' into dev
R1KO Oct 10, 2026
da91a52
Remove updates.md: its 3.0 DEV history now lives in the 3.0 R release…
R1KO Oct 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.smx
.sourceknight
plugins/
.omc/
36 changes: 20 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,43 @@
- `-E` = warnings are errors. Fix every warning, including deprecation ones. SM 1.10 is the strictest parser (e.g. missing `;`), so code must build there too.
- Alt: `sourceknight build` (`sourceknight.yaml`, SM 1.13). It ignores spcomp's exit code — check output for `error`.
- Never commit `*.smx`, `plugins/`, `.sourceknight`.

## Git
- `dev` is the integration branch: branch from `dev`, merge back into `dev`. `master` is for releases.
- LF line endings only (enforced by `.gitattributes`); don't introduce CRLF.
- Git: `dev` is the integration branch: branch from `dev`, merge back into `dev`. `master` is for releases. LF line endings only (`.gitattributes`).

## Layout
- `scripting/VIP_Core.sp` — entry point; `#include`s every `vip/*.sp` into ONE compilation unit (order matters: Global → Debug → ... → API → CMD → Clients). New file = add `#include` there.
- Compile-time switches in `VIP_Core.sp`: `DEBUG_MODE`, `USE_ADMINMENU` (gates `AdminMenu.sp` + `vip/adminmenu/*`), `USE_MORE_SERVERS`.
- Compile-time switches in `VIP_Core.sp`: `DEBUG_MODE`, `USE_ADMINMENU` (gates `AdminMenu.sp` + `vip/adminmenu/*`), `USE_MORE_SERVERS`, `USE_CLIENTPREFS` (toggle statuses in cookies vs `vip_storage`; status I/O only via `Features_GetSavedStatus`/`Features_SaveStatus`).
- `vip/Global.sp` — all globals, macros (`SZF`, `UID/CID`, `SET_BIT/UNSET_BIT`), client flag bits (`IS_VIP`, `IS_LOADED`, ...), core state bits (`IS_STARTED`, `IS_MySQL`, `IS_LOADING`).
- `vip/API.sp` — forwards (`API_SetupForwards`, `CreateForward_*`) and natives (`AskPluginLoad2`, `RegNative(X)` → `VIP_X` bound to `Native_X`).
- `vip/Database.sp` — connection, schema, queries. `UTIL.sp` — shared helpers; check here before writing new ones.
- `vip/Clients.sp` — client load/unload lifecycle, spawn handling. `Features.sp` — feature registry.
- `include/vip_core.inc` — PUBLIC API for third-party modules.
- `data/vip/cfg/*.ini` — runtime configs (groups, info, sort_menu, times). `translations/vip_core.phrases.txt` — all user-facing strings.
- `vip/Database.sp` — connection, schema, queries. `UTIL.sp` — shared helpers; check here before writing new ones. `Clients.sp` — client load/unload lifecycle, spawn. `Features.sp` — feature registry.
- `include/vip_core.inc` — PUBLIC API for third-party modules. `data/vip/cfg/*.ini` — runtime configs (groups, info, sort_menu, times). `translations/vip_core.phrases.txt` — all user-facing strings.

## Public API rules (vip_core.inc)
- Third-party modules depend on it: never change existing native/forward signatures or semantics. Add new params with defaults or add new natives.
- Third-party modules depend on it: never change existing native/forward signatures or semantics. Add new params with defaults or add new natives. Deprecate via `#pragma deprecated`, don't delete (see `docs/update_modules.md`).
- New native: implement `Native_X` in API.sp, `RegNative(X)` in `AskPluginLoad2`, declare in `.inc`, add `MarkNativeAsOptional("VIP_X")` in `__pl_vip_core_SetNTVOptional`.
- New forward: `static GlobalForward` field + `new GlobalForward(...)` in `API_SetupForwards` + `CreateForward_*` wrapper + `forward` declaration with doc comment in `.inc`.
- Deprecate via `#pragma deprecated`, don't delete (see `update_modules.md`).

## Database
- Config name `vip_core` in databases.cfg → MySQL; otherwise falls back to local SQLite. Every query must work on BOTH.
- Schemas differ: MySQL has `sid` column (PK `account_id, sid`), SQLite has no `sid`. Use `g_szSID` (empty on SQLite) when filtering by server.
- MySQL uses `utf8mb4`. Escape user strings with `g_hDatabase.Escape`. All queries are async (`g_hDatabase.Query` + callback); check `szError` in callbacks.
- Players are keyed by `account_id` (SteamID AccountID), not userid/client index.
- Players are keyed by `account_id` (SteamID AccountID), not userid/client index. Never store data under `account_id` 0 (unauthorized client).
- `vip/Storage.sp` — per-player key/value cache over `vip_storage` (filtered by `sm_vip_storage_id` on MySQL), loaded on connect, written on disconnect.

## Code style (new/changed code; legacy deviations are not a reason to copy them)
- `#pragma semicolon 1`, `#pragma newdecls required`. Tabs, no trailing whitespace. Allman braces, always braced, also single-statement `if`/`for` and `case` bodies (`case MenuAction_End: delete hMenu;` is the only one-liner).
- Space after keywords: `if (`, `for (`, `while (`, `switch (`. `++i` in loops. `!bFlag`, not `bFlag == false`. Buffers: `SZF(szBuf)`, not `szBuf, sizeof(szBuf)`; `FormatEx` unless formatting a buffer into itself.
- Names: locals/params Hungarian `iClient`, `szName`, `hMenu`, `bFlag`, `fTime`, `eStatus`; globals `g_` + prefix (`g_hDatabase`, `g_szSID`), cvars `g_CVAR_*`; macros/consts `UPPER_SNAKE`, StringMap keys `KEY_*` / `DATA_KEY_*`.
- Functions: `PascalCase` with file prefix: `Clients_*`, `Features_*`, `Storage_*`, `DB_*`, `UTIL_*`, `API_*`. Callbacks: `SQL_Callback_*`, `SQL_TxnCallback_*`, `Timer_*`, `MenuHandler_*`, `Event_*`; commands `*_CMD`; natives `Native_*`; forward wrappers `CreateForward_*`.
- SQL: backticks around identifiers, single quotes for values, trailing `;`, user strings via `g_hDatabase.Format`/`Escape`. Callbacks: `if (hResult == null || szError[0]) { LogError("<Callback>: %s", szError); return; }`, free the DataPack on every path.
- File-private state/helpers are `static`. Never pass already formatted text as a format string: `PrintToServer("%s", szMsg)`, not `PrintToServer(szMsg)`.

## Comments
- Explain *why*, never restate *what* the code does. A comment doesn't excuse unclear code: rename/restructure first; if a clear comment is hard to write, the code is the problem.
- Comment what a reader would trip over: unidiomatic code, SourceMod quirks, ordering constraints, odd-looking bug fixes. Mark unfinished parts `// TODO: <what and why>`. Link the source of copied code and external refs (SM docs, AlliedModders) where they help.

## Conventions
- `#pragma semicolon 1`, `#pragma newdecls required`. Tabs. Hungarian-ish names: `iClient`, `szName`, `hMenu`, `bFlag`, globals `g_*`, cvars `g_CVAR_*`.
- Pass client across async boundaries as userid (`UID`/`CID`), never raw index.
- `GLOBAL_TRIE` / `GLOBAL_INFO` are index `[0]` of per-client arrays — slot 0 = global, not a player.
- Use methodmaps (`StringMap`, `Cookie`, `KeyValues`, `delete`), not legacy procedural calls (`CreateTrie`, `SetClientCookie`, `CloseHandle`, `Kv*`).
- Debug logging via `DBG_*` / `DebugMessage` functions from `Debug.sp` (empty unless `DEBUG_MODE 1`); calls still need a trailing `;`.
- Any new user-facing text → new phrase in `vip_core.phrases.txt` with at least `en` and `ru`.
- Comments and cvar descriptions are mostly Russian; either language is fine, keep the surrounding style.
- Bump `VIP_VERSION` in `VIP_Core.sp` only when asked; changelog lives in `updates.md`.
- English only in code, comments, cvar descriptions, log/error strings and docs. Other languages live only in `translations/*.phrases.txt` and the per-language values of `data/vip/cfg/*.ini`. Any new user-facing text → new phrase in `vip_core.phrases.txt` with at least `en` and `ru`. Bump `VIP_VERSION` in `VIP_Core.sp` only when asked; changelog lives in `updates.md`.
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ Download latest vesrion [https://github.com/R1KO/VIP-Core/releases](Releases)

## [VIP] Core

RU: Плагин позволяет выдавать игрокам VIP-статус на определенный срок или навсегда.
Учитывая модульную систему плагина вы всегда имеете возможность расширить функционал плагина.
Плагин очень гибкий и удобный в настройке, может работать как с SQLite так и с MySQL базой.


[RU: [VIP] Core Официальная тема на HlMod.ru](http://hlmod.ru/resources/vip-core.245/)

[RU: Документация](https://r1ko.github.io/VIP-Core/)


EN: This plugin allows you to give VIP status to players for a specific period or forever.
This plugin allows you to give VIP status to players for a specific period or forever.
Given the plugin’s modular system, the functionality can always be expanded.
The plugin is very flexible and easy to configure, it can work with both SQLite and MySQL database.

[EN: [VIP] Core official theme on HlMod.ru](http://hlmod.ru/resources/vip-core.245/)
[[VIP] Core official thread on HlMod.ru](http://hlmod.ru/resources/vip-core.245/)

[Documentation](https://r1ko.github.io/VIP-Core/)

[EN: Documentation](https://r1ko.github.io/VIP-Core/)
### Guides
- [Module update guide](docs/update_modules.md)
- [Issue labels](docs/issue_labels.md)
- [Changelog](updates.md)
4 changes: 2 additions & 2 deletions addons/sourcemod/data/vip/cfg/groups.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"VIP_GROUPS"
{
"vip1" // Имя группы | Group name
"vip1" // Group name
{
// Опции (основные VIP-модули) | Options (VIP Core Modules)
// Options (VIP Core Modules)
}

"vip2"
Expand Down
50 changes: 25 additions & 25 deletions addons/sourcemod/data/vip/cfg/info.ini
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
"VIP_INFO"
{
"connect_info_time" // Сообщение для VIP-игрока при входе на сервер (когда вип на время) | Message for the VIP player when entering the server (when the VIP is on time)
"connect_info_time" // Message for the VIP player when entering the server (timed VIP)
{
// {NAME} - Ник игрока | Player Nickname
// {GROUP} - Группа игрока | Player Group
// {TIMELEFT} - Через сколько истекает VIP-статус | How long does it take for VIP status to expire?
// {EXPIRES} - Когда истекает VIP-статус | When VIP status expires
// {NAME} - Player Nickname
// {GROUP} - Player Group
// {TIMELEFT} - Time left until VIP status expires
// {EXPIRES} - When VIP status expires

"chat" // Сообщение в чат | Chat Message
"chat" // Chat Message
{
"ru" "{DEFAULT}Здравствуйте, {GREEN}{NAME}{DEFAULT}! Вы являетесь {LIGHTGREEN}VIP-игроком{DEFAULT}. Ваш VIP статус истекает {GREEN}{EXPIRES}"
"en" "{DEFAULT}Hello, {GREEN}{NAME}{DEFAULT}! You have {LIGHTGREEN}VIP features {DEFAULT}for {GREEN}{EXPIRES}"
"pt" "{DEFAULT}Olá, {GREEN}{NAME}{DEFAULT}! Você tem {LIGHTGREEN}status VIP {DEFAULT}para {GREEN}{EXPIRES}"
"fr" "{DEFAULT}Bonjour, {GREEN}{NAME}{DEFAULT}! Vous avez un {LIGHTGREEN}statut VIP {DEFAULT}pendant {GREEN}{EXPIRES}"
}
"menu" // Сообщение в меню | Menu Message
"menu" // Menu Message
{
"time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself)
"time" "12" // After how many seconds the menu will be closed automatically (0 - until the player closes it)
"ru"
{
// Пукнты меню | Menu Items
// Menu Items
"item" "Вы имеете VIP-статус"
"item" "SPACER"
"item" "Ник: {NAME}"
Expand Down Expand Up @@ -56,24 +56,24 @@
}
}
}
"connect_info_perm" // Сообщение для VIP-игрока при входе на сервер (когда вип навсегда) | A message for the VIP player when entering the server (when the VIP is forever)
"connect_info_perm" // A message for the VIP player when entering the server (when the VIP is forever)
{
// {NAME} - Ник игрока | Player Nickname
// {GROUP} - Группа игрока | Player Group
// {NAME} - Player Nickname
// {GROUP} - Player Group

"chat" // Сообщение в чат | Chat Message
"chat" // Chat Message
{
"ru" "{DEFAULT}Здравствуйте, {GREEN}{NAME}{DEFAULT}! Вы являетесь {LIGHTGREEN}VIP-игроком{DEFAULT}."
"en" "{DEFAULT}Hello, {GREEN}{NAME}{DEFAULT}! You have {LIGHTGREEN}VIP features{DEFAULT}."
"pt" "{DEFAULT}Olá, {GREEN}{NAME}{DEFAULT}! Você tem {LIGHTGREEN}status VIP{DEFAULT}."
"fr" "{DEFAULT}Bonjour, {GREEN}{NAME}{DEFAULT}! Vous avez un {LIGHTGREEN}statut VIP{DEFAULT}."
}
"menu" // Сообщение в меню | Menu Message
"menu" // Menu Message
{
"time" "30" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself)
"time" "30" // After how many seconds the menu will be closed automatically (0 - until the player closes it)
"ru"
{
// Пукнты меню | Menu Items
// Menu Items
"item" "Вы имеете VIP-статус"
"item" "Группа: {GROUP}"
}
Expand All @@ -94,14 +94,14 @@
}
}
}
"no_access_info" // Сообщение об остутствии VIP-статуса
"no_access_info" // Message shown when the player has no VIP status
{
"menu" // Сообщение в меню | Menu Message
"menu" // Menu Message
{
"time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself)
"time" "12" // After how many seconds the menu will be closed automatically (0 - until the player closes it)
"ru"
{
// Пукнты меню | Menu Items
// Menu Items
"item" "У вас нет доступа к этому меню"
"item" "Чтобы приобрести VIP-статус"
"item" "Oбратитесь к администратору"
Expand All @@ -126,22 +126,22 @@
}
}

"url" // Ссылка, которую нужно открыть | Link to open
"url" // Link to open
{
"ru" "http://mysite.ru/vip/no_access.php?lang=ru"
"en" "http://mysite.ru/vip/no_access.php?lang=en"
"pt" "http://mysite.ru/vip/no_access.php?lang=pt"
"fr" "http://mysite.ru/vip/no_access.php?lang=fr"
}
}
"expired_info" // Сообщение об истечении VIP-статуса
"expired_info" // Message shown when the VIP status expires
{
"menu" // Сообщение в меню | Menu Message
"menu" // Menu Message
{
"time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself)
"time" "12" // After how many seconds the menu will be closed automatically (0 - until the player closes it)
"ru"
{
// Пукнты меню | Menu Items
// Menu Items
"item" "Срок вашего VIP-статуса истек"
"item" "Чтобы вновь приобрести VIP-статус"
"item" "Oбратитесь к администратору"
Expand Down
4 changes: 2 additions & 2 deletions addons/sourcemod/data/vip/cfg/times.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"TIMES"
{
"0" // Время в секундах | Time in seconds
"0" // Time in seconds
{
"ru" "Навсегда" // Отображение в меню | Display in the menu
"ru" "Навсегда" // Display in the menu
"en" "Permanent"
"pt" "Permanente"
"fr" "Permanent"
Expand Down
13 changes: 8 additions & 5 deletions addons/sourcemod/scripting/VIP_Core.sp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
#include <clientprefs>

#if !defined VIP_VERSION
#define VIP_VERSION "3.0.7 R"
#define VIP_VERSION "3.1.0 R"
#endif


#define DEBUG_MODE 0 // Режим отладки
#define DEBUG_MODE 0 // Debug mode

#define USE_ADMINMENU 1 // Включение админ-меню для управления VIP
#define USE_ADMINMENU 1 // Admin menu for managing VIPs

#define USE_MORE_SERVERS 1 // Включить/Отключить режим при котором если ID сервера у игрока 0 - то VIP будет работать на всех серверах
#define USE_MORE_SERVERS 1 // A VIP with server ID 0 is active on all servers

#define USE_CLIENTPREFS 0 // Store VIP feature statuses in cookies (1) or in the vip_storage table (0, old cookies are migrated automatically)


public Plugin myinfo =
Expand All @@ -31,6 +33,7 @@ public Plugin myinfo =
#include "vip/Downloads.sp"
#include "vip/Colors.sp"
#include "vip/UTIL.sp"
#include "vip/Storage.sp"
#include "vip/Features.sp"
#include "vip/Sounds.sp"
#include "vip/Info.sp"
Expand Down Expand Up @@ -74,6 +77,7 @@ public void OnPluginStart()
ITEM_DRAW = hDataPack.Position;
delete hDataPack;

API_SetupForwards();
ReadConfigs();

VIPMenu_Setup();
Expand All @@ -82,7 +86,6 @@ public void OnPluginStart()
#endif

Cvars_Setup();
API_SetupForwards();

HookEvent("player_spawn", Event_PlayerSpawn);
HookEvent("player_death", Event_PlayerDeath);
Expand Down
Loading
Loading