Код
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <orpheu>
#include <nvault>
#include <colorchat>
#pragma semicolon 1
#define get_bit(%1,%2) (%1 & (1 << (%2 & 31)))
#define set_bit(%1,%2) %1 |= (1 << (%2 & 31))
#define clr_bit(%1,%2) %1 &= ~(1 << (%2 & 31))
#define inv_bit(%1,%2) %1 ^= (1 << (%2 & 31))
#define is_client(%0) (0 < (%0) <= max_players)
#define is_connected(%0) get_bit(ingame, %0)
#define is_alive(%0) is_user_alive(%0)
#define is_valid_client(%0) (is_client(%0) && is_connected(%0))
#define is_observer(%0) pev(%0, pev_iuser1)
#define is_vip(%0) (user_flags[%0] & _VIP)
#define is_admin(%0) (user_flags[%0] & _ADMIN)
#define is_spectator(%0) (user_team[%0] == TEAM_SPECTATOR)
#define PC PLUGIN_CONTINUE
#define PH PLUGIN_HANDLED
#define PH_MAIN PLUGIN_HANDLED_MAIN
#define printf_chat client_print_color
#define is_said_slash_mute (said[0] == '/' && said[1] == 'm' && said[2] == 'u' && said[3] == 't' && said[4] == 'e')
const MAX_CLIENTS = 32;
const NAME_LEN = 32;
const MSG_LEN = 191;
const ITEM_LEN = 128;
const ALL = 0;
const LOAD = 1;
const SAVE = 0;
const AUTH_LEN = 34;
const IP_LEN = 16;
const POST = 1;
const PRE = 0;
const m_iMenu = 205;
const MENU_OFF = 0;
const _IMMUNITY = ADMIN_IMMUNITY; // flag a
const _ADMIN = ADMIN_BAN; // flag d
const _MAIN_ADMIN = ADMIN_RCON; // flag l
const _VIP = ADMIN_LEVEL_H; // flag t
const LOAD_FLAGS_TASKID = 344733;
const MAX_GAGTIME_AGO = -1800; //время в секундах после которого запись в gag.vault будет считаться устаревшей
new const Float: GAG_TIME[] = {300.0, 600.0, 1200.0, 1800.0, 2700.0, 3600.0}; //время бана в секундах, через запятую можно добавить еще
enum
{
TEAM_UNASSIGNED = 0,
TEAM_TERRORIST = 1,
TEAM_CT = 2,
TEAM_SPECTATOR = 3
}
enum menu_prop
{
BACKNAME = 0,
NEXTNAME,
EXITNAME
}
stock const MENU_PROP_LIST[menu_prop][] = {
"Назад",
"След.",
"Выход"
};
stock const PLAYER[] = "player";
stock const PL_LEAVED[] = "Игрок покинул сервер";
stock const CHAT_INFO_PREFIX[] = "^1[^4Информация^1]";
stock user_team [MAX_CLIENTS + 1],
user_flags [MAX_CLIENTS + 1],
user_name [MAX_CLIENTS + 1][NAME_LEN],
user_steamid[MAX_CLIENTS + 1][AUTH_LEN],
user_ip [MAX_CLIENTS + 1][IP_LEN];
stock item_name[128], item_info[2], item_status, said[MSG_LEN],
max_players, players_num, ingame, isAlive, gmsgTeamInfo,fpv_gag,
is_gagged_by_admin, is_gagged_chat, is_voice_team, is_voice_vip,
is_gagged[MAX_CLIENTS + 1], gag_data[MAX_CLIENTS + 1], hso_voice,
Float: ungag_time[MAX_CLIENTS + 1], Float: can_speak_after_death_time[MAX_CLIENTS + 1],
Float: auth_delay_load_flags, pcv_auth_delay_load_flags,
Float: block_voice_delay, pcv_can_speak_after_death_delay,
sv_alltalk, pcv_alltalk,
alive_listen_dead, pcv_alive_listen_dead,
dead_listen_dead, pcv_dead_listen_dead,
player_listen_enemy, pcv_player_listen_enemy,
admin_listen_mode, pcv_admin_listen_mode;
native gag_menu_display(id);
public plugin_natives()
{
register_native("gag_menu_display", "_gag_menu_display");
}
public plugin_init()
{
register_plugin ("New gag + mute", "1.0", "Eazy*");
register_srvcmd ("amx_reloadcvars", "load_cvars");
fpv_gag = nvault_open("gag");
if (fpv_gag == INVALID_HANDLE) {
set_fail_state("Error opening file: /cstrike/addons/amxmodx/data/vault/gag.vault");
}
register_clcmd ("+voiceteam", "clcmd_voiceteam_plus");
register_clcmd ("-voiceteam", "clcmd_voiceteam_minus");
register_clcmd ("+voicevip", "clcmd_voicevip_plus");
register_clcmd ("-voicevip", "clcmd_voicevip_minus");
register_clcmd ("say", "hook_say");
register_clcmd ("say_team", "hook_say");
register_clcmd ("amx_gagmenu", "clcmd_gagmenu");
RegisterHam (Ham_Spawn, PLAYER, "player_Spawn_Post", POST);
RegisterHam (Ham_Killed, PLAYER, "player_Killed_Post", POST);
hso_voice = CreateHudSyncObj();
gmsgTeamInfo = get_user_msgid ("TeamInfo");
register_message (gmsgTeamInfo, "msg_TeamInfo");
register_forward (FM_SetClientKeyValue, "fwd_FM_SetClientKeyValue", PRE);
OrpheuRegisterHook(OrpheuGetFunction("Voice_SetClientListening"), "Voice_SetClientListening");
max_players = get_maxplayers();
}
public plugin_cfg()
{
load_cvars();
}
public load_cvars()
{
static is_cvars_registered;
if (!is_cvars_registered) {
pcv_auth_delay_load_flags = register_cvar ("auth_delay_load_flags" , "0.0");
pcv_can_speak_after_death_delay = register_cvar ("can_speak_after_death_delay", "5.0");
pcv_alive_listen_dead = register_cvar ("alive_listen_dead" , "0");
pcv_dead_listen_dead = register_cvar ("dead_listen_dead" , "1");
pcv_player_listen_enemy = register_cvar ("player_listen_enemy" , "1");
pcv_admin_listen_mode = register_cvar ("admin_listen_mode" , "2");
pcv_alltalk = get_cvar_pointer ("sv_alltalk");
is_cvars_registered = 1;
}
server_exec();
auth_delay_load_flags = get_pcvar_float (pcv_auth_delay_load_flags);
block_voice_delay = get_pcvar_float (pcv_can_speak_after_death_delay);
alive_listen_dead = get_pcvar_num (pcv_alive_listen_dead);
dead_listen_dead = get_pcvar_num (pcv_dead_listen_dead);
player_listen_enemy = get_pcvar_num (pcv_player_listen_enemy);
admin_listen_mode = get_pcvar_num (pcv_admin_listen_mode);
sv_alltalk = get_pcvar_num(pcv_alltalk);
if (!sv_alltalk) {
set_pcvar_num(pcv_alltalk, 1);
}
}
public client_putinserver(id)
{
clr_bit(is_gagged_by_admin, id);
clr_bit(is_gagged_chat, id);
clr_bit(isAlive, id);
clr_bit(is_voice_team, id);
clr_bit(is_voice_vip, id);
is_gagged[id] = 0;
can_speak_after_death_time[id] = 0.0;
players_num++;
set_bit(ingame, id);
get_user_name (id, user_name[id], NAME_LEN - 1);
get_user_authid (id, user_steamid[id], AUTH_LEN - 1);
get_user_ip(id, user_ip[id], IP_LEN - 1, 1);
if (auth_delay_load_flags > 0.0) {
set_task(auth_delay_load_flags, "delayed_load_flags", id + LOAD_FLAGS_TASKID);
}
else {
delayed_load_flags(id + LOAD_FLAGS_TASKID);
}
}
public delayed_load_flags(id)
{
id -= LOAD_FLAGS_TASKID;
if (is_valid_client(id)) {
user_flags[id] = get_user_flags(id);
if (is_user_bot(id)) {
user_flags[id] |= _VIP;
}
gag_vault(id, LOAD);
}
}
public client_disconnect(id)
{
if (is_connected(id)) {
if (get_bit(is_gagged_by_admin, id)) {
gag_vault(id, SAVE);
}
players_num--;
}
clr_bit(ingame,id);
}
public hook_say(id)
{
read_args (said, charsmax(said));
remove_quotes (said);
if (said[0] == 0) {
return PH;
}
if (get_bit(is_gagged_chat, id)) {
if (get_gametime() <= ungag_time[id]) {
printf_chat(id, print_team_default, "%s Вам запрещено писать в чат. (Размут: Vk.com/made_in_bel)", CHAT_INFO_PREFIX);
return PH;
}
else {
clr_bit(is_gagged_chat, id);
}
}
if (is_said_slash_mute) {
return mute_menu (id);
}
return PC;
}
public player_Spawn_Post(id)
{
if (is_alive(id)) {
set_bit(isAlive, id);
}
}
public player_Killed_Post(id, attacker, should_gib)
{
clr_bit(isAlive, id);
can_speak_after_death_time[id] = get_gametime() + block_voice_delay;
}
public OrpheuHookReturn: Voice_SetClientListening (listener, talker, can_hear)
{
if (listener != talker && is_valid_client(listener) && is_valid_client(talker)) {
if (!CanPlayerHearPlayer(listener, talker)) {
OrpheuSetParam(3, 0);
}
}
}
bool: CanPlayerHearPlayer(listener, talker)
{
static listener_alive, talker_alive;
if (get_bit(is_gagged_by_admin, talker)) {
if (get_gametime() <= ungag_time[talker]) {
return false;
}
else {
clr_bit(is_gagged_by_admin, talker);
}
}
if (get_bit(is_gagged[listener], talker)) {
return false;
}
if (admin_listen_mode == 1) {
if (is_admin(listener) || is_admin(talker)) {
return true;
}
}
else if (admin_listen_mode == 2) {
if (is_admin(listener) && is_spectator(listener)) {
return true;
}
if (is_admin(talker) && is_spectator(talker)) {
return true;
}
}
if (get_bit(is_voice_vip, talker) && is_vip(listener)) {
return true;
}
listener_alive = get_bit(isAlive, listener);
talker_alive = get_bit(isAlive, talker);
if (user_team[listener] != user_team[talker]) {
if (!player_listen_enemy && dead_listen_dead && !listener_alive && !talker_alive) {
return true;
}
if (user_team[listener] == TEAM_CT && user_team[talker] == TEAM_TERRORIST) {
return (player_listen_enemy && !get_bit(is_voice_team, talker));
}
if (user_team[listener] == TEAM_TERRORIST && user_team[talker] == TEAM_CT) {
return (player_listen_enemy && !get_bit(is_voice_team, talker));
}
}
if (is_observer(listener)) {
return true;
}
if (listener_alive) {
if (!talker_alive) {
return (alive_listen_dead || get_gametime() < can_speak_after_death_time[talker]);
}
}
else {
if (talker_alive) {
return true;
}
}
return listener_alive && talker_alive;
}
public clcmd_voiceteam_plus(id)
{
set_bit(is_voice_team, id);
client_cmd (id, "+voicerecord");
return PH;
}
public clcmd_voiceteam_minus(id)
{
clr_bit(is_voice_team, id);
client_cmd (id, "-voicerecord");
return PH;
}
public clcmd_voicevip_plus(id)
{
if (is_vip(id)) {
set_bit(is_voice_vip, id);
client_cmd (id, "+voicerecord");
}
return PH;
}
public clcmd_voicevip_minus(id)
{
if (is_vip(id)) {
clr_bit(is_voice_vip, id);
client_cmd (id, "-voicerecord");
}
return PH;
}
public msg_TeamInfo ()
{
static id, team_name_tmp[11];
id = get_msg_arg_int(1);
get_msg_arg_string(2, team_name_tmp, charsmax(team_name_tmp));
switch (team_name_tmp[0]) {
case 'T': user_team[id] = TEAM_TERRORIST;
case 'C': user_team[id] = TEAM_CT;
case 'S': user_team[id] = TEAM_SPECTATOR;
case 'U': user_team[id] = TEAM_UNASSIGNED;
}
}
public fwd_FM_SetClientKeyValue(id, infobuffer[256], key[32], value[32])
{
#define is_key_name (key[0] == 'n' && key[1] == 'a' && key[2] == 'm' && key[3] == 'e')
if (is_valid_client(id)) {
if (is_key_name && value[0]) {
copy(user_name[id], NAME_LEN - 1, value);
}
}
}
public clcmd_gagmenu(id)
{
return gag_menu(id);
}
public _gag_menu_display(plugin_id, argc)
{
return gag_menu(get_param(1));
}
gag_menu(id)
{
if (is_valid_client(id) && user_flags[id] & _ADMIN) {
new gag_menu_id = menu_create ("\yЗаткнуть игрока^n(только голосовой)","gag_menu_handler");
static gag_menu_callback_id;
if (!gag_menu_callback_id) {
gag_menu_callback_id = menu_makecallback ("gag_menu_callback");
}
menu_setprop (gag_menu_id, MPROP_BACKNAME, MENU_PROP_LIST[BACKNAME]);
menu_setprop (gag_menu_id, MPROP_NEXTNAME, MENU_PROP_LIST[NEXTNAME]);
menu_setprop (gag_menu_id, MPROP_EXITNAME, MENU_PROP_LIST[EXITNAME]);
new user2;
if (!is_alive(id)) {
user2 = pev(id, pev_iuser2);
if (user2 && is_alive(user2)) {
item_info[0] = user2;
menu_additem (gag_menu_id, user_name[user2], item_info, 0, gag_menu_callback_id);
}
}
for (new i = 1; i <= max_players; ++i){
if(is_connected(i) && i != user2){
item_info[0] = i;
menu_additem (gag_menu_id, user_name[i], item_info, 0, gag_menu_callback_id);
}
}
#if AMXX_VERSION_NUM < 183
set_pdata_int (id, m_iMenu, MENU_OFF);
#endif
menu_display (id, gag_menu_id);
}
return PH;
}
public gag_menu_callback (id, menu, item)
{
static access, callback, ITEM_STATUS, index;
ITEM_STATUS = ITEM_ENABLED;
menu_item_getinfo (menu, item, access, item_info, charsmax(item_info), item_name, charsmax(item_name), callback);
index = item_info[0];
if (id == index || !(user_flags[id] & _MAIN_ADMIN) && user_flags[index] & _IMMUNITY) {
formatex (item_name, charsmax(item_name), "%s \r*", user_name[index]);
ITEM_STATUS = ITEM_DISABLED;
}
else if (get_bit(is_gagged_by_admin, index)) {
formatex (item_name, charsmax(item_name), "%s \r[Заткнут]", user_name[index]);
ITEM_STATUS = ITEM_ENABLED;
}
else if (user_flags[index] & _VIP) {
ITEM_STATUS = (user_flags[id] & (_ADMIN | _MAIN_ADMIN)) ? ITEM_ENABLED : ITEM_DISABLED;
}
menu_item_setname (menu, item, item_name);
return ITEM_STATUS;
}
public gag_menu_handler (id, menu, item) //изменить
{
static access, callback, index;
if (item != MENU_EXIT) {
menu_item_getinfo (menu, item, access, item_info, charsmax(item_info), item_name, charsmax(item_name), callback);
index = gag_data[id] = item_info[0];
if (is_valid_client(index)) {
if (get_bit(is_gagged_by_admin, index)) {
ungag_time[index] = 0.0;
clr_bit(is_gagged_by_admin, index);
printf_chat(ALL, print_team_default, "^4*^1 Администратор ^3%s ^1снял молчанку с игрока ^3%s^1.", user_name[id], user_name[index]);
}
else {
gagtime_menu(id);
}
}
else {
printf_chat (id, print_team_default, PL_LEAVED);
}
}
menu_destroy(menu);
return PH;
}
gagtime_menu(id)
{
static gagtime_menu_id;
if (is_valid_client(id)) {
if (!gagtime_menu_id) {
gagtime_menu_id = menu_create ("\yВыберите время молчанки", "gagtime_menu_handler");
menu_setprop (gagtime_menu_id, MPROP_EXITNAME, MENU_PROP_LIST[EXITNAME]);
for (new i; i < sizeof GAG_TIME; ++i) {
formatex(item_name, charsmax(item_name), "%.0f минут", (GAG_TIME[i] / 60.0));
menu_additem (gagtime_menu_id, item_name);
}
}
#if AMXX_VERSION_NUM < 183
set_pdata_int (id, m_iMenu, MENU_OFF);
#endif
menu_display (id, gagtime_menu_id);
}
return PH;
}
public gagtime_menu_handler (id, menu, item)
{
if (item != MENU_EXIT) {
ungag_time[gag_data[id]] = get_gametime() + GAG_TIME[item];
set_bit(is_gagged_by_admin, gag_data[id]);
set_bit(is_gagged_chat, gag_data[id]);
printf_chat(ALL, print_team_default, "^4*^1 Администратор ^3%s^1 заткнул ^3%s^1 на^3 %.0f^1 минут.", user_name[id], user_name[gag_data[id]], (GAG_TIME[item] / 60.0));
}
return PH;
}
gag_vault(id, mode)
{
static Float: ctime, sys_time, ungag_systime, ungag_systime_str[11];
ctime = get_gametime();
sys_time = get_systime();
if (mode == LOAD) {
ungag_systime = nvault_get (fpv_gag, user_steamid[id]);
if (!ungag_systime) {
ungag_systime = nvault_get (fpv_gag, user_ip[id]);
}
if (ungag_systime > sys_time) {
set_bit(is_gagged_by_admin, id);
set_bit(is_gagged_chat, id);
ungag_time[id] = ctime + float(ungag_systime - sys_time);
}
}
else {
ungag_systime = floatround(ungag_time[id] - ctime) + sys_time;
if (ungag_systime > sys_time) {
num_to_str(ungag_systime, ungag_systime_str, charsmax(ungag_systime_str));
nvault_set (fpv_gag, user_steamid[id], ungag_systime_str);
nvault_set (fpv_gag, user_ip[id], ungag_systime_str);
}
}
}
mute_menu (id)
{
if (is_valid_client(id)) {
if (players_num < 2) {
printf_chat (id, print_team_default, "%s На сервере менее 2-ух игроков!", CHAT_INFO_PREFIX);
return PH;
}
new mute_menu_id = menu_create ("\yЗаглушить игрока","mute_menu_handler");
static mute_menu_callback_id;
if (!mute_menu_callback_id) {
mute_menu_callback_id = menu_makecallback ("mute_menu_callback");
}
menu_setprop (mute_menu_id, MPROP_BACKNAME, MENU_PROP_LIST[BACKNAME]);
menu_setprop (mute_menu_id, MPROP_NEXTNAME, MENU_PROP_LIST[NEXTNAME]);
menu_setprop (mute_menu_id, MPROP_EXITNAME, MENU_PROP_LIST[EXITNAME]);
new user2;
if (!is_alive(id)) {
user2 = pev(id, pev_iuser2);
if (user2 && is_alive(user2)) {
item_info[0] = user2;
menu_additem (mute_menu_id, user_name[user2], item_info, 0, mute_menu_callback_id);
}
}
for (new i = 1; i <= max_players; ++i){
if(is_connected(i) && i != id && i != user2){
item_info[0] = i;
menu_additem (mute_menu_id, user_name[i], item_info, 0, mute_menu_callback_id);
}
}
#if AMXX_VERSION_NUM < 183
set_pdata_int (id, m_iMenu, MENU_OFF);
#endif
menu_display (id, mute_menu_id);
}
return PH;
}
public mute_menu_callback (id, menu, item)
{
static access, callback;
item_status = ITEM_ENABLED;
if (item == 0) {
if (is_gagged[id] == -1) {
copy (item_name, charsmax(item_name), "Заглушить всех \y[\rВкл\y]^n");
}
else {
copy (item_name, charsmax(item_name), "Заглушить всех \y[\rВыкл\y]^n");
}
}
else {
menu_item_getinfo (menu, item, access, item_info, charsmax(item_info), item_name, charsmax(item_name), callback);
if (get_bit(is_gagged[id], item_info[0])) {
formatex (item_name, charsmax(item_name), "%s \y[\r+\y]", user_name[item_info[0]]);
item_status = ITEM_ENABLED;
}
}
menu_item_setname (menu, item, item_name);
return item_status;
}
public mute_menu_handler (id, menu, item)
{
static need_announce, Float: ctime, Float: next_announce_time[MAX_CLIENTS + 1];
ctime = get_gametime();
need_announce = (ctime > next_announce_time[id]) ? 1 : 0;
if (item != MENU_EXIT) {
if (item == 0) {
if (is_gagged[id] == -1) {
is_gagged[id] = 0;
need_announce && printf_chat(ALL, print_team_default, "%s Игрок ^3%s^1 написал^3 /mute^1 (^4слышит всех^1)", CHAT_INFO_PREFIX, user_name[id]);
}
else {
is_gagged[id] = -1;
need_announce && printf_chat(ALL, print_team_default, "%s Игрок ^3%s^1 написал^3 /mute^1 (^4не слышит никого^1)", CHAT_INFO_PREFIX, user_name[id]);
}
}
else {
static access, callback;
menu_item_getinfo (menu, item, access, item_info, charsmax(item_info), item_name, charsmax(item_name), callback);
gag_data[id] = item_info[0];
if (is_connected(gag_data[id])) {
if (get_bit(is_gagged[id], gag_data[id])) {
clr_bit(is_gagged[id], gag_data[id]);
need_announce && printf_chat(ALL, print_team_default, "%s Игрок ^3%s^1 написал^3 /mute^1 (^4слышит %s^1)", CHAT_INFO_PREFIX, user_name[id], user_name[gag_data[id]]);
}
else {
set_bit(is_gagged[id], gag_data[id]);
need_announce && printf_chat(ALL, print_team_default, "%s Игрок ^3%s^1 написал^3 /mute^1 (^4не слышит %s^1)", CHAT_INFO_PREFIX, user_name[id], user_name[gag_data[id]]);
}
}
else {
printf_chat (id, print_team_default, PL_LEAVED);
}
}
menu_destroy(menu);
mute_menu (id);
}
else {
menu_destroy(menu);
}
next_announce_time[id] = ctime + 3.0;
return PH;
}
public plugin_end()
{
if (fpv_gag != INVALID_HANDLE) {
nvault_prune(fpv_gag, 0, get_systime(MAX_GAGTIME_AGO));
nvault_close(fpv_gag);
}
set_pcvar_num(pcv_alltalk, sv_alltalk);
}