#include <amxmodx>
#include <fakemeta>
#include <amxmisc>
#include <nvault>
#include <reapi>
#pragma semicolon 1
const INACTIVITY_DAYS = 7; // Удалять неактивных игроков через 'n' дней
const SECONDS_IN_DAY = 86400; // Количество секунд в одном дне
const Float:TIME_AFTER_DEATH = 5.0; // Время после смерти, через которое живые не услышат мертвого игрока
const VOICE_LIMIT = 1; // Лимит на одновременное использование микрофона
const AUTHID_STRLEN = 24;
const NAME_STRLEN = 32;
const MESSAGE_STRLEN = 512;
const TIME_STRLEN = 32;
const PATH_STRLEN = 64;
const ELLIPSES_ARG = 4;
const START_TIME = 0;
new g_iVaultID;
new g_iNumSpeakers;
new g_sLogsDir[PATH_STRLEN];
new bool:g_bAlive[MAX_PLAYERS + 1];
new bool:g_bCantHearDead[MAX_PLAYERS + 1];
new bool:g_bCantTalk[MAX_PLAYERS + 1];
public plugin_init() {
register_plugin("Voice Manager", "1.0", "Javekson");
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", .post = true);
RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed", .post = true);
RegisterHookChain(RG_CSGameRules_CanPlayerHearPlayer, "CSGameRules_CanPlayerHearPlayer", .post = false);
register_clcmd("say /vc", "ClCmdVoice");
}
public plugin_cfg() {
get_localinfo("amxx_logs", g_sLogsDir, charsmax(g_sLogsDir));
add(g_sLogsDir, charsmax(g_sLogsDir), "/voice_manager");
if(!dir_exists(g_sLogsDir)) mkdir(g_sLogsDir);
g_iVaultID = nvault_open("voice_manager");
nvault_prune(g_iVaultID, START_TIME, get_systime() - SECONDS_IN_DAY * INACTIVITY_DAYS);
}
public client_putinserver(id) {
new sAuthID[AUTHID_STRLEN];
get_user_authid(id, sAuthID, charsmax(sAuthID));
if((g_bCantHearDead[id] = bool:nvault_get(g_iVaultID, sAuthID))) {
nvault_touch(g_iVaultID, sAuthID);
}
}
public plugin_end() {
nvault_close(g_iVaultID);
}
public CBasePlayer_Spawn(id) {
g_bAlive[id] = true;
}
public CBasePlayer_Killed(id) {
set_task_ex(TIME_AFTER_DEATH, "task_AfterDeath", .flags = SetTask_Once);
}
public CSGameRules_CanPlayerHearPlayer(const iListener, const iSender) {
if(iSender != iListener) {
if(g_bCantTalk[iSender]) {
SetHookChainReturn(ATYPE_INTEGER, false);
return HC_BREAK;
}
if(g_bCantHearDead[iListener]) {
if(g_bAlive[iListener] && !g_bAlive[iSender]) {
SetHookChainReturn(ATYPE_INTEGER, false);
return HC_BREAK;
}
}
}
return HC_CONTINUE;
}
public VTC_OnClientStartSpeak(const id) {
if(VTC_IsClientMuted(id)) {
return PLUGIN_CONTINUE;
}
if(g_iNumSpeakers >= VOICE_LIMIT) {
g_bCantTalk[id] = true;
static aPlayersID[MAX_PLAYERS], iPlayersNum;
get_players_ex(aPlayersID, iPlayersNum, GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV);
static iListener, iSender; iSender = id;
for(new i; i < iPlayersNum; i++) {
iListener = aPlayersID[i];
if(iListener == id) continue;
engfunc(EngFunc_SetClientListening, iListener, iSender, false);
}
}
g_iNumSpeakers++;
return PLUGIN_CONTINUE;
}
public VTC_OnClientStopSpeak(const id) {
if(g_bCantTalk[id]) {
g_bCantTalk[id] = false;
}
g_iNumSpeakers--;
}
public ClCmdVoice(const id) {
new sAuthID[AUTHID_STRLEN], sName[NAME_STRLEN];
get_user_authid(id, sAuthID, charsmax(sAuthID));
get_user_name(id, sName, charsmax(sName));
if(g_bCantHearDead[id]) {
g_bCantHearDead[id] = false;
nvault_remove(g_iVaultID, sAuthID);
client_print_color(id, print_team_default, "^4* ^1[^4GMF^1] Теперь ^4Вы ^1слышите всех ^4игроков");
logging(g_sLogsDir, "voice_manager_", "^"%-32s %-32s Слышит всех игроков^"", sAuthID, sName);
return PLUGIN_CONTINUE;
}
g_bCantHearDead[id] = true;
nvault_set(g_iVaultID, sAuthID, "1");
client_print_color(id, print_team_default, "^4* ^1[^4GMF^1] Теперь ^4Вы ^1слышите только ^4живых игроков");
logging(g_sLogsDir, "voice_manager_", "^"%-32s %-32s Слышит только живых игроков^"", sAuthID, sName);
return PLUGIN_CONTINUE;
}
public task_AfterDeath(id) {
g_bAlive[id] = false;
}
stock logging(const sLogsDir[], const sFileName[], const sMessage[], any:...) {
new sFmtMsg[MESSAGE_STRLEN], sTime[TIME_STRLEN], sLogFile[PATH_STRLEN + 32], iFileID;
vformat(sFmtMsg, charsmax(sFmtMsg), sMessage, ELLIPSES_ARG);
get_time("%m.%Y.log", sTime, charsmax(sTime));
formatex(sLogFile, charsmax(sLogFile), "%s/%s%s", sLogsDir, sFileName, sTime);
iFileID = fopen(sLogFile, "at");
get_time("%d.%m.%Y - %H:%M:%S", sTime, charsmax(sTime));
fprintf(iFileID, "^"%s^" %s^n", sTime, sFmtMsg);
fclose(iFileID);
}