├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── README.md ├── addons └── sourcemod │ ├── data │ └── vip │ │ ├── cfg │ │ ├── groups.ini │ │ ├── info.ini │ │ ├── sort_menu.ini │ │ └── times.ini │ │ └── modules │ │ └── downloadlist.txt │ ├── scripting │ ├── VIP_Core.sp │ ├── include │ │ └── vip_core.inc │ └── vip │ │ ├── API.sp │ │ ├── AdminMenu.sp │ │ ├── CMD.sp │ │ ├── Clients.sp │ │ ├── Colors.sp │ │ ├── Configs.sp │ │ ├── Cvars.sp │ │ ├── Database.sp │ │ ├── Debug.sp │ │ ├── Downloads.sp │ │ ├── Features.sp │ │ ├── Global.sp │ │ ├── Info.sp │ │ ├── Sounds.sp │ │ ├── UTIL.sp │ │ ├── VipMenu.sp │ │ └── adminmenu │ │ ├── Add.sp │ │ ├── Del.sp │ │ ├── Edit.sp │ │ └── List.sp │ └── translations │ └── vip_core.phrases.txt ├── issue_info.md ├── sourceknight.yaml ├── update_modules.md └── updates.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sp gitlab-language=cpp 2 | *.inc gitlab-language=cpp -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - '*' 9 | pull_request: 10 | branches: 11 | - master 12 | workflow_dispatch: 13 | 14 | jobs: 15 | compile: 16 | runs-on: ubuntu-latest 17 | continue-on-error: ${{ matrix.sm-version == '1.12.x' }} 18 | strategy: 19 | matrix: 20 | sm-version: [ '1.11.x', '1.12.x' ] 21 | 22 | name: "Build SM ${{ matrix.sm-version }}" 23 | steps: 24 | - name: Prepare env 25 | shell: bash 26 | run: | 27 | echo "GITHUB_SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV 28 | SMVERSION_FULL=${{ matrix.sm-version }} 29 | echo "SMVERSION_SHORT=${SMVERSION_FULL:0:-2}" >> $GITHUB_ENV 30 | 31 | - uses: actions/checkout@v4 32 | 33 | - name: Setup SP 34 | uses: rumblefrog/setup-sp@master 35 | with: 36 | version: ${{ matrix.sm-version }} 37 | 38 | - name: Run compiler 39 | run: | 40 | cd addons/sourcemod 41 | mkdir plugins 42 | cd scripting 43 | spcomp VIP_Core.sp -E -o ../plugins/VIP_Core.smx -i./include 44 | 45 | - name: Upload artifact 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: VIP-Core-${{ env.SMVERSION_SHORT }}-${{ env.GITHUB_SHA_SHORT }} 49 | path: | 50 | addons 51 | LICENSE 52 | retention-days: 2 53 | 54 | release: 55 | name: Release 56 | if: github.ref_type == 'tag' 57 | needs: compile 58 | runs-on: ubuntu-latest 59 | steps: 60 | - name: Download artifacts 61 | uses: actions/download-artifact@v4 62 | 63 | - name: Find Assets 64 | shell: bash 65 | run: | 66 | echo "artifact_1_11=$(find * -maxdepth 0 -type d -name '*1.11*')" >> $GITHUB_ENV 67 | echo "artifact_1_12=$(find * -maxdepth 0 -type d -name '*1.12*')" >> $GITHUB_ENV 68 | 69 | - name: Archive Assets 70 | run: | 71 | zip -r ${{ env.artifact_1_11 }}.zip ${{ env.artifact_1_11 }} 72 | zip -r ${{ env.artifact_1_12 }}.zip ${{ env.artifact_1_12 }} 73 | 74 | - name: Create Release 75 | id: create_release 76 | uses: actions/create-release@v1.1.4 77 | env: 78 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | with: 80 | tag_name: ${{ github.ref_name }} 81 | release_name: ${{ github.ref_name }} 82 | draft: true 83 | prerelease: false 84 | 85 | - name: Upload Asset 1.11 86 | uses: actions/upload-release-asset@v1.0.2 87 | env: 88 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 89 | with: 90 | upload_url: ${{ steps.create_release.outputs.upload_url }} 91 | asset_path: ${{ env.artifact_1_11 }}.zip 92 | asset_name: ${{ env.artifact_1_11 }}.zip 93 | asset_content_type: application/zip 94 | 95 | - name: Upload Asset 1.12 96 | uses: actions/upload-release-asset@v1.0.2 97 | env: 98 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 99 | with: 100 | upload_url: ${{ steps.create_release.outputs.upload_url }} 101 | asset_path: ${{ env.artifact_1_12 }}.zip 102 | asset_name: ${{ env.artifact_1_12 }}.zip 103 | asset_content_type: application/zip 104 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | *.smx 3 | .sourceknight 4 | plugins/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build](https://github.com/R1KO/VIP-Core/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/R1KO/VIP-Core/actions/workflows/build.yml) 2 | 3 | Download latest vesrion [https://github.com/R1KO/VIP-Core/releases](Releases) 4 | 5 | [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine/) 6 | 7 | 8 | ## [VIP] Core 9 | 10 | RU: Плагин позволяет выдавать игрокам VIP-статус на определенный срок или навсегда. 11 | Учитывая модульную систему плагина вы всегда имеете возможность расширить функционал плагина. 12 | Плагин очень гибкий и удобный в настройке, может работать как с SQLite так и с MySQL базой. 13 | 14 | 15 | [RU: [VIP] Core Официальная тема на HlMod.ru](http://hlmod.ru/resources/vip-core.245/) 16 | 17 | [RU: Документация](https://r1ko.github.io/VIP-Core/) 18 | 19 | 20 | EN: This plugin allows you to give VIP status to players for a specific period or forever. 21 | Given the plugin’s modular system, the functionality can always be expanded. 22 | The plugin is very flexible and easy to configure, it can work with both SQLite and MySQL database. 23 | 24 | [EN: [VIP] Core official theme on HlMod.ru](http://hlmod.ru/resources/vip-core.245/) 25 | 26 | [EN: Documentation](https://r1ko.github.io/VIP-Core/) 27 | -------------------------------------------------------------------------------- /addons/sourcemod/data/vip/cfg/groups.ini: -------------------------------------------------------------------------------- 1 | "VIP_GROUPS" 2 | { 3 | "vip1" // Имя группы | Group name 4 | { 5 | // Опции (основные VIP-модули) | Options (VIP Core Modules) 6 | } 7 | 8 | "vip2" 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /addons/sourcemod/data/vip/cfg/info.ini: -------------------------------------------------------------------------------- 1 | "VIP_INFO" 2 | { 3 | "connect_info_time" // Сообщение для VIP-игрока при входе на сервер (когда вип на время) | Message for the VIP player when entering the server (when the VIP is on time) 4 | { 5 | // {NAME} - Ник игрока | Player Nickname 6 | // {GROUP} - Группа игрока | Player Group 7 | // {TIMELEFT} - Через сколько истекает VIP-статус | How long does it take for VIP status to expire? 8 | // {EXPIRES} - Когда истекает VIP-статус | When VIP status expires 9 | 10 | "chat" // Сообщение в чат | Chat Message 11 | { 12 | "ru" "{DEFAULT}Здравствуйте, {GREEN}{NAME}{DEFAULT}! Вы являетесь {LIGHTGREEN}VIP-игроком{DEFAULT}. Ваш VIP статус истекает {GREEN}{EXPIRES}" 13 | "en" "{DEFAULT}Hello, {GREEN}{NAME}{DEFAULT}! You have {LIGHTGREEN}VIP features {DEFAULT}for {GREEN}{EXPIRES}" 14 | "pt" "{DEFAULT}Olá, {GREEN}{NAME}{DEFAULT}! Você tem {LIGHTGREEN}status VIP {DEFAULT}para {GREEN}{EXPIRES}" 15 | "fr" "{DEFAULT}Bonjour, {GREEN}{NAME}{DEFAULT}! Vous avez un {LIGHTGREEN}statut VIP {DEFAULT}pendant {GREEN}{EXPIRES}" 16 | } 17 | "menu" // Сообщение в меню | Menu Message 18 | { 19 | "time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself) 20 | "ru" 21 | { 22 | // Пукнты меню | Menu Items 23 | "item" "Вы имеете VIP-статус" 24 | "item" "SPACER" 25 | "item" "Ник: {NAME}" 26 | "item" "Группа: {GROUP}" 27 | "item" "Истекает: {EXPIRES}" 28 | "item" "Истекает через: {TIMELEFT}" 29 | } 30 | "en" 31 | { 32 | "item" "You have a VIP-status" 33 | "item" "SPACER" 34 | "item" "Nick: {NAME}" 35 | "item" "Group: {GROUP}" 36 | "item" "Expires: {EXPIRES}" 37 | "item" "Expires in: {TIMELEFT}" 38 | } 39 | "pt" 40 | { 41 | "item" "Você tem um status VIP" 42 | "item" "SPACER" 43 | "item" "Nick: {NAME}" 44 | "item" "Grupo: {GROUP}" 45 | "item" "Expira: {EXPIRES}" 46 | "item" "Expira em: {TIMELEFT}" 47 | } 48 | "fr" 49 | { 50 | "item" "Vous avez un statut VIP" 51 | "item" "SPACER" 52 | "item" "Nom: {NAME}" 53 | "item" "Groupe: {GROUP}" 54 | "item" "Expiration: {EXPIRES}" 55 | "item" "Expire dans: {TIMELEFT}" 56 | } 57 | } 58 | } 59 | "connect_info_perm" // Сообщение для VIP-игрока при входе на сервер (когда вип навсегда) | A message for the VIP player when entering the server (when the VIP is forever) 60 | { 61 | // {NAME} - Ник игрока | Player Nickname 62 | // {GROUP} - Группа игрока | Player Group 63 | 64 | "chat" // Сообщение в чат | Chat Message 65 | { 66 | "ru" "{DEFAULT}Здравствуйте, {GREEN}{NAME}{DEFAULT}! Вы являетесь {LIGHTGREEN}VIP-игроком{DEFAULT}." 67 | "en" "{DEFAULT}Hello, {GREEN}{NAME}{DEFAULT}! You have {LIGHTGREEN}VIP features{DEFAULT}." 68 | "pt" "{DEFAULT}Olá, {GREEN}{NAME}{DEFAULT}! Você tem {LIGHTGREEN}status VIP{DEFAULT}." 69 | "fr" "{DEFAULT}Bonjour, {GREEN}{NAME}{DEFAULT}! Vous avez un {LIGHTGREEN}statut VIP{DEFAULT}." 70 | } 71 | "menu" // Сообщение в меню | Menu Message 72 | { 73 | "time" "30" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself) 74 | "ru" 75 | { 76 | // Пукнты меню | Menu Items 77 | "item" "Вы имеете VIP-статус" 78 | "item" "Группа: {GROUP}" 79 | } 80 | "en" 81 | { 82 | "item" "You have a VIP-status" 83 | "item" "Group: {GROUP}" 84 | } 85 | "pt" 86 | { 87 | "item" "Você tem um status VIP" 88 | "item" "Grupo: {GROUP}" 89 | } 90 | "fr" 91 | { 92 | "item" "Vous avez un statut VIP" 93 | "item" "Groupe: {GROUP}" 94 | } 95 | } 96 | } 97 | "no_access_info" // Сообщение об остутствии VIP-статуса 98 | { 99 | "menu" // Сообщение в меню | Menu Message 100 | { 101 | "time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself) 102 | "ru" 103 | { 104 | // Пукнты меню | Menu Items 105 | "item" "У вас нет доступа к этому меню" 106 | "item" "Чтобы приобрести VIP-статус" 107 | "item" "Oбратитесь к администратору" 108 | } 109 | "en" 110 | { 111 | "item" "You do not have access to this menu" 112 | "item" "To purchase VIP-status" 113 | "item" "Contact the administrator" 114 | } 115 | "pt" 116 | { 117 | "item" "Você não tem acesso a este menu" 118 | "item" "Para adquirir status VIP" 119 | "item" "Contate o administrador" 120 | } 121 | "fr" 122 | { 123 | "item" "Vous n'avez pas accès à ce menu VIP" 124 | "item" "Pour acheter le statut VIP" 125 | "item" "Contactez un administrateur" 126 | } 127 | } 128 | 129 | "url" // Ссылка, которую нужно открыть | Link to open 130 | { 131 | "ru" "http://mysite.ru/vip/no_access.php?lang=ru" 132 | "en" "http://mysite.ru/vip/no_access.php?lang=en" 133 | "pt" "http://mysite.ru/vip/no_access.php?lang=pt" 134 | "fr" "http://mysite.ru/vip/no_access.php?lang=fr" 135 | } 136 | } 137 | "expired_info" // Сообщение об истечении VIP-статуса 138 | { 139 | "menu" // Сообщение в меню | Menu Message 140 | { 141 | "time" "12" // Через сколько секунд меню будет закрыто автоматически (0 - пока игрок сам не закроет) | After how many seconds the menu will be closed automatically (0 - until the player closes himself) 142 | "ru" 143 | { 144 | // Пукнты меню | Menu Items 145 | "item" "Срок вашего VIP-статуса истек" 146 | "item" "Чтобы вновь приобрести VIP-статус" 147 | "item" "Oбратитесь к администратору" 148 | } 149 | "en" 150 | { 151 | "item" "Your VIP-status has expired" 152 | "item" "To re-purchase VIP-status" 153 | "item" "Contact the administrator" 154 | } 155 | "pt" 156 | { 157 | "item" "Seu status VIP expirou" 158 | "item" "Para comprar novamente o status VIP" 159 | "item" "Contate o administrador" 160 | } 161 | "fr" 162 | { 163 | "item" "Votre statut VIP a expiré" 164 | "item" "Pour acheter de nouveau un statut VIP" 165 | "item" "Contactez un administrateur" 166 | } 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /addons/sourcemod/data/vip/cfg/sort_menu.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R1KO/VIP-Core/2cb4db6bbaa31bdd2d831c2122de49bff4a255ef/addons/sourcemod/data/vip/cfg/sort_menu.ini -------------------------------------------------------------------------------- /addons/sourcemod/data/vip/cfg/times.ini: -------------------------------------------------------------------------------- 1 | "TIMES" 2 | { 3 | "0" // Время в секундах | Time in seconds 4 | { 5 | "ru" "Навсегда" // Отображение в меню | Display in the menu 6 | "en" "Permanent" 7 | "pt" "Permanente" 8 | "fr" "Permanent" 9 | } 10 | 11 | "3600" 12 | { 13 | "ru" "1 Час" 14 | "en" "1 Hour" 15 | "pt" "1 Hora" 16 | "fr" "1 Heure" 17 | } 18 | 19 | "86400" 20 | { 21 | "ru" "1 Сутки" 22 | "en" "1 Day" 23 | "pt" "1 Dia" 24 | "fr" "1 Jour" 25 | } 26 | 27 | "604800" 28 | { 29 | "ru" "1 Неделя" 30 | "en" "1 Week" 31 | "pt" "1 Semana" 32 | "fr" "1 Semaine" 33 | } 34 | 35 | "2592000" 36 | { 37 | "ru" "1 Месяц" 38 | "en" "1 Month" 39 | "pt" "1 Mês" 40 | "fr" "1 Mois" 41 | } 42 | 43 | "15552000" 44 | { 45 | "ru" "6 Месяцев" 46 | "en" "6 Months" 47 | "pt" "6 Mês" 48 | "fr" "6 Mois" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /addons/sourcemod/data/vip/modules/downloadlist.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R1KO/VIP-Core/2cb4db6bbaa31bdd2d831c2122de49bff4a255ef/addons/sourcemod/data/vip/modules/downloadlist.txt -------------------------------------------------------------------------------- /addons/sourcemod/scripting/VIP_Core.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #pragma newdecls required 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #if !defined VIP_VERSION 10 | #define VIP_VERSION "3.0.6 R" 11 | #endif 12 | 13 | 14 | #define DEBUG_MODE 0 // Режим отладки 15 | 16 | #define USE_ADMINMENU 1 // Включение админ-меню для управления VIP 17 | 18 | #define USE_MORE_SERVERS 1 // Включить/Отключить режим при котором если ID сервера у игрока 0 - то VIP будет работать на всех серверах 19 | 20 | 21 | public Plugin myinfo = 22 | { 23 | name = "[VIP] Core", 24 | author = "R1KO", 25 | version = VIP_VERSION, 26 | url = "https://github.com/R1KO/VIP-Core" 27 | }; 28 | 29 | #include "vip/Global.sp" 30 | #include "vip/Debug.sp" 31 | #include "vip/Downloads.sp" 32 | #include "vip/Colors.sp" 33 | #include "vip/UTIL.sp" 34 | #include "vip/Features.sp" 35 | #include "vip/Sounds.sp" 36 | #include "vip/Info.sp" 37 | #include "vip/Database.sp" 38 | #include "vip/Configs.sp" 39 | #include "vip/Cvars.sp" 40 | #if USE_ADMINMENU 41 | #include "vip/AdminMenu.sp" 42 | #include "vip/adminmenu/Add.sp" 43 | #include "vip/adminmenu/List.sp" 44 | #include "vip/adminmenu/Edit.sp" 45 | #include "vip/adminmenu/Del.sp" 46 | #endif 47 | #include "vip/VipMenu.sp" 48 | #include "vip/API.sp" 49 | #include "vip/CMD.sp" 50 | #include "vip/Clients.sp" 51 | 52 | public void OnPluginStart() 53 | { 54 | #if DEBUG_MODE 55 | BuildPath(Path_SM, SZF(g_szDebugLogFile), "logs/VIP_Debug.log"); 56 | #endif 57 | 58 | BuildPath(Path_SM, SZF(g_szLogFile), "logs/VIP_Logs.log"); 59 | 60 | LoadTranslations("vip_core.phrases"); 61 | LoadTranslations("vip_modules.phrases"); 62 | LoadTranslations("common.phrases"); 63 | LoadTranslations("core.phrases"); 64 | 65 | g_iMaxPageItems = GetMaxPageItems(GetMenuStyleHandle(MenuStyle_Default)); 66 | g_hFeaturesArray = new ArrayList(ByteCountToCells(FEATURE_NAME_LENGTH)); 67 | GLOBAL_TRIE = new StringMap(); 68 | 69 | // Fix DataPack positions in sm 1.10 70 | DataPack hDataPack = new DataPack(); 71 | hDataPack.WriteCell(0); 72 | ITEM_DISPLAY = hDataPack.Position; 73 | hDataPack.WriteCell(0); 74 | ITEM_DRAW = hDataPack.Position; 75 | delete hDataPack; 76 | 77 | ReadConfigs(); 78 | 79 | VIPMenu_Setup(); 80 | #if USE_ADMINMENU 81 | AdminMenu_Setup(); 82 | #endif 83 | 84 | Cvars_Setup(); 85 | API_SetupForwards(); 86 | 87 | HookEvent("player_spawn", Event_PlayerSpawn); 88 | HookEvent("player_death", Event_PlayerDeath); 89 | HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy); 90 | HookEventEx("cs_match_end_restart", Event_MatchEndRestart, EventHookMode_PostNoCopy); 91 | 92 | CMD_Setup(); 93 | 94 | g_EngineVersion = GetEngineVersion(); 95 | } 96 | 97 | public void OnAllPluginsLoaded() 98 | { 99 | DB_OnPluginStart(); 100 | } 101 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/vip_core.inc: -------------------------------------------------------------------------------- 1 | #if defined _vip_core_included 2 | #endinput 3 | #endif 4 | #define _vip_core_included 5 | 6 | /* Типы данных VIP-функций */ 7 | enum VIP_ValueType 8 | { 9 | VIP_NULL = 0, // Нет данных 10 | INT, // Целочисленный тип 11 | FLOAT, // Числа с плавающей точкой (Дробные) 12 | BOOL, // Логический тип (1/0) 13 | STRING // Строчный тип 14 | } 15 | 16 | /* Статусы VIP-функций */ 17 | enum VIP_ToggleState 18 | { 19 | DISABLED = 0, // Выключено 20 | ENABLED, // Включено 21 | NO_ACCESS // Нет доступа 22 | } 23 | 24 | /* Типы VIP-функций */ 25 | enum VIP_FeatureType 26 | { 27 | TOGGLABLE = 0, // Вкл/Выкл в меню 28 | SELECTABLE, // Только нажатие 29 | HIDE // Скрытый 30 | } 31 | 32 | typeset ItemSelectCallback 33 | { 34 | /** 35 | * Вызывается когда VIP-игрок нажимает на пункт в меню (для типа TOGGLABLE). 36 | * 37 | * @param iClient Индекс игрока. 38 | * @param szFeature Уникальное имя ф-и. 39 | * @param eOldStatus Старое значение статуса. 40 | * @param eNewStatus Новое значение статуса. 41 | * 42 | * @return Plugin_Stop или Plugin_Handled - остановит переключение статуса; 43 | * Plugin_Continue - разрешит переключение статуса без изменений; 44 | * Plugin_Changed - разрешит переключение статуса на eNewStatus. 45 | */ 46 | function Action (int iClient, const char[] szFeature, VIP_ToggleState eOldStatus, VIP_ToggleState &eNewStatus); 47 | 48 | /** 49 | * Вызывается когда VIP-игрок нажимает на пункт в меню (для типа SELECTABLE). 50 | * 51 | * @param iClient Индекс игрока. 52 | * @param szFeature Уникальное имя ф-и. 53 | * 54 | * @return true - снова откроет игроку VIP-меню; 55 | * false. 56 | */ 57 | function bool (int iClient, const char[] szFeature); 58 | }; 59 | 60 | /** 61 | * Вызывается когда VIP-игроку отображается пункт в меню. 62 | * 63 | * @param iClient Индекс игрока. 64 | * @param szFeature Уникальное имя ф-и. 65 | * @param szDisplay Буфер. 66 | * @param iMaxLength Размер буфера. 67 | * 68 | * @return true - Отображение содержимого szDisplay. 69 | * false - Отображение без изменений. 70 | */ 71 | typedef ItemDisplayCallback = function bool (int iClient, const char[] szFeature, char[] szDisplay, int iMaxLength); 72 | 73 | /** 74 | * Вызывается когда VIP-игроку отображается стиль пункта в меню. 75 | * 76 | * @param iClient Индекс игрока. 77 | * @param szFeature Уникальное имя ф-и. 78 | * @param iStyle Стиль. 79 | * 80 | * @return Необходимый стиль (ITEMDRAW_*). 81 | */ 82 | typedef ItemDrawCallback = function int (int iClient, const char[] szFeature, int iStyle); 83 | 84 | /** 85 | * Вызывается когда игрок возрождается. 86 | * 87 | * @param iClient Индекс игрока. 88 | * @param iTeam Команда игрока (2 - Т, 3- КТ). 89 | * @param bIsVIP Имеет ли игрок VIP-статус. 90 | * 91 | * @noreturn 92 | */ 93 | forward void VIP_OnPlayerSpawn(int iClient, int iTeam, bool bIsVIP); 94 | 95 | /** 96 | * Вызывается когда игру отображается информация. 97 | * 98 | * @param iClient Индекс игрока. 99 | * @param szEvent Имя события: 100 | * "connect_info_time" - VIP-игрок вошел на сервер (VIP-статус на время); 101 | * "connect_info_perm" - VIP-игрок вошел на сервер (VIP-статус навсегда); 102 | * "no_access_info" - Игрок попытался открыть VIP-меню; 103 | * "connect_info_time" - VIP-статус игрока истек. 104 | * @param szType Тип сообщения: 105 | * "chat" - В чат; 106 | * "menu" - В меню; 107 | * "url" - В MOTD окно. 108 | * @param hKeyValues KeyValues ключа события. 109 | * 110 | * @return Plugin_Stop или Plugin_Handled - запретит показ уведомления; 111 | * Plugin_Changed - разрешит с изменениями; 112 | * Plugin_Continue - разрешит без изменений. 113 | */ 114 | forward Action VIP_OnShowClientInfo(int iClient, const char[] szEvent, const char[] szType, KeyValues hKeyValues); 115 | 116 | /** 117 | * Вызывается когда у VIP-игрока изменяется статус функции. 118 | * 119 | * @param iClient Индекс игрока. 120 | * @param szFeature Уникальное имя ф-и. 121 | * @param eOldStatus Старое значение статуса. 122 | * @param eNewStatus Новое значение статуса. 123 | * 124 | * @return Plugin_Stop или Plugin_Handled - остановит переключение статуса; 125 | * Plugin_Continue - разрешит переключение статуса без изменений; 126 | * Plugin_Changed - разрешит переключение статуса на eNewStatus. 127 | */ 128 | forward Action VIP_OnFeatureToggle(int iClient, const char[] szFeature, VIP_ToggleState eOldStatus, VIP_ToggleState &eNewStatus); 129 | 130 | /** 131 | * Вызывается когда VIP-плагин загрузился. 132 | * 133 | * @noparams 134 | * 135 | * @noreturn 136 | */ 137 | forward void VIP_OnVIPLoaded(); 138 | 139 | /** 140 | * Вызывается когда VIP-функция была зарегистрирована. 141 | * 142 | * @param szFeature Уникальное имя ф-и. 143 | * 144 | * @noreturn 145 | */ 146 | forward void VIP_OnFeatureRegistered(const char[] szFeature); 147 | 148 | /** 149 | * Вызывается когда VIP-функция была удалена. 150 | * 151 | * @param szFeature Уникальное имя ф-и. 152 | * 153 | * @noreturn 154 | */ 155 | forward void VIP_OnFeatureUnregistered(const char[] szFeature); 156 | 157 | /** 158 | * Вызывается перед проверкой игрока на наличие VIP-статуса. 159 | * 160 | * @param iClient Индекс игрока. 161 | * 162 | 163 | * @return true - продолжить. 164 | * false - не выполнять проверку. 165 | */ 166 | forward bool VIP_OnClientPreLoad(int iClient); 167 | 168 | /** 169 | * Вызывается когда игрок был загружен. 170 | * 171 | * @param iClient Индекс игрока. 172 | * @param bIsVIP Имеет ли игрок VIP-статус. 173 | * 174 | * @noreturn 175 | */ 176 | forward void VIP_OnClientLoaded(int iClient, bool bIsVIP); 177 | 178 | /** 179 | * Вызывается когда VIP-игрок был загружен. 180 | * 181 | * @param iClient Индекс игрока. 182 | * 183 | * @noreturn 184 | */ 185 | forward void VIP_OnVIPClientLoaded(int iClient); 186 | 187 | /** 188 | * Вызывается когда игрок на стадии отключения. 189 | * 190 | * @param iClient Индекс игрока. 191 | * @param bIsVIP Имеет ли игрок VIP-статус. 192 | * 193 | * @noreturn 194 | */ 195 | forward void VIP_OnClientDisconnect(int iClient, bool bIsVIP); 196 | 197 | /** 198 | * Вызывается когда игрок получает VIP-статус. 199 | * 200 | * @param iClient Индекс игрока. 201 | * @param iAdmin Индекс админа (0 - сервер). 202 | * 203 | * @noreturn 204 | */ 205 | forward void VIP_OnVIPClientAdded(int iClient, int iAdmin); 206 | 207 | /** 208 | * Вызывается когда игрок лишается VIP-статуса. 209 | * 210 | * @param iClient Индекс игрока. 211 | * @param szReason Причина: 212 | * "Expired" - Истек; 213 | * "Removed by Admin" - Удален админом; 214 | * "Removed by native" - Удален нативом. 215 | * @param iAdmin Индекс админа (0 - сервер). 216 | * 217 | * @noreturn 218 | */ 219 | forward void VIP_OnVIPClientRemoved(int iClient, const char[] szReason, int iAdmin); 220 | 221 | /** 222 | * Запускает проверку игрока на наличие VIP прав. 223 | * 224 | * @param iClient Индекс игрока. 225 | * @param bNotify Известить ли игрока о результате проверки. 226 | * @param bForward Вызывать ли форврад VIP_OnClientPreLoad перед проверкой. 227 | * 228 | * @noreturn 229 | */ 230 | native void VIP_CheckClient(int iClient, bool bNotify = false, bool bForward = true); 231 | 232 | /** 233 | * Получает наличие VIP прав у игрока. 234 | * 235 | * @param iClient Индекс игрока. 236 | * 237 | * @return true - У игрока имеются VIP-статус. 238 | * false - У игрока нет VIP-статуса. 239 | */ 240 | native bool VIP_IsClientVIP(int iClient); 241 | 242 | /** 243 | * Получает уникальный ID VIP-игрока. 244 | * 245 | * @param iClient Индекс игрока. 246 | * 247 | * @return Уникальный ID или -1 если временный. 248 | */ 249 | native int VIP_GetClientID(int iClient); 250 | 251 | /** 252 | * Получает время окончания VIP-прав у игрока (unix). 253 | * 254 | * @param iClient Индекс игрока. 255 | * 256 | * @return Дата в unix формате (0 - навсегда, -1 если не удалось получить). 257 | */ 258 | native int VIP_GetClientAccessTime(int iClient); 259 | 260 | /** 261 | * Устанавливает время окончания VIP-прав у игрока (unix). 262 | * 263 | * @param iClient Индекс игрока. 264 | * @param iTime Дата в unix формате, 0 если права навсегда, -1 если временный. 265 | * @param bInDB Изменять ли в базе данных. 266 | * 267 | * @return true - Успешно. 268 | * false - Не удалось выполнить. 269 | */ 270 | native bool VIP_SetClientAccessTime(int iClient, int iTime, bool bInDB = true); 271 | 272 | /** 273 | * Получает VIP-группу игрока. 274 | * 275 | * @param iClient Индекс игрока. 276 | * @param szGroup Буфер, в который будет помещен результат. 277 | * @param iMaxLength Размер буфера. 278 | * 279 | * @return true - Успешно. 280 | * false - Не удалось выполнить. 281 | */ 282 | native bool VIP_GetClientVIPGroup(int iClient, char[] szGroup, int iMaxLength); 283 | 284 | /** 285 | * Устанавливает игроку VIP-группу. 286 | * 287 | * @param iClient Индекс игрока. 288 | * @param szGroup VIP-группа. 289 | * @param bInDBB Изменять ли в базе данных. 290 | * 291 | * @return true - Успешно. 292 | * false - Не удалось выполнить. 293 | */ 294 | native bool VIP_SetClientVIPGroup(int iClient, const char[] szGroup, bool bInDB = true); 295 | 296 | /** 297 | * Получает Handle adt trie настроек VIP-игрока. 298 | * 299 | * @param iClient Индекс игрока. 300 | * 301 | * @return StringMap (Handle) adt trie настроек VIP-игрока. 302 | */ 303 | native StringMap VIP_GetVIPClientTrie(int iClient); 304 | 305 | /** 306 | * Проверяет наличие VIP-группы. 307 | * 308 | * @param szGroup Имя VIP-группы. 309 | * 310 | * @return true - VIP-группа существует. 311 | * false - VIP-группа не существует. 312 | */ 313 | native bool VIP_IsValidVIPGroup(const char[] szGroup); 314 | 315 | /** 316 | * Выводит игроку сообщение в чат с приставкой (фраза в переводе "VIP_CHAT_PREFIX"). 317 | * 318 | * @param iClient Индекс игрока. 319 | * @param szMessage Правила форматирования сообщение. 320 | * @param ... Параметры форматирования. 321 | * 322 | * @noreturn 323 | */ 324 | native void VIP_PrintToChatClient(int iClient, const char[] szMessage, any ...); 325 | 326 | /** 327 | * Выводит всем игрокам сообщение в чат с приставкой (фраза в переводе "VIP_CHAT_PREFIX"). 328 | * 329 | * @param szMessage Правила форматирования сообщение. 330 | * @param ... Параметры форматирования. 331 | * 332 | * @noreturn 333 | */ 334 | native void VIP_PrintToChatAll(const char[] szMessage, any ...); 335 | 336 | /** 337 | * Записывает сообщение в лог. 338 | * 339 | * @param szMessage Правила форматирования сообщение. 340 | * @param ... Параметры форматирования. 341 | * 342 | * @noreturn 343 | */ 344 | native void VIP_LogMessage(const char[] szMessage, any ...); 345 | 346 | /** 347 | * Отправляет игроку VIP-меню. 348 | * 349 | * @param iClient Индекс игрока. 350 | * @param bSelection Режим открытия: 351 | * true - на первой странице; 352 | * false - на странице последнего выбранного пункта. 353 | * 354 | * @noreturn 355 | */ 356 | native void VIP_SendClientVIPMenu(int iClient, bool bSelection = false); 357 | 358 | /** 359 | * Выдает игроку VIP-права. 360 | * 361 | * @param iAdmin Индекс админа (0 - сервер, -1 - плагин). 362 | * @param iClient Индекс игрока. 363 | * @param iTime Время в секундах. 364 | * @param szGroup Имя VIP-группы. 365 | * @param bAddToDB Добавлять ли в базу данных. 366 | * 367 | * @noreturn 368 | */ 369 | native void VIP_GiveClientVIP(int iAdmin = 0, int iClient, int iTime, const char[] szGroup, bool bAddToDB = true); 370 | 371 | #pragma deprecated Use VIP_GiveClientVIP() instead 372 | native bool VIP_SetClientVIP(int iClient, int iTime, any AuthType, const char[] szGroup, bool bAddToDB = true); 373 | 374 | /** 375 | * Отнимает у игрока VIP-права. 376 | * 377 | * @param iAdmin Индекс админа (0 - сервер, -1 - плагин). 378 | * @param iClient Индекс игрока. 379 | * @param bInDB Удалять ли из базы данных. 380 | * @param bNotify Уведомление игрока (true - уведомить/false - не уведомлять). 381 | * 382 | * @return true - Успешно. 383 | * false - Не удалось выполнить. 384 | */ 385 | native bool VIP_RemoveClientVIP2(int iAdmin = 0, int iClient, bool bInDB, bool bNotify); 386 | 387 | #pragma deprecated Use VIP_RemoveClientVIP2() instead 388 | native bool VIP_RemoveClientVIP(int iClient, bool bInDB, bool bNotify); 389 | 390 | /** 391 | * Проверка что ядро загружено и готово к регистрации функций. 392 | * 393 | * @noparams 394 | * 395 | * @return true - Ядро загружено. 396 | * false - Ядро не загружено. 397 | */ 398 | native bool VIP_IsVIPLoaded(); 399 | 400 | /** 401 | * Добавляет новую VIP-функцию. 402 | * 403 | * @param szFeature Уникальное имя ф-и. 404 | * @param ValType Тип данных ф-и. 405 | * @param FeatureType Тип ф-и. 406 | * @param Item_select_callback Обратный вызов при смене статуса ф-и. 407 | * @param Item_display_callback Обратный вызов при отображении пункта ф-и . 408 | * @param Item_draw_callback Обратный вызов при отображении стиля пункта ф-и. 409 | * @param eDefStatus Значение по-умолчанию: 410 | * ENABLED - Включена 411 | * DISABLED - Отключена 412 | * NO_ACCESS - Не использовать (будет зависеть от sm_vip_features_default_status) 413 | * @param bCookie Регистрировать ли куки для ф-и (действительно только для типа SELECTABLE). 414 | * 415 | * @noreturn 416 | */ 417 | 418 | native void VIP_RegisterFeature(const char[] szFeature, 419 | VIP_ValueType eValType = VIP_NULL, 420 | VIP_FeatureType eType = TOGGLABLE, 421 | ItemSelectCallback Item_select_callback = INVALID_FUNCTION, 422 | ItemDisplayCallback Item_display_callback = INVALID_FUNCTION, 423 | ItemDrawCallback Item_draw_callback = INVALID_FUNCTION, 424 | VIP_ToggleState eDefStatus = NO_ACCESS, 425 | bool bCookie = false); 426 | 427 | /** 428 | * Удаляет VIP-функцию. 429 | * 430 | * @param szFeature Уникальное имя ф-и. 431 | * 432 | * @noreturn 433 | */ 434 | native void VIP_UnregisterFeature(const char[] szFeature); 435 | 436 | /** 437 | * Удаляет все VIP-функции зарегистрированные плагином (вызывать в OnPluginEnd()). 438 | * 439 | * @noparams 440 | * 441 | * @noreturn 442 | */ 443 | native void VIP_UnregisterMe(); 444 | 445 | /** 446 | * Проверяет существование функции. 447 | * 448 | * @param szFeature Уникальное имя ф-и. 449 | * 450 | * @return true - VIP-функция существует. 451 | * false - VIP-функция не существует. 452 | */ 453 | native bool VIP_IsValidFeature(const char[] szFeature); 454 | 455 | /** 456 | * Получает тип функции. 457 | * 458 | * @param szFeature Уникальное имя ф-и. 459 | * 460 | * @return Возвращает элемент списка VIP_FeatureType. 461 | */ 462 | native VIP_FeatureType VIP_GetFeatureType(const char[] szFeature); 463 | 464 | /** 465 | * Получает тип значения функции. 466 | * 467 | * @param szFeature Уникальное имя ф-и. 468 | * 469 | * @return Возвращает элемент списка VIP_ValueType. 470 | */ 471 | native VIP_ValueType VIP_GetFeatureValueType(const char[] szFeature); 472 | 473 | /** 474 | * Заполняет adt массив ф-ями. 475 | * 476 | * @param hArray Массив типа ArrayList. 477 | * 478 | * @return Количество добавленных элементов. 479 | */ 480 | native int VIP_FillArrayByFeatures(ArrayList hArray); 481 | 482 | /** 483 | * Возвращает статус VIP-функции у игрока. 484 | * 485 | * @param iClient Индекс игрока. 486 | * @param szFeature Уникальное имя ф-и. 487 | * 488 | * @return Возвращает элемент списка VIP_ToggleState. 489 | */ 490 | native VIP_ToggleState VIP_GetClientFeatureStatus(int iClient, const char[] szFeature); 491 | 492 | /** 493 | * Устанавливает статус VIP-функции игроку. 494 | * 495 | * @param iClient Индекс игрока. 496 | * @param szFeature Уникальное имя ф-и. 497 | * @param eStatus Статус VIP-функции. 498 | * @param bCallback Вызывать ли toggle каллбэк. 499 | * @param bSave Сохранить ли в куки. 500 | * 501 | * @return true - Успешно. 502 | * false - Не удалось выполнить. 503 | */ 504 | native bool VIP_SetClientFeatureStatus(int iClient, const char[] szFeature, VIP_ToggleState eStatus, bool bCallback = true, bool bSave = false); 505 | 506 | /** 507 | * Возвращает статус VIP-функции у игрока. 508 | * 509 | * @param iClient Индекс игрока. 510 | * @param szFeature Уникальное имя ф-и. 511 | * 512 | * @return true - VIP-функции включена. 513 | * false - VIP-функции выключена или нет доступа. 514 | */ 515 | native bool VIP_IsClientFeatureUse(int iClient, const char[] szFeature); 516 | 517 | /** 518 | * Получает целочисленное значение параметра VIP-функции у игрока. 519 | * 520 | * @param iClient Индекс игрока. 521 | * @param szFeature Уникальное имя ф-и. 522 | * 523 | * @return Возвращает целочисленное значение параметра VIP-функции у игрока. 524 | */ 525 | native int VIP_GetClientFeatureInt(int iClient, const char[] szFeature); 526 | 527 | /** 528 | * Получает дробное значение параметра VIP-функции у игрока. 529 | * 530 | * @param iClient Индекс игрока. 531 | * @param szFeature Уникальное имя ф-и. 532 | * 533 | * @return Возвращает дробное значение параметра VIP-функции у игрока. 534 | */ 535 | native float VIP_GetClientFeatureFloat(int iClient, const char[] szFeature); 536 | 537 | /** 538 | * Получает логическое значение параметра VIP-функции у игрока. 539 | * 540 | * @param iClient Индекс игрока. 541 | * @param szFeature Уникальное имя ф-и. 542 | * 543 | * @return Возвращает логическое значение параметра VIP-функции у игрока (true/false). 544 | */ 545 | native bool VIP_GetClientFeatureBool(int iClient, const char[] szFeature); 546 | 547 | /** 548 | * Получает строчное значение параметра VIP-функции у игрока. 549 | * 550 | * @param iClient Индекс игрока. 551 | * @param szFeature Уникальное имя ф-и. 552 | * @param szBuffer Буфер, в который будет помещен результат. 553 | * @param iMaxLength Размер буфера. 554 | * 555 | * @noreturn 556 | */ 557 | native void VIP_GetClientFeatureString(int iClient, const char[] szFeature, char[] szBuffer, int iMaxLength); 558 | 559 | /** 560 | * Выдает игроку VIP-функцию и устанавливает её значение (на время сессии). 561 | * 562 | * @param iClient Индекс игрока. 563 | * @param szFeature Уникальное имя ф-и. 564 | * @param szValue Значение (автоматически будет приведено к типу ф-и). 565 | * 566 | * @return true - Успешно. 567 | * false - Не удалось выполнить. 568 | */ 569 | native bool VIP_GiveClientFeature(int iClient, const char[] szFeature, const char[] szValue); 570 | 571 | /** 572 | * Отнимает у VIP-игрока VIP-функцию (на время сессии). 573 | * 574 | * @param iClient Индекс игрока. 575 | * @param szFeature Уникальное имя ф-и. 576 | * 577 | * @return true - Успешно. 578 | * false - Не удалось выполнить. 579 | */ 580 | native bool VIP_RemoveClientFeature(int iClient, const char[] szFeature); 581 | 582 | /** 583 | * Получает Handle базы данных. После работы необходимо закрыть с помощью CloseHandle() или delete 584 | * 585 | * @noparams 586 | * 587 | * @return Database (Handle) базы данных 588 | */ 589 | native Database VIP_GetDatabase(); 590 | 591 | /** 592 | * Получает тип базы данных. 593 | * 594 | * @noparams 595 | * 596 | * @return true - MySQL. 597 | * false - SQLite. 598 | */ 599 | native bool VIP_GetDatabaseType(); 600 | 601 | /** 602 | * Получает время в секундах в зависимости от sm_vip_time_mode. 603 | * 604 | * @param iTime Время. 605 | * 606 | * @return Возвращает количество секунд в зависимости от sm_vip_time_mode. 607 | */ 608 | native int VIP_TimeToSeconds(int iTime); 609 | 610 | /** 611 | * Получает время в зависимости от sm_vip_time_mode. 612 | * 613 | * @param iTime Количество секунд. 614 | * 615 | * @return Возвращает время в зависимости от sm_vip_time_mode. 616 | */ 617 | native int VIP_SecondsToTime(int iTime); 618 | 619 | /** 620 | * Переводит секунды в человекопонятный вид. 621 | * 622 | * @param szBuffer Буфер, в который будет помещен результат. 623 | * @param iMaxLength Размер буфера. 624 | * @param iTimeStamp Кол-во секунд. 625 | * @param iClient Индекс игрока или LANG_SERVER. 626 | * 627 | * @return true - Успешно. 628 | * false - Не удалось выполнить. 629 | */ 630 | native bool VIP_GetTimeFromStamp(char[] szBuffer, int iMaxLength, int iTimeStamp, int iClient = LANG_SERVER); 631 | 632 | /** 633 | * Добавляет к строке статус ф-и. 634 | * 635 | * @param szInput Исходная строка. 636 | * @param szBuffer Буфер, в который будет помещен результат. 637 | * @param iMaxLength Размер буфера. 638 | * @param szFeature Уникальное имя ф-и. 639 | * @param iClient Индекс игрока. 640 | * 641 | * @noreturn 642 | */ 643 | native void VIP_AddStringToggleStatus(const char[] szInput, char[] szBuffer, int iMaxLength, const char[] szFeature, int iClient); 644 | 645 | public SharedPlugin __pl_vip_core= 646 | { 647 | name = "vip_core", 648 | file = "VIP_Core.smx", 649 | #if defined REQUIRE_PLUGIN 650 | required = 1 651 | #else 652 | required = 0 653 | #endif 654 | }; 655 | 656 | #if !defined REQUIRE_PLUGIN 657 | public void __pl_vip_core_SetNTVOptional() 658 | { 659 | MarkNativeAsOptional("VIP_IsVIPLoaded"); 660 | MarkNativeAsOptional("VIP_GetDatabase"); 661 | MarkNativeAsOptional("VIP_GetDatabaseType"); 662 | MarkNativeAsOptional("VIP_RegisterFeature"); 663 | MarkNativeAsOptional("VIP_UnregisterFeature"); 664 | MarkNativeAsOptional("VIP_IsValidFeature"); 665 | MarkNativeAsOptional("VIP_GetFeatureType"); 666 | MarkNativeAsOptional("VIP_GetFeatureValueType"); 667 | MarkNativeAsOptional("VIP_SetFeatureDefStatus"); 668 | MarkNativeAsOptional("VIP_FillArrayByFeatures"); 669 | MarkNativeAsOptional("VIP_SetClientVIP"); 670 | MarkNativeAsOptional("VIP_RemoveClientVIP"); 671 | MarkNativeAsOptional("VIP_RemoveClientVIP2"); 672 | MarkNativeAsOptional("VIP_CheckClient"); 673 | MarkNativeAsOptional("VIP_IsClientVIP"); 674 | MarkNativeAsOptional("VIP_GetClientID"); 675 | MarkNativeAsOptional("VIP_GetClientVIPGroup"); 676 | MarkNativeAsOptional("VIP_SetClientVIPGroup"); 677 | MarkNativeAsOptional("VIP_GetClientAccessTime"); 678 | MarkNativeAsOptional("VIP_SetClientAccessTime"); 679 | MarkNativeAsOptional("VIP_GetVIPClientTrie"); 680 | MarkNativeAsOptional("VIP_SendClientVIPMenu"); 681 | MarkNativeAsOptional("VIP_IsValidVIPGroup"); 682 | MarkNativeAsOptional("VIP_GetClientFeatureStatus"); 683 | MarkNativeAsOptional("VIP_SetClientFeatureStatus"); 684 | MarkNativeAsOptional("VIP_IsClientFeatureUse"); 685 | MarkNativeAsOptional("VIP_GetClientFeatureInt"); 686 | MarkNativeAsOptional("VIP_GetClientFeatureFloat"); 687 | MarkNativeAsOptional("VIP_GetClientFeatureBool"); 688 | MarkNativeAsOptional("VIP_GetClientFeatureString"); 689 | MarkNativeAsOptional("VIP_PrintToChatClient"); 690 | MarkNativeAsOptional("VIP_PrintToChatAll"); 691 | MarkNativeAsOptional("VIP_LogMessage"); 692 | MarkNativeAsOptional("VIP_TimeToSeconds"); 693 | MarkNativeAsOptional("VIP_SecondsToTime"); 694 | MarkNativeAsOptional("VIP_GetTimeFromStamp"); 695 | MarkNativeAsOptional("VIP_AddStringToggleStatus"); 696 | MarkNativeAsOptional("VIP_GiveClientVIP"); 697 | MarkNativeAsOptional("VIP_UnregisterMe"); 698 | MarkNativeAsOptional("VIP_GiveClientFeature"); 699 | MarkNativeAsOptional("VIP_RemoveClientFeature"); 700 | } 701 | #endif 702 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/vip/AdminMenu.sp: -------------------------------------------------------------------------------- 1 | #undef REQUIRE_PLUGIN 2 | #include 3 | #define REQUIRE_PLUGIN 4 | 5 | static TopMenuObject g_eAdminMenuObject = INVALID_TOPMENUOBJECT; 6 | static TopMenu g_hTopMenu; 7 | static Menu g_hVIPAdminMenu; 8 | 9 | stock const char DATA_KEY_MenuType[] = "MenuType"; 10 | stock const char DATA_KEY_MenuListType[] = "MenuListType"; 11 | stock const char DATA_KEY_ThrowMenuType[] = "ThrowMenuType"; 12 | stock const char DATA_KEY_TargetID[] = "TargetID"; 13 | stock const char DATA_KEY_TargetUID[] = "TargetUID"; 14 | stock const char DATA_KEY_TimeType[] = "TimeType"; 15 | stock const char DATA_KEY_Time[] = "Time"; 16 | stock const char DATA_KEY_Name[] = "Name"; 17 | stock const char DATA_KEY_Group[] = "Group"; 18 | stock const char DATA_KEY_Auth[] = "Auth"; 19 | stock const char DATA_KEY_Offset[] = "Offset"; 20 | stock const char DATA_KEY_Search[] = "Search"; 21 | 22 | static const char g_szAdminMenuLibrary[] = "adminmenu"; 23 | 24 | enum AdminMenuType 25 | { 26 | TOP_ADMIN_MENU = 0, 27 | ADMIN_MENU 28 | } 29 | 30 | enum TimeActionItem 31 | { 32 | TIME_SET = 0, 33 | TIME_ADD, 34 | TIME_TAKE 35 | } 36 | 37 | enum AdminMenuItem 38 | { 39 | MENU_TYPE_ADD = 0, 40 | MENU_TYPE_EDIT, 41 | MENU_TYPE_ONLINE_LIST, 42 | MENU_TYPE_DB_LIST 43 | } 44 | 45 | void DisplayAdminMenu(int iClient) 46 | { 47 | g_hVIPAdminMenu.Display(iClient, MENU_TIME_FOREVER); 48 | } 49 | 50 | void BackToAdminMenu(int iClient) 51 | { 52 | AdminMenuType eThrowMenuType; 53 | g_hClientData[iClient].GetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); 54 | switch (eThrowMenuType) 55 | { 56 | case TOP_ADMIN_MENU: g_hTopMenu.Display(iClient, TopMenuPosition_LastCategory); 57 | case ADMIN_MENU: g_hVIPAdminMenu.Display(iClient, MENU_TIME_FOREVER); 58 | } 59 | } 60 | 61 | void InitiateDataMap(int iClient) 62 | { 63 | if (g_hClientData[iClient] == null) 64 | { 65 | g_hClientData[iClient] = new StringMap(); 66 | } 67 | else 68 | { 69 | g_hClientData[iClient].Clear(); 70 | } 71 | } 72 | 73 | int IsClientOnline(int ID) 74 | { 75 | int iClientID; 76 | for (int i = 1; i <= MaxClients; ++i) 77 | { 78 | if (IsClientInGame(i) && g_hFeatures[i] != null && g_hFeatures[i].GetValue(KEY_CID, iClientID) && iClientID == ID) return i; 79 | } 80 | return 0; 81 | } 82 | 83 | // ************************ ADMIN_MENU ************************ 84 | void AdminMenu_Setup() 85 | { 86 | g_hVIPAdminMenu = new Menu(Handler_VIPAdminMenu, MenuAction_Display | MenuAction_Select | MenuAction_DisplayItem); 87 | 88 | g_hVIPAdminMenu.AddItem(NULL_STRING, "vip_add"); 89 | g_hVIPAdminMenu.AddItem(NULL_STRING, "vip_list"); 90 | g_hVIPAdminMenu.AddItem(NULL_STRING, "vip_reload_players"); 91 | g_hVIPAdminMenu.AddItem(NULL_STRING, "vip_reload_settings"); 92 | 93 | if(LibraryExists(g_szAdminMenuLibrary)) 94 | { 95 | TopMenu hTopMenu = GetAdminTopMenu(); 96 | if(hTopMenu != null) 97 | { 98 | OnAdminMenuReady(hTopMenu); 99 | } 100 | } 101 | } 102 | 103 | public int Handler_VIPAdminMenu(Menu hMenu, MenuAction action, int iClient, int iItem) 104 | { 105 | switch (action) 106 | { 107 | case MenuAction_Display: 108 | { 109 | char szTitle[128]; 110 | FormatEx(SZF(szTitle), "%T:\n ", "VIP_ADMIN_MENU_TITLE", iClient); 111 | (view_as(iItem)).SetTitle(szTitle); 112 | } 113 | case MenuAction_DisplayItem: 114 | { 115 | char szDisplay[128]; 116 | 117 | switch (iItem) 118 | { 119 | case 0: FormatEx(SZF(szDisplay), "%T", "MENU_ADD_VIP", iClient); 120 | case 1: FormatEx(SZF(szDisplay), "%T", "MENU_LIST_VIP", iClient); 121 | case 2: FormatEx(SZF(szDisplay), "%T", "ADMIN_MENU_RELOAD_VIP_PLAYES", iClient); 122 | case 3: FormatEx(SZF(szDisplay), "%T", "ADMIN_MENU_RELOAD_VIP_CFG", iClient); 123 | } 124 | 125 | return RedrawMenuItem(szDisplay); 126 | } 127 | 128 | case MenuAction_Select: 129 | { 130 | switch (iItem) 131 | { 132 | case 0: 133 | { 134 | InitiateDataMap(iClient); 135 | g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); 136 | g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); 137 | ShowAddVIPMenu(iClient); 138 | } 139 | case 1: 140 | { 141 | InitiateDataMap(iClient); 142 | g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); 143 | ShowVipPlayersListMenu(iClient); 144 | } 145 | case 2: 146 | { 147 | ReloadVIPPlayers_CMD(iClient, 0); 148 | 149 | g_hVIPAdminMenu.Display(iClient, MENU_TIME_FOREVER); 150 | } 151 | case 3: 152 | { 153 | ReloadVIPCfg_CMD(iClient, 0); 154 | 155 | g_hVIPAdminMenu.Display(iClient, MENU_TIME_FOREVER); 156 | } 157 | } 158 | } 159 | } 160 | 161 | return 0; 162 | } 163 | 164 | // ************************ TOP_ADMIN_MENU ************************ 165 | public void OnLibraryAdded(const char[] szLibraryName) 166 | { 167 | if (strcmp(szLibraryName, g_szAdminMenuLibrary) == 0) 168 | { 169 | TopMenu hTopMenu = GetAdminTopMenu(); 170 | if (hTopMenu != null) 171 | { 172 | OnAdminMenuReady(hTopMenu); 173 | } 174 | } 175 | } 176 | 177 | public void OnLibraryRemoved(const char[] szLibraryName) 178 | { 179 | if (strcmp(szLibraryName, g_szAdminMenuLibrary) == 0) 180 | { 181 | g_hTopMenu = null; 182 | g_eAdminMenuObject = INVALID_TOPMENUOBJECT; 183 | } 184 | } 185 | 186 | public void OnAdminMenuReady(Handle aTopMenu) 187 | { 188 | TopMenu hTopMenu = TopMenu.FromHandle(aTopMenu); 189 | if (g_hTopMenu == hTopMenu) 190 | { 191 | return; 192 | } 193 | 194 | g_hTopMenu = hTopMenu; 195 | 196 | AddItemsToTopMenu(); 197 | } 198 | 199 | void AddItemsToTopMenu() 200 | { 201 | if (g_eAdminMenuObject == INVALID_TOPMENUOBJECT) 202 | { 203 | g_eAdminMenuObject = g_hTopMenu.AddCategory("vip_admin", Handler_MenuAdmin, "sm_vipadmin", ADMFLAG_ROOT); 204 | } 205 | 206 | g_hTopMenu.AddItem("vip_add", Handler_MenuAdd, g_eAdminMenuObject, "sm_vipadmin", ADMFLAG_ROOT); 207 | g_hTopMenu.AddItem("vip_list", Handler_MenuList, g_eAdminMenuObject, "sm_vipadmin", ADMFLAG_ROOT); 208 | g_hTopMenu.AddItem("vip_reload_players", Handler_MenuReloadPlayers, g_eAdminMenuObject, "sm_vipadmin", ADMFLAG_ROOT); 209 | g_hTopMenu.AddItem("vip_reload_settings", Handler_MenuReloadSettings, g_eAdminMenuObject, "sm_vipadmin", ADMFLAG_ROOT); 210 | } 211 | 212 | public void Handler_MenuAdmin(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] szBuffer, int iMaxLen) 213 | { 214 | switch (action) 215 | { 216 | case TopMenuAction_DisplayOption: FormatEx(szBuffer, iMaxLen, "%T", "VIP_ADMIN_MENU_TITLE", iClient); 217 | case TopMenuAction_DisplayTitle: FormatEx(szBuffer, iMaxLen, "%T:\n ", "VIP_ADMIN_MENU_TITLE", iClient); 218 | } 219 | } 220 | 221 | // ************************ ADD_VIP ************************ 222 | public void Handler_MenuAdd(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] szBuffer, int iMaxLen) 223 | { 224 | switch (action) 225 | { 226 | case TopMenuAction_DisplayOption: FormatEx(szBuffer, iMaxLen, "%T", "MENU_ADD_VIP", iClient); 227 | case TopMenuAction_SelectOption: 228 | { 229 | InitiateDataMap(iClient); 230 | g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); 231 | g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); 232 | ShowAddVIPMenu(iClient); 233 | } 234 | } 235 | } 236 | 237 | // ************************ LIST_VIP ************************ 238 | 239 | public void Handler_MenuList(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] szBuffer, int iMaxLen) 240 | { 241 | switch (action) 242 | { 243 | case TopMenuAction_DisplayOption: FormatEx(szBuffer, iMaxLen, "%T", "MENU_LIST_VIP", iClient); 244 | case TopMenuAction_SelectOption: 245 | { 246 | InitiateDataMap(iClient); 247 | g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); 248 | ShowVipPlayersListMenu(iClient); 249 | } 250 | } 251 | } 252 | 253 | // ************************ RELOAD_VIP_PLAYES ************************ 254 | public void Handler_MenuReloadPlayers(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] szBuffer, int iMaxLen) 255 | { 256 | switch (action) 257 | { 258 | case TopMenuAction_DisplayOption: FormatEx(szBuffer, iMaxLen, "%T", "ADMIN_MENU_RELOAD_VIP_PLAYES", iClient); 259 | case TopMenuAction_SelectOption: 260 | { 261 | ReloadVIPPlayers_CMD(iClient, 0); 262 | RedisplayAdminMenu(g_hTopMenu, iClient); 263 | } 264 | } 265 | } 266 | 267 | // ************************ RELOAD_VIP_CFG ************************ 268 | public void Handler_MenuReloadSettings(TopMenu hMenu, TopMenuAction action, TopMenuObject object_id, int iClient, char[] szBuffer, int iMaxLen) 269 | { 270 | switch (action) 271 | { 272 | case TopMenuAction_DisplayOption: FormatEx(szBuffer, iMaxLen, "%T", "ADMIN_MENU_RELOAD_VIP_CFG", iClient); 273 | case TopMenuAction_SelectOption: 274 | { 275 | ReloadVIPCfg_CMD(iClient, 0); 276 | 277 | RedisplayAdminMenu(g_hTopMenu, iClient); 278 | } 279 | } 280 | } 281 | 282 | void ShowTimeMenu(int iClient) 283 | { 284 | Menu hMenu = new Menu(MenuHandler_TimeMenu); 285 | 286 | TimeActionItem iMenuType; 287 | g_hClientData[iClient].GetValue(DATA_KEY_TimeType, iMenuType); 288 | 289 | switch (iMenuType) 290 | { 291 | case TIME_SET: hMenu.SetTitle("%T:\n ", "MENU_TIME_SET", iClient); 292 | case TIME_ADD: hMenu.SetTitle("%T:\n ", "MENU_TIME_ADD", iClient); 293 | case TIME_TAKE: hMenu.SetTitle("%T:\n ", "MENU_TIME_TAKE", iClient); 294 | } 295 | 296 | hMenu.ExitBackButton = true; 297 | 298 | KeyValues hKv = CreateConfig("data/vip/cfg/times.ini", "TIMES"); 299 | 300 | if (hKv.GotoFirstSubKey()) 301 | { 302 | char szBuffer[128], szTime[32], szClientLang[4], szServerLang[4]; 303 | GetLanguageInfo(GetServerLanguage(), SZF(szServerLang)); 304 | GetLanguageInfo(GetClientLanguage(iClient), SZF(szClientLang)); 305 | 306 | do 307 | { 308 | hKv.GetSectionName(SZF(szTime)); 309 | 310 | if (iMenuType != TIME_SET && szTime[0] == '0') continue; 311 | 312 | hKv.GetString(szClientLang, SZF(szBuffer)); 313 | if (!szBuffer[0]) 314 | { 315 | hKv.GetString(szServerLang, SZF(szBuffer)); 316 | } 317 | if (!szBuffer[0]) 318 | { 319 | strcopy(SZF(szBuffer), "LangError"); 320 | } 321 | 322 | hMenu.AddItem(szTime, szBuffer); 323 | 324 | } 325 | while (hKv.GotoNextKey(false)); 326 | } 327 | 328 | delete hKv; 329 | 330 | hMenu.Display(iClient, MENU_TIME_FOREVER); 331 | } 332 | 333 | public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int iItem) 334 | { 335 | switch (action) 336 | { 337 | case MenuAction_End: delete hMenu; 338 | case MenuAction_Cancel: 339 | { 340 | if (iItem == MenuCancel_ExitBack) 341 | { 342 | AdminMenuItem eMenuItem; 343 | g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); 344 | 345 | switch (eMenuItem) 346 | { 347 | case MENU_TYPE_ADD: ShowAddVIPMenu(iClient); 348 | case MENU_TYPE_EDIT: ShowEditTimeMenu(iClient); 349 | } 350 | } 351 | } 352 | case MenuAction_Select: 353 | { 354 | char szName[64]; 355 | hMenu.GetItem(iItem, SZF(szName)); 356 | int iTime, iTarget; 357 | AdminMenuItem eMenuItem; 358 | iTime = S2I(szName); 359 | g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); 360 | 361 | if (eMenuItem == MENU_TYPE_ADD) 362 | { 363 | g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); 364 | if ((iTarget = GetClientOfUserId(iTarget))) 365 | { 366 | char szBuffer[64]; 367 | hMenu.GetItem(iItem, SZF(szBuffer)); 368 | g_hClientData[iClient].SetValue(DATA_KEY_Time, S2I(szBuffer)); 369 | ShowGroupsMenu(iClient); 370 | } 371 | else 372 | { 373 | VIP_PrintToChatClient(iClient, "%t", "PLAYER_NO_LONGER_AVAILABLE"); 374 | BackToAdminMenu(iClient); 375 | } 376 | return 0; 377 | } 378 | 379 | char szTime[64]; 380 | int iExpires; 381 | g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); 382 | 383 | TimeActionItem eTimeActionItem; 384 | g_hClientData[iClient].GetValue(DATA_KEY_TimeType, eTimeActionItem); 385 | switch(eTimeActionItem) 386 | { 387 | case TIME_SET: 388 | { 389 | if (iTime == 0) 390 | { 391 | iExpires = 0; 392 | } 393 | else 394 | { 395 | iExpires = GetTime() + iTime; 396 | } 397 | 398 | FormatTime(SZF(szTime), "%d/%m/%Y - %H:%M", iExpires); 399 | VIP_PrintToChatClient(iClient, "%t", "ADMIN_SET_EXPIRATION", szName, szTime); 400 | 401 | if (g_CVAR_bLogsEnable) 402 | { 403 | LogToFile(g_szLogFile, "%T", "LOG_ADMIN_SET_EXPIRATION", LANG_SERVER, iClient, szName, szTime); 404 | } 405 | } 406 | case TIME_ADD: 407 | { 408 | g_hClientData[iClient].GetValue(DATA_KEY_Time, iExpires); 409 | if (iExpires <= 0) 410 | { 411 | VIP_PrintToChatClient(iClient, "%t", "UNABLE_TO_EXTENDED"); 412 | ShowTimeMenu(iClient); 413 | return 0; 414 | } 415 | 416 | iExpires += iTime; 417 | 418 | UTIL_GetTimeFromStamp(SZF(szTime), iTime, iClient); 419 | VIP_PrintToChatClient(iClient, "%t", "ADMIN_EXTENDED", szName, szTime); 420 | 421 | if (g_CVAR_bLogsEnable) 422 | { 423 | LogToFile(g_szLogFile, "%T", "LOG_ADMIN_EXTENDED", LANG_SERVER, iClient, szName, szTime); 424 | } 425 | } 426 | case TIME_TAKE: 427 | { 428 | g_hClientData[iClient].GetValue(DATA_KEY_Time, iExpires); 429 | if (iExpires <= 0) 430 | { 431 | VIP_PrintToChatClient(iClient, "%t", "UNABLE_TO_REDUCE"); 432 | ShowTimeMenu(iClient); 433 | return 0; 434 | } 435 | 436 | iExpires -= iTime; 437 | 438 | if (iExpires <= GetTime()) 439 | { 440 | VIP_PrintToChatClient(iClient, "%t", "INCORRECT_TIME"); 441 | ShowTimeMenu(iClient); 442 | return 0; 443 | } 444 | 445 | UTIL_GetTimeFromStamp(SZF(szTime), iTime, iClient); 446 | 447 | VIP_PrintToChatClient(iClient, "%t", "ADMIN_REDUCED", szName, szTime); 448 | 449 | if (g_CVAR_bLogsEnable) 450 | { 451 | LogToFile(g_szLogFile, "%T", "LOG_ADMIN_REDUCED", LANG_SERVER, iClient, szName, szTime); 452 | } 453 | } 454 | } 455 | 456 | g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTarget); 457 | g_hClientData[iClient].SetValue(DATA_KEY_Time, iExpires); 458 | 459 | char szQuery[512]; 460 | FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `expires` = '%d' WHERE `account_id` = '%d'%s;", iExpires, iTarget, g_szSID); 461 | DBG_SQL_Query(szQuery); 462 | g_hDatabase.Query(SQL_Callback_ChangeTime, szQuery, UID(iClient)); 463 | 464 | ShowTargetInfoMenu(iClient); 465 | } 466 | } 467 | 468 | return 0; 469 | } 470 | 471 | void ShowGroupsMenu(int iClient, const char[] sTargetGroup = NULL_STRING) 472 | { 473 | char szGroup[MAX_NAME_LENGTH]; 474 | Menu hMenu = new Menu(MenuHandler_GroupsList); 475 | hMenu.SetTitle("%T:\n ", "GROUP", iClient); 476 | hMenu.ExitBackButton = true; 477 | szGroup[0] = 0; 478 | g_hGroups.Rewind(); 479 | if (g_hGroups.GotoFirstSubKey()) 480 | { 481 | do 482 | { 483 | if (g_hGroups.GetSectionName(SZF(szGroup))) 484 | { 485 | if(sTargetGroup[0] && !strcmp(sTargetGroup, szGroup)) 486 | { 487 | Format(SZF(szGroup), "%s [X]", szGroup); 488 | hMenu.AddItem(szGroup, szGroup, ITEMDRAW_DISABLED); 489 | continue; 490 | } 491 | 492 | hMenu.AddItem(szGroup, szGroup); 493 | } 494 | } while (g_hGroups.GotoNextKey()); 495 | } 496 | if (!szGroup[0]) 497 | { 498 | FormatEx(SZF(szGroup), "%T", "NO_GROUPS_AVAILABLE", iClient); 499 | hMenu.AddItem(NULL_STRING, szGroup, ITEMDRAW_DISABLED); 500 | } 501 | 502 | hMenu.Display(iClient, MENU_TIME_FOREVER); 503 | } 504 | 505 | public int MenuHandler_GroupsList(Menu hMenu, MenuAction action, int iClient, int iItem) 506 | { 507 | switch (action) 508 | { 509 | case MenuAction_End:delete hMenu; 510 | case MenuAction_Cancel: 511 | { 512 | if (iItem == MenuCancel_ExitBack) 513 | { 514 | AdminMenuItem eMenuItem; 515 | g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); 516 | switch(eMenuItem) 517 | { 518 | case MENU_TYPE_ADD: 519 | { 520 | ShowTimeMenu(iClient); 521 | } 522 | case MENU_TYPE_EDIT: 523 | { 524 | ShowTargetInfoMenu(iClient); 525 | } 526 | } 527 | } 528 | } 529 | case MenuAction_Select: 530 | { 531 | char szGroup[64]; 532 | hMenu.GetItem(iItem, SZF(szGroup)); 533 | AdminMenuItem eMenuItem; 534 | g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); 535 | switch(eMenuItem) 536 | { 537 | case MENU_TYPE_ADD: 538 | { 539 | int iTarget, iBuffer; 540 | g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); 541 | iTarget = CID(iTarget); 542 | if (iTarget) 543 | { 544 | g_hClientData[iClient].GetValue(DATA_KEY_Time, iBuffer); 545 | g_hClientData[iClient].Clear(); 546 | UTIL_ADD_VIP_PLAYER(iClient, iTarget, _, iBuffer, szGroup); 547 | } 548 | else 549 | { 550 | VIP_PrintToChatClient(iClient, "%t", "Player no longer available"); 551 | } 552 | 553 | BackToAdminMenu(iClient); 554 | } 555 | case MENU_TYPE_EDIT: 556 | { 557 | char szQuery[256], szName[MNL], szOldGroup[64]; 558 | hMenu.GetItem(iItem, SZF(szGroup)); 559 | int iTargetID; 560 | g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTargetID); 561 | g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); 562 | g_hClientData[iClient].GetString(DATA_KEY_Group, SZF(szOldGroup)); 563 | 564 | FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `group` = '%s' WHERE `account_id` = %d%s;", szGroup, iTargetID, g_szSID); 565 | 566 | DBG_SQL_Query(szQuery); 567 | g_hDatabase.Query(SQL_Callback_ErrorCheck, szQuery); 568 | 569 | int iTarget = 0; 570 | g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); 571 | iTarget = CID(iTarget); 572 | if (!iTarget) 573 | { 574 | iTarget = IsClientOnline(iTargetID); 575 | } 576 | 577 | if (iTarget) 578 | { 579 | ResetClient(iTarget); 580 | CreateForward_OnVIPClientRemoved(iTarget, "VIP-Group Changed", iClient); 581 | Clients_CheckVipAccess(iTarget, false); 582 | } 583 | 584 | VIP_PrintToChatClient(iClient, "%t", "ADMIN_SET_GROUP", szName, szGroup); 585 | if (g_CVAR_bLogsEnable) 586 | { 587 | char szAdmin[256], szAdminInfo[128]; 588 | UTIL_GetClientInfo(iClient, SZF(szAdminInfo)); 589 | FormatEx(SZF(szAdmin), "%T %s", "BY_ADMIN", LANG_SERVER, szAdminInfo); 590 | LogToFile(g_szLogFile, "%T", "LOG_CHANGE_GROUP", LANG_SERVER, szName, iTargetID, szOldGroup, szGroup, szAdmin); 591 | } 592 | 593 | ShowTargetInfo(iClient); 594 | } 595 | } 596 | } 597 | } 598 | 599 | return 0; 600 | } 601 | 602 | public void SQL_Callback_ChangeTime(Database hOwner, DBResultSet hResult, const char[] szError, any UserID) 603 | { 604 | DBG_SQL_Response("SQL_Callback_ChangeTime") 605 | if (szError[0]) 606 | { 607 | LogError("SQL_Callback_ChangeTime: %s", szError); 608 | return; 609 | } 610 | 611 | DBG_SQL_Response("hResult.AffectedRows = %d", hResult.AffectedRows) 612 | 613 | if (hResult.AffectedRows) 614 | { 615 | int iClient = CID(UserID); 616 | if (iClient) 617 | { 618 | int iTarget; 619 | g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); 620 | iTarget = CID(iTarget); 621 | if(!iTarget) 622 | { 623 | g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTarget); 624 | iTarget = IsClientOnline(iTarget); 625 | } 626 | 627 | if (iTarget) 628 | { 629 | Clients_CheckVipAccess(iTarget, true); 630 | } 631 | } 632 | } 633 | } 634 | 635 | void ReductionMenu(Menu &hMenu, int iNum) 636 | { 637 | for (int i = 0; i < iNum; ++i) 638 | { 639 | hMenu.AddItem(NULL_STRING, NULL_STRING, ITEMDRAW_NOTEXT); 640 | } 641 | } 642 | 643 | public Action OnClientSayCommand(int iClient, const char[] szCommand, const char[] szArgs) 644 | { 645 | if(iClient > 0 && iClient <= MaxClients && szArgs[0]) 646 | { 647 | if(g_iClientInfo[iClient] & IS_WAIT_CHAT_SEARCH) 648 | { 649 | if(g_iClientInfo[iClient] & IS_WAIT_CHAT_SEARCH) 650 | { 651 | ShowWaitSearchMenu(iClient, szArgs); 652 | } 653 | 654 | return Plugin_Handled; 655 | } 656 | } 657 | 658 | return Plugin_Continue; 659 | } 660 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/vip/CMD.sp: -------------------------------------------------------------------------------- 1 | void CMD_Setup() 2 | { 3 | RegAdminCmd("sm_refresh_vips", ReloadVIPPlayers_CMD, ADMFLAG_ROOT); 4 | RegAdminCmd("sm_reload_vip_cfg", ReloadVIPCfg_CMD, ADMFLAG_ROOT); 5 | RegAdminCmd("sm_addvip", AddVIP_CMD, ADMFLAG_ROOT); 6 | RegAdminCmd("sm_delvip", DelVIP_CMD, ADMFLAG_ROOT); 7 | 8 | #if USE_ADMINMENU 9 | RegAdminCmd("sm_vipadmin", VIPAdmin_CMD, ADMFLAG_ROOT); 10 | #endif 11 | 12 | #if DEBUG_MODE 13 | RegAdminCmd("sm_vip_dump_features", DumpFeatures_CMD, ADMFLAG_ROOT); 14 | #endif 15 | } 16 | 17 | public void OnConfigsExecuted() 18 | { 19 | static bool bIsRegistered; 20 | if (bIsRegistered == false) 21 | { 22 | UTIL_LoadVipCmd(g_CVAR_hVIPMenu_CMD, VIPMenu_CMD); 23 | 24 | bIsRegistered = true; 25 | } 26 | } 27 | 28 | #if USE_ADMINMENU 29 | public Action VIPAdmin_CMD(int iClient, int iArgs) 30 | { 31 | if (iClient) 32 | { 33 | DisplayAdminMenu(iClient); 34 | } 35 | 36 | return Plugin_Handled; 37 | } 38 | #endif 39 | 40 | public Action ReloadVIPPlayers_CMD(int iClient, int iArgs) 41 | { 42 | UTIL_ReloadVIPPlayers(iClient, true); 43 | 44 | return Plugin_Handled; 45 | } 46 | 47 | public Action ReloadVIPCfg_CMD(int iClient, int iArgs) 48 | { 49 | ReadConfigs(); 50 | UTIL_ReloadVIPPlayers(iClient, false); 51 | UTIL_Reply(iClient, "%t", "VIP_CFG_REFRESHED"); 52 | 53 | return Plugin_Handled; 54 | } 55 | 56 | public Action AddVIP_CMD(int iClient, int iArgs) 57 | { 58 | if (iArgs != 3) 59 | { 60 | ReplyToCommand(iClient, "[VIP] %t!\nSyntax: sm_addvip <#steam_id|#name|#userid>