v1.3: разграничение прав, логирование, удалены blind/invertmouse
- Обычные админы (флаги abcdefghij без z) видят только меню Эффекты игрока - Группы DEIDARA/TESTER сохраняют полный доступ - Действия обычных админов логируются в addons/sourcemod/logs/super_admin_menu.log - Удалён эффект Ослепление на 2 сек - Удалён эффект Инверсия мыши
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
# Super Admin Menu
|
# Super Admin Menu
|
||||||
|
|
||||||
Расширенное меню администратора для CS:GO серверов на SourceMod. Открывается одной командой и предоставляет все нужные инструменты управления игроками.
|
Расширенное меню администратора для CS:GO серверов на SourceMod. Открывается одной командой и предоставляет все нужные инструменты управления игроками с разграничением прав.
|
||||||
|
|
||||||
## Функции
|
## Функции
|
||||||
|
|
||||||
- Выдача снаряжения (сет с оружием): AK-47, M4A4, M4A1-S, AWP, Deagle Only
|
- Выдача снаряжения (сет с оружием): AK-47, M4A4, M4A1-S, AWP, Deagle Only
|
||||||
- Выдача денег: 3000 / 5000 / 10000 / 16000$
|
- Выдача денег: 3000 / 5000 / 10000 / 16000$
|
||||||
- Респавн игроков (себе / всем / конкретному игроку)
|
- Респавн игроков (себе / всем / конкретному игроку)
|
||||||
- Восстановление 100 HP + 100 Armor (только группы DEIDARA / TESTER)
|
- Восстановление 100 HP + 100 Armor
|
||||||
- Невидимость для администратора с сокрытием оружия
|
- Невидимость для администратора с сокрытием оружия
|
||||||
- Телепорт к игроку / телепорт игрока к себе
|
- Телепорт к игроку / телепорт игрока к себе
|
||||||
- Телепорт на плент A или B (автоопределение по карте)
|
- Телепорт на плент A или B (автоопределение по карте)
|
||||||
@@ -17,10 +17,9 @@
|
|||||||
- Drug-эффект (дёргание экрана + случайный FOV)
|
- Drug-эффект (дёргание экрана + случайный FOV)
|
||||||
- Случайный FOV
|
- Случайный FOV
|
||||||
- Инверсия движения
|
- Инверсия движения
|
||||||
- Инверсия мыши
|
|
||||||
- Сильное сотрясение экрана
|
- Сильное сотрясение экрана
|
||||||
- Ослепление на 2 секунды
|
- Уведомления о действиях в чате членам групп DEIDARA / TESTER
|
||||||
- Все действия логируются в чат онлайн-администраторам
|
- Логирование действий обычных админов в файл
|
||||||
|
|
||||||
## Зависимости
|
## Зависимости
|
||||||
|
|
||||||
@@ -38,18 +37,51 @@
|
|||||||
|
|
||||||
| Команда | Доступ | Описание |
|
| Команда | Доступ | Описание |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `!sadmin` / `sm_sadmin` | Root или группа DEIDARA/TESTER | Открыть супер-админ меню |
|
| `!sadmin` / `sm_sadmin` | Группа DEIDARA / TESTER или обычный админ (флаги `a`–`j`) | Открыть супер-админ меню |
|
||||||
|
|
||||||
## Уровни доступа
|
## Уровни доступа
|
||||||
|
|
||||||
| Уровень | Возможности |
|
| Уровень | Возможности |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Root (`ADMFLAG_ROOT`) | Все функции меню |
|
| Группа **DEIDARA** | Все функции меню (полный доступ) |
|
||||||
| Группа **DEIDARA** | Все функции меню |
|
| Группа **TESTER** | Все функции меню (полный доступ) |
|
||||||
| Группа **TESTER** | Все функции меню |
|
| Обычный админ (любые флаги `abcdefghij`, без `z`) | Только меню «Эффекты игрока» |
|
||||||
|
| Без админ-флагов | Доступ запрещён |
|
||||||
|
|
||||||
> Базовые функции (сет, деньги, респавн) доступны всем Root-админам. Расширенные функции (невидимость, телепорт, эффекты, восстановление HP) — только группам DEIDARA и TESTER.
|
> Группы DEIDARA / TESTER определяются по имени группы в `admin_groups.cfg` (регистр не важен) — флаги роли не нужны.
|
||||||
|
> Обычные админы — все, у кого есть любой флаг кроме `z` (Root) и кто не состоит в группах DEIDARA/TESTER. Им доступно только подменю «Эффекты игрока» с полным набором эффектов.
|
||||||
|
|
||||||
|
## Логирование
|
||||||
|
|
||||||
|
Все действия **обычных админов** в подменю «Эффекты игрока» автоматически пишутся в лог-файл:
|
||||||
|
|
||||||
|
```
|
||||||
|
addons/sourcemod/logs/super_admin_menu.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Формат записи:
|
||||||
|
```
|
||||||
|
[YYYY-MM-DD HH:MM:SS] АдминИмя (STEAM_X:Y:Z) -> Действие -> ВКЛ/ВЫКЛ на игроке Имя (STEAM_X:Y:Z)
|
||||||
|
```
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
```
|
||||||
|
[2026-05-01 18:42:11] AdminBob (STEAM_1:0:12345) -> 0 урона -> ВКЛ на игроке player1 (STEAM_1:1:67890)
|
||||||
|
[2026-05-01 18:42:34] AdminBob (STEAM_1:0:12345) -> Тряска экрана на игроке player2 (STEAM_1:0:55555)
|
||||||
|
```
|
||||||
|
|
||||||
|
Действия членов групп DEIDARA / TESTER в файл **не пишутся** (они отображаются только в чате другим членам этих групп через `PrintToRootAdmins`).
|
||||||
|
|
||||||
## Версия
|
## Версия
|
||||||
|
|
||||||
`1.2` — Автор: OpenAI + deidara.dev
|
`1.3` — Автор: OpenAI + deidara.dev
|
||||||
|
|
||||||
|
### Changelog
|
||||||
|
|
||||||
|
- **1.3**
|
||||||
|
- Разграничение прав: обычные админы (флаги `a`–`j`, без `z`) теперь имеют доступ только к меню «Эффекты игрока»
|
||||||
|
- Полный доступ — только у групп DEIDARA / TESTER
|
||||||
|
- Добавлено логирование действий обычных админов в `addons/sourcemod/logs/super_admin_menu.log`
|
||||||
|
- Удалён эффект «Ослепление на 2 секунды»
|
||||||
|
- Удалён эффект «Инверсия мыши»
|
||||||
|
- **1.2** — Базовая версия меню
|
||||||
|
|||||||
+103
-54
@@ -15,7 +15,6 @@ bool g_bSuperRecoil[MAXPLAYERS + 1];
|
|||||||
bool g_bDrugEffect[MAXPLAYERS + 1];
|
bool g_bDrugEffect[MAXPLAYERS + 1];
|
||||||
bool g_bRandomFov[MAXPLAYERS + 1];
|
bool g_bRandomFov[MAXPLAYERS + 1];
|
||||||
bool g_bInvertMovement[MAXPLAYERS + 1];
|
bool g_bInvertMovement[MAXPLAYERS + 1];
|
||||||
bool g_bInvertMouse[MAXPLAYERS + 1];
|
|
||||||
Handle g_hDrugTimer[MAXPLAYERS + 1];
|
Handle g_hDrugTimer[MAXPLAYERS + 1];
|
||||||
Handle g_hRandomFovTimer[MAXPLAYERS + 1];
|
Handle g_hRandomFovTimer[MAXPLAYERS + 1];
|
||||||
int g_iEffectTargetUserId[MAXPLAYERS + 1];
|
int g_iEffectTargetUserId[MAXPLAYERS + 1];
|
||||||
@@ -25,7 +24,7 @@ public Plugin myinfo =
|
|||||||
name = "Super Admin Menu",
|
name = "Super Admin Menu",
|
||||||
author = "OpenAI + deidara.dev",
|
author = "OpenAI + deidara.dev",
|
||||||
description = "Единое супер-админ меню по команде sm_sadmin",
|
description = "Единое супер-админ меню по команде sm_sadmin",
|
||||||
version = "1.2"
|
version = "1.3"
|
||||||
};
|
};
|
||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
@@ -62,7 +61,6 @@ public void OnClientDisconnect(int client)
|
|||||||
g_bDrugEffect[client] = false;
|
g_bDrugEffect[client] = false;
|
||||||
g_bRandomFov[client] = false;
|
g_bRandomFov[client] = false;
|
||||||
g_bInvertMovement[client] = false;
|
g_bInvertMovement[client] = false;
|
||||||
g_bInvertMouse[client] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,8 +105,7 @@ public Action Command_SuperAdminMenu(int client, int args)
|
|||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasRootFlag = (GetUserFlagBits(client) & ADMFLAG_ROOT) != 0;
|
if (!IsClientInAllowedGroup(client) && !IsRegularAdmin(client))
|
||||||
if (!hasRootFlag && !IsClientInAllowedGroup(client))
|
|
||||||
{
|
{
|
||||||
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
@@ -126,12 +123,11 @@ void ShowMainMenu(int client)
|
|||||||
|
|
||||||
bool isDeidara = IsClientInAllowedGroup(client);
|
bool isDeidara = IsClientInAllowedGroup(client);
|
||||||
|
|
||||||
menu.AddItem("sets", "Выдать сет");
|
|
||||||
menu.AddItem("money", "Выдать деньги");
|
|
||||||
menu.AddItem("respawn", "Респавн");
|
|
||||||
|
|
||||||
if (isDeidara)
|
if (isDeidara)
|
||||||
{
|
{
|
||||||
|
menu.AddItem("sets", "Выдать сет");
|
||||||
|
menu.AddItem("money", "Выдать деньги");
|
||||||
|
menu.AddItem("respawn", "Респавн");
|
||||||
menu.AddItem("restore", "Восстановить 100 HP / 100 Armor");
|
menu.AddItem("restore", "Восстановить 100 HP / 100 Armor");
|
||||||
menu.AddItem("invis", g_bInvisible[client] ? "Выключить невидимость" : "Включить невидимость");
|
menu.AddItem("invis", g_bInvisible[client] ? "Выключить невидимость" : "Включить невидимость");
|
||||||
menu.AddItem("tp_to", "Телепорт к игроку");
|
menu.AddItem("tp_to", "Телепорт к игроку");
|
||||||
@@ -139,6 +135,11 @@ void ShowMainMenu(int client)
|
|||||||
menu.AddItem("plant", "Телепорт на плент");
|
menu.AddItem("plant", "Телепорт на плент");
|
||||||
menu.AddItem("effects", "Эффекты игрока");
|
menu.AddItem("effects", "Эффекты игрока");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Обычный админ: только Эффекты игрока
|
||||||
|
menu.AddItem("effects", "Эффекты игрока");
|
||||||
|
}
|
||||||
|
|
||||||
menu.Display(client, MENU_TIME);
|
menu.Display(client, MENU_TIME);
|
||||||
}
|
}
|
||||||
@@ -159,6 +160,20 @@ public int MenuHandler_Main(Menu menu, MenuAction action, int client, int item)
|
|||||||
|
|
||||||
bool isDeidara = IsClientInAllowedGroup(client);
|
bool isDeidara = IsClientInAllowedGroup(client);
|
||||||
|
|
||||||
|
// Обычные админы могут открыть только меню эффектов
|
||||||
|
if (!isDeidara && !StrEqual(info, "effects"))
|
||||||
|
{
|
||||||
|
PrintToChat(client, "[SM] У тебя нет доступа к этому пункту.");
|
||||||
|
ShowMainMenu(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrEqual(info, "effects"))
|
||||||
|
{
|
||||||
|
ShowEffectTargetMenu(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (StrEqual(info, "sets"))
|
if (StrEqual(info, "sets"))
|
||||||
{
|
{
|
||||||
ShowTargetMenu(client, "set");
|
ShowTargetMenu(client, "set");
|
||||||
@@ -171,11 +186,6 @@ public int MenuHandler_Main(Menu menu, MenuAction action, int client, int item)
|
|||||||
{
|
{
|
||||||
ShowTargetMenu(client, "respawn");
|
ShowTargetMenu(client, "respawn");
|
||||||
}
|
}
|
||||||
else if (!isDeidara)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Этот пункт доступен только группам DEIDARA и TESTER.");
|
|
||||||
ShowMainMenu(client);
|
|
||||||
}
|
|
||||||
else if (StrEqual(info, "restore"))
|
else if (StrEqual(info, "restore"))
|
||||||
{
|
{
|
||||||
ShowTargetMenu(client, "restore");
|
ShowTargetMenu(client, "restore");
|
||||||
@@ -197,10 +207,6 @@ public int MenuHandler_Main(Menu menu, MenuAction action, int client, int item)
|
|||||||
{
|
{
|
||||||
ShowPlantMenu(client);
|
ShowPlantMenu(client);
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "effects"))
|
|
||||||
{
|
|
||||||
ShowEffectTargetMenu(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -875,9 +881,9 @@ void StripWeapons(int client)
|
|||||||
|
|
||||||
void ShowEffectTargetMenu(int client)
|
void ShowEffectTargetMenu(int client)
|
||||||
{
|
{
|
||||||
if (!IsClientInAllowedGroup(client))
|
if (!IsClientInAllowedGroup(client) && !IsRegularAdmin(client))
|
||||||
{
|
{
|
||||||
PrintToChat(client, "[SM] Этот пункт доступен только группам DEIDARA и TESTER.");
|
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
||||||
ShowMainMenu(client);
|
ShowMainMenu(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -915,12 +921,12 @@ void ShowEffectTargetMenu(int client)
|
|||||||
|
|
||||||
public int MenuHandler_EffectTarget(Menu menu, MenuAction action, int client, int item)
|
public int MenuHandler_EffectTarget(Menu menu, MenuAction action, int client, int item)
|
||||||
{
|
{
|
||||||
if (!IsClientInAllowedGroup(client))
|
if (!IsClientInAllowedGroup(client) && !IsRegularAdmin(client))
|
||||||
{
|
{
|
||||||
if (action == MenuAction_End)
|
if (action == MenuAction_End)
|
||||||
delete menu;
|
delete menu;
|
||||||
else if (action == MenuAction_Select)
|
else if (action == MenuAction_Select)
|
||||||
PrintToChat(client, "[SM] Этот пункт доступен только группам DEIDARA и TESTER.");
|
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -949,9 +955,9 @@ public int MenuHandler_EffectTarget(Menu menu, MenuAction action, int client, in
|
|||||||
|
|
||||||
void ShowEffectMenu(int client)
|
void ShowEffectMenu(int client)
|
||||||
{
|
{
|
||||||
if (!IsClientInAllowedGroup(client))
|
if (!IsClientInAllowedGroup(client) && !IsRegularAdmin(client))
|
||||||
{
|
{
|
||||||
PrintToChat(client, "[SM] Этот пункт доступен только группам DEIDARA и TESTER.");
|
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
||||||
ShowMainMenu(client);
|
ShowMainMenu(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -977,20 +983,18 @@ void ShowEffectMenu(int client)
|
|||||||
menu.AddItem("drug", g_bDrugEffect[target] ? "Выключить drug-эффект" : "Включить drug-эффект");
|
menu.AddItem("drug", g_bDrugEffect[target] ? "Выключить drug-эффект" : "Включить drug-эффект");
|
||||||
menu.AddItem("randomfov", g_bRandomFov[target] ? "Выключить случайный FOV" : "Включить случайный FOV");
|
menu.AddItem("randomfov", g_bRandomFov[target] ? "Выключить случайный FOV" : "Включить случайный FOV");
|
||||||
menu.AddItem("invertmove", g_bInvertMovement[target] ? "Выключить инверсию движения" : "Включить инверсию движения");
|
menu.AddItem("invertmove", g_bInvertMovement[target] ? "Выключить инверсию движения" : "Включить инверсию движения");
|
||||||
menu.AddItem("invertmouse", g_bInvertMouse[target] ? "Выключить инверсию мыши" : "Включить инверсию мыши");
|
|
||||||
menu.AddItem("shake", "Сильно тряхнуть экран");
|
menu.AddItem("shake", "Сильно тряхнуть экран");
|
||||||
menu.AddItem("blind", "Ослепить на 2 сек");
|
|
||||||
menu.Display(client, MENU_TIME);
|
menu.Display(client, MENU_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MenuHandler_EffectMenu(Menu menu, MenuAction action, int client, int item)
|
public int MenuHandler_EffectMenu(Menu menu, MenuAction action, int client, int item)
|
||||||
{
|
{
|
||||||
if (!IsClientInAllowedGroup(client))
|
if (!IsClientInAllowedGroup(client) && !IsRegularAdmin(client))
|
||||||
{
|
{
|
||||||
if (action == MenuAction_End)
|
if (action == MenuAction_End)
|
||||||
delete menu;
|
delete menu;
|
||||||
else if (action == MenuAction_Select)
|
else if (action == MenuAction_Select)
|
||||||
PrintToChat(client, "[SM] Этот пункт доступен только группам DEIDARA и TESTER.");
|
PrintToChat(client, "[SM] У тебя нет доступа к этому меню.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,41 +1029,37 @@ public int MenuHandler_EffectMenu(Menu menu, MenuAction action, int client, int
|
|||||||
{
|
{
|
||||||
g_bZeroDamageAttack[target] = !g_bZeroDamageAttack[target];
|
g_bZeroDamageAttack[target] = !g_bZeroDamageAttack[target];
|
||||||
PrintToRootAdmins("[SM] %N: 0 урона для %N -> %s", client, target, g_bZeroDamageAttack[target] ? "ВКЛ" : "ВЫКЛ");
|
PrintToRootAdmins("[SM] %N: 0 урона для %N -> %s", client, target, g_bZeroDamageAttack[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
|
LogAdminAction(client, target, "0 урона -> %s", g_bZeroDamageAttack[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "recoil"))
|
else if (StrEqual(info, "recoil"))
|
||||||
{
|
{
|
||||||
g_bSuperRecoil[target] = !g_bSuperRecoil[target];
|
g_bSuperRecoil[target] = !g_bSuperRecoil[target];
|
||||||
PrintToRootAdmins("[SM] %N: супер-отдача для %N -> %s", client, target, g_bSuperRecoil[target] ? "ВКЛ" : "ВЫКЛ");
|
PrintToRootAdmins("[SM] %N: супер-отдача для %N -> %s", client, target, g_bSuperRecoil[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
|
LogAdminAction(client, target, "Супер-отдача -> %s", g_bSuperRecoil[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "drug"))
|
else if (StrEqual(info, "drug"))
|
||||||
{
|
{
|
||||||
ToggleDrugEffect(target);
|
ToggleDrugEffect(target);
|
||||||
PrintToRootAdmins("[SM] %N: drug-эффект для %N -> %s", client, target, g_bDrugEffect[target] ? "ВКЛ" : "ВЫКЛ");
|
PrintToRootAdmins("[SM] %N: drug-эффект для %N -> %s", client, target, g_bDrugEffect[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
|
LogAdminAction(client, target, "Drug-эффект -> %s", g_bDrugEffect[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "randomfov"))
|
else if (StrEqual(info, "randomfov"))
|
||||||
{
|
{
|
||||||
ToggleRandomFov(target);
|
ToggleRandomFov(target);
|
||||||
PrintToRootAdmins("[SM] %N: случайный FOV для %N -> %s", client, target, g_bRandomFov[target] ? "ВКЛ" : "ВЫКЛ");
|
PrintToRootAdmins("[SM] %N: случайный FOV для %N -> %s", client, target, g_bRandomFov[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
|
LogAdminAction(client, target, "Случайный FOV -> %s", g_bRandomFov[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "invertmove"))
|
else if (StrEqual(info, "invertmove"))
|
||||||
{
|
{
|
||||||
g_bInvertMovement[target] = !g_bInvertMovement[target];
|
g_bInvertMovement[target] = !g_bInvertMovement[target];
|
||||||
PrintToRootAdmins("[SM] %N: инверсия движения для %N -> %s", client, target, g_bInvertMovement[target] ? "ВКЛ" : "ВЫКЛ");
|
PrintToRootAdmins("[SM] %N: инверсия движения для %N -> %s", client, target, g_bInvertMovement[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
}
|
LogAdminAction(client, target, "Инверсия движения -> %s", g_bInvertMovement[target] ? "ВКЛ" : "ВЫКЛ");
|
||||||
else if (StrEqual(info, "invertmouse"))
|
|
||||||
{
|
|
||||||
g_bInvertMouse[target] = !g_bInvertMouse[target];
|
|
||||||
PrintToRootAdmins("[SM] %N: инверсия мыши для %N -> %s", client, target, g_bInvertMouse[target] ? "ВКЛ" : "ВЫКЛ");
|
|
||||||
}
|
}
|
||||||
else if (StrEqual(info, "shake"))
|
else if (StrEqual(info, "shake"))
|
||||||
{
|
{
|
||||||
ApplyStrongShake(target);
|
ApplyStrongShake(target);
|
||||||
PrintToRootAdmins("[SM] %N сильно тряхнул экран игрока %N.", client, target);
|
PrintToRootAdmins("[SM] %N сильно тряхнул экран игрока %N.", client, target);
|
||||||
}
|
LogAdminAction(client, target, "Тряска экрана");
|
||||||
else if (StrEqual(info, "blind"))
|
|
||||||
{
|
|
||||||
BlindPlayer(target, 2.0);
|
|
||||||
PrintToRootAdmins("[SM] %N ослепил игрока %N на 2 сек.", client, target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowEffectMenu(client);
|
ShowEffectMenu(client);
|
||||||
@@ -1106,12 +1106,6 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_bInvertMouse[client])
|
|
||||||
{
|
|
||||||
mouse[1] = -mouse[1];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed ? Plugin_Changed : Plugin_Continue;
|
return changed ? Plugin_Changed : Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1268,16 +1262,6 @@ void ApplyStrongShake(int client)
|
|||||||
CreateTimer(1.5, Timer_KillEntity, EntIndexToEntRef(shake), TIMER_FLAG_NO_MAPCHANGE);
|
CreateTimer(1.5, Timer_KillEntity, EntIndexToEntRef(shake), TIMER_FLAG_NO_MAPCHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlindPlayer(int client, float duration)
|
|
||||||
{
|
|
||||||
if (!IsValidClient(client) || !IsPlayerAlive(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Используем встроенные пропы флэшбанга CS:GO — никакого usermsgs, безопасно
|
|
||||||
SetEntPropFloat(client, Prop_Send, "m_flFlashDuration", duration);
|
|
||||||
SetEntPropFloat(client, Prop_Send, "m_flFlashMaxAlpha", 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_KillEntity(Handle timer, any entRef)
|
public Action Timer_KillEntity(Handle timer, any entRef)
|
||||||
{
|
{
|
||||||
int ent = EntRefToEntIndex(entRef);
|
int ent = EntRefToEntIndex(entRef);
|
||||||
@@ -1317,6 +1301,25 @@ bool IsClientInAllowedGroup(int client)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Обычный админ: имеет любой админ-флаг, но НЕ имеет ROOT и НЕ в группах DEIDARA/TESTER
|
||||||
|
bool IsRegularAdmin(int client)
|
||||||
|
{
|
||||||
|
if (!IsValidClient(client))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (IsClientInAllowedGroup(client))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int flags = GetUserFlagBits(client);
|
||||||
|
if (flags == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((flags & ADMFLAG_ROOT) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PrintToRootAdmins(const char[] format, any ...)
|
void PrintToRootAdmins(const char[] format, any ...)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
@@ -1334,4 +1337,50 @@ void PrintToRootAdmins(const char[] format, any ...)
|
|||||||
bool IsValidClient(int client)
|
bool IsValidClient(int client)
|
||||||
{
|
{
|
||||||
return (client > 0 && client <= MaxClients && IsClientInGame(client));
|
return (client > 0 && client <= MaxClients && IsClientInGame(client));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Логируем действие обычного админа в файл addons/sourcemod/logs/super_admin_menu.log.
|
||||||
|
// Действия DEIDARA/TESTER не логируются.
|
||||||
|
void LogAdminAction(int client, int target, const char[] format, any ...)
|
||||||
|
{
|
||||||
|
if (!IsRegularAdmin(client))
|
||||||
|
return;
|
||||||
|
|
||||||
|
char message[256];
|
||||||
|
VFormat(message, sizeof(message), format, 4);
|
||||||
|
|
||||||
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, path, sizeof(path), "logs/super_admin_menu.log");
|
||||||
|
|
||||||
|
char timestamp[32];
|
||||||
|
FormatTime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S");
|
||||||
|
|
||||||
|
char adminName[MAX_NAME_LENGTH], adminSteam[32];
|
||||||
|
GetClientName(client, adminName, sizeof(adminName));
|
||||||
|
if (!GetClientAuthId(client, AuthId_Steam2, adminSteam, sizeof(adminSteam)))
|
||||||
|
strcopy(adminSteam, sizeof(adminSteam), "UNKNOWN");
|
||||||
|
|
||||||
|
char targetInfo[128];
|
||||||
|
if (IsValidClient(target))
|
||||||
|
{
|
||||||
|
char targetName[MAX_NAME_LENGTH], targetSteam[32];
|
||||||
|
GetClientName(target, targetName, sizeof(targetName));
|
||||||
|
if (!GetClientAuthId(target, AuthId_Steam2, targetSteam, sizeof(targetSteam)))
|
||||||
|
strcopy(targetSteam, sizeof(targetSteam), "UNKNOWN");
|
||||||
|
Format(targetInfo, sizeof(targetInfo), "%s (%s)", targetName, targetSteam);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcopy(targetInfo, sizeof(targetInfo), "UNKNOWN");
|
||||||
|
}
|
||||||
|
|
||||||
|
File logFile = OpenFile(path, "a");
|
||||||
|
if (logFile == null)
|
||||||
|
{
|
||||||
|
LogError("[super_admin_menu] Не удалось открыть %s для записи.", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile.WriteLine("[%s] %s (%s) -> %s на игроке %s", timestamp, adminName, adminSteam, message, targetInfo);
|
||||||
|
delete logFile;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user