Русское сообщество по скриптингу

Добавить возможность наказывать VIP-игроков

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы только с поиском исполнителя или заказчика.

Правила при создании новой темы:
1. При вставке кода плагина необходимо использовать тег [code=php].
2. Любые изображения должны быть загружены, как вложения к вашему сообщению.
3. При описании проблемы или запросе на помощь в редактировании плагина обязательно выкладывайте исходник sma плагина.

Добавить возможность наказывать VIP-игроков

Сообщение Selpsan » 11 дек 2016, 11:38

Приветствую.

[amx_gag] Необходимо доработать возможность простым администраторам ("d") глушить любых игроков за исключением самого себя, главного администратора ("l"), простых администраторов ("d"). В меню всех иммунитированных игроков помечать с желтой звездочкой возле никнейма (в конце), себя соответственно видеть с красной звездочкой. Главный администратор в свою очередь имеет возможность заглушить всех без исключения (включая самого себя). Конструкция со звездочками та же. Не за спасибо, если кто возьмется. )

Код: Выделить всё
/*
    Версии: 
        * 1.0 Beta 1 - 8. Написание плагина и исправления ошибок
        * 1.0 Beta 9. Фикс гага навсегда
        * 1.0 Beta 10. Полировка кода
        * 1.0 Beta 11. Добавлен /mute
        * 1.1. Добавлен "словарь". Выход из беты
        * 1.2. Добавлен VoiceTranscoder API for GAG function's
        * 1.3. Фикс менюшки в /mute
        * 1.4. Фикс блокировки голосового чата
        
        * 1.0 Beta X. //#define MYSQL    // Поддержка MySQL | Не актуально. Так сказать это в планах.
*/

#include <amxmodx>
#include <gmf_directory>

//#define USE_API_VTC
/* 
    Раскомментируйте, если используете VTC версии не ниже 2.0RC1 (требуется модуль VoiceTranscoderApiProvider)
    Несмотря на доп модуль, это работает намного быстрее, нежели через Fakemeta
    Работает только для функции Gag. Надеюсь, простотема допилит.
*/

#define SORRY                // Разрешить команду /sorry для извинения игроков
#define MUTEMENU            // Поддержка команды /mute
#define GAG_ACCESS    ADMIN_BAN     // Доступ к функциям гага
#define SORRYTIME     60        // Как часто можно пользоваться командой /sorry. Время в секундах
#define PREFIX        "*"     // Префикс в чате
#define SUPERADMIN            // Админ с флагом L(изменить можно на 281 строке) может гагать других админов с иммунитетом

new g_BlockTimes[] =     // Время блокировки в минутах
{
    30,
    60,
    180,
    360,
    720,
    1440,
    10080
}

new g_AllowCommands[][] = // Разрешенные команды
{
    "/me",
    "/top15",
    "/rank",
    "/hp",
    "/rtv",
    "/top",
    "/rs",
    "rtv"
}

/* Словарь плагина */
#define MSG_SORRY_FLOOD             "^4%s ^1Повторно извиниться можно через %d секунд(у, ы)"
#define MSG_SORRY_ADMIN             "^4%s ^1Игрок %s извинился и просит снять заглушку"
// #define MSG_CHAT_IS_BLOCKED         "^4%s ^1Вы заглушены"
#define MSG_BLOCK_EXPIRED_TIME        "^4%s ^1До снятия заглушки осталось %d минут(у, ы)"
#define MSG_BLOCK_EXPIRED             "^4%s ^1Время заглушки истекло. Подождите обновления информации"
#define MSG_SAY_SORRY                 "^4%s ^1Чтобы извиниться, напишите в чат /sorry"
#define MSG_CHAT_SORRY                 "^4%s ^1Ваше извинение было отправлено"
#define MSG_CHAT_UNBLOCK_ALL         "^4%s ^1Администратор %s снял заглушку с игрока %s"
#define MSG_CHAT_UNBLOCK_PL         "^4%s ^1Администратор %s снял с Вас заглушку"
#define MSG_CHAT_BLOCK_ALL             "^4%s ^1Администратор %s заглушил %s %s"
#define MSG_CHAT_BLOCK_PL             "^4%s ^1Администратор %s заглушил Вас %s"
#define MSG_MUTE_ALL_PLAYERS         "^4%s ^1Вы заглушили всех игроков" 
#define MSG_UNMUTE_ALL_PLAYERS         "^4%s ^1Вы сняли заглушку со всех игроков" 
#define MSG_UNMUTE_PLAYER             "^4%s ^1Вы сняли заглушку с игрока %s"
#define MSG_MUTE_PLAYER             "^4%s ^1Вы заглушили игрока %s"

/* Технические данные */
#if defined USE_API_VTC
    #include <VoiceTranscoderAPI>
#endif
#if defined MUTEMENU || !defined USE_API_VTC
    #include <fakemeta>
#endif
#define STORAGE     "addons/amxmodx/data/amx_gag.dat"
#define MAX_ITEMS    1000

#define    GetBit(%1,%2)    (%1 & (1 << (%2 & 31)))
#define    SetBit(%1,%2)    %1 |= (1 << (%2 & 31))
#define    ResetBit(%1,%2)    %1 &= ~(1 << (%2 & 31))
new g_bitBlockChats;

enum _:DATA
{
    IP[16],
    STEAMID[25],
    BLOCKTIME
};
new g_aLoadedData[33][DATA];

new Trie:g_tAllowCmds;

new Array:g_aUsersBlocked;
new g_arrData[DATA];

static iFloodTime[33], systime;

const PATH_STRLEN = 96;
new g_LogsDir[PATH_STRLEN];

new pl[32], pnum;
#if defined MUTEMENU
new g_iMutePlayer[33][33];
#endif

public plugin_init()
{
#if defined USE_API_VTC
    #define VERSION "1.4.2[VTC Api]"
#else
    #define VERSION "1.4.2"
#endif
    register_plugin("Advanced Gag", VERSION, "neygomon");
    //register_cvar("adv_gag", VERSION, FCVAR_SERVER | FCVAR_SPONLY);
#if defined MUTEMENU || !defined USE_API_VTC
    register_forward(FM_Voice_SetClientListening, "FwdSetClientListening", false);
#endif
    register_clcmd("amx_gagmenu", "ClCmdGagMenu");
    register_menucmd(register_menuid("AmxGag Menu"), 1023, "GagMenuHandler");
#if defined MUTEMENU    
    register_clcmd("say /mute", "ClCmdMuteMenu");
    register_clcmd("say_team /mute", "ClCmdMuteMenu");
    register_menucmd(register_menuid("Mute Menu"), 1023, "MuteMenuHandler");
#endif    
    register_clcmd("say",         "SayChat");
    register_clcmd("say_team",     "SayChat");
    
    set_task
(60.0, "CheckBlockedUsers", .flags = "b");
}

public plugin_cfg()
{
    gmf_get_logsdir(g_LogsDir, charsmax(g_LogsDir));
    g_aUsersBlocked = ArrayCreate(DATA);
    
    new fp 
= fopen(STORAGE, "rt");
    if(fp)
    {
        new i, blocktime[15], buffer[128];
        new sys = get_systime();

        while(!feof(fp) && i < MAX_ITEMS)
        {
            fgets(fp, buffer, charsmax(buffer));
            trim(buffer);
            
            if
(buffer[0] == EOS || buffer[0] == ';') continue;
            
            if
(parse(buffer, 
                    g_arrData
[IP], charsmax(g_arrData[IP]), 
                    g_arrData
[STEAMID], charsmax(g_arrData[STEAMID]), 
                    blocktime
, charsmax(blocktime)
                )
            )
            {
                g_arrData[BLOCKTIME] = str_to_num(blocktime);
                if(!g_arrData[BLOCKTIME] || g_arrData[BLOCKTIME] > sys)
                {
                    ArrayPushArray(g_aUsersBlocked, g_arrData);
                    i++;
                }    
            
}
        }
        fclose(fp);
    }
    g_tAllowCmds = TrieCreate();
    for(new i; i < sizeof g_AllowCommands; i++)
        TrieSetCell(g_tAllowCmds, g_AllowCommands[i], i);
}

public client_putinserver(id)
{
    if(is_user_bot(id) || is_user_hltv(id)) return;

    get_user_ip(id, g_aLoadedData[id][IP], charsmax(g_aLoadedData[][IP]), 1);
    get_user_authid(id, g_aLoadedData[id][STEAMID], charsmax(g_aLoadedData[][STEAMID]));
    
    if
(IsUserBlocked(id, g_aLoadedData[id][IP], g_aLoadedData[id][STEAMID]) != -1) 
        SetBit
(g_bitBlockChats, id);
    else     ResetBit(g_bitBlockChats, id);
#if defined MUTEMENU    
    arrayset(g_iMutePlayer[id], 0, sizeof g_iMutePlayer[]);
#endif    
}

#if defined MUTEMENU || !defined USE_API_VTC
public FwdSetClientListening(iReciever, iSender)
{
    if(iSender != iReciever)
    {
#if !defined USE_API_VTC && defined MUTEMENU 
        if(GetBit(g_bitBlockChats, iSender) || g_iMutePlayer[iReciever][iSender])
#endif
#if defined MUTEMENU && defined USE_API_VTC
        if(g_iMutePlayer[iReciever][iSender])
#endif    
        {    
            engfunc
(EngFunc_SetClientListening, iReciever, iSender, false);
            forward_return(FMV_CELL, false);
            return FMRES_SUPERCEDE;
        }    
    
}
    return FMRES_IGNORED;
}
#endif

public SayChat(id)
{
    if(!GetBit(g_bitBlockChats, id)) 
        return PLUGIN_CONTINUE
;

    static sMessage[128]; 
    read_args
(sMessage, charsmax(sMessage));
    remove_quotes(sMessage);
        
    if
(TrieKeyExists(g_tAllowCmds, sMessage))
        return PLUGIN_CONTINUE;
#if defined SORRY            
    else if(!strcmp(sMessage, "/sorry"))
    {
        //static iFloodTime[33], systime;
        if(iFloodTime[id] > (systime = get_systime()))
            ChatColor(id, 0, MSG_SORRY_FLOOD, PREFIX, iFloodTime[id] - systime);
        else
        
{
            ChatColor(id, 0, MSG_CHAT_SORRY, PREFIX);
            static sName[32]; get_user_name(id, sName, charsmax(sName));
            get_players(pl, pnum, "ch");
            for(new i; i < pnum; i++)
            {
                if(get_user_flags(pl[i]) & GAG_ACCESS)
                    ChatColor(pl[i], 0, MSG_SORRY_ADMIN, PREFIX, sName);
            }
            iFloodTime[id] = systime + SORRYTIME;
        }
    }
#endif        
    else
    
{
        static sName[32], ost; 
        get_user_name
(id, sName, charsmax(sName));
        // ChatColor(id, 0, MSG_CHAT_IS_BLOCKED, PREFIX, sName);
        if(g_aLoadedData[id][BLOCKTIME])
        {
            if((ost = g_aLoadedData[id][BLOCKTIME] - get_systime()) / 60 > 0)
                ChatColor(id, 0, MSG_BLOCK_EXPIRED_TIME, PREFIX, ost / 60);
            else     ChatColor(id, 0, MSG_BLOCK_EXPIRED, PREFIX);
        }
        ChatColor(id, 0, MSG_SAY_SORRY, PREFIX);
    }
    return PLUGIN_HANDLED;
}

public CheckBlockedUsers()
{
    static i, sys; sys = get_systime();
    get_players(pl, pnum);
    
    for
(= 0; i < pnum; i++)
    {
        if(g_aLoadedData[pl[i]][BLOCKTIME] && sys > g_aLoadedData[pl[i]][BLOCKTIME])
            UserBlock(pl[i], 0);
    }
}

new g_iMenuSelectBlock[33], g_iMenuPos[33], players[33][32];
public ClCmdGagMenu(id)
{
    if(get_user_flags(id) & GAG_ACCESS)
    {
        g_iMenuSelectBlock[id] = g_iMenuPos[id] = 0;
        ShowGagMenu(id, 0);
    }    
    return PLUGIN_HANDLED
;
}

ShowGagMenu(id, iPos)
{
    new sMenu[512], iLen, iKeys, sName[32], a, start, end;
    get_players(players[id], pnum, "ch"); 
    
    start     
= iPos * 7; 
    end       
= start + 7;
    a    = 0;
    
    if
(start >= pnum) start = iPos = g_iMenuPos[id] = 0;
    if(end > pnum)      end = pnum;
    
    iLen 
= formatex(sMenu, charsmax(sMenu), "\yМеню заглушки\d (%d/%d)^n^n", iPos + 1, (pnum / 7 + ((pnum % 7) ? 1 : 0))), iKeys = MENU_KEY_0|MENU_KEY_8;
#if defined SUPERADMIN
    new bool:superadmin = bool:(get_user_flags(id) & ADMIN_RCON);
#endif    
    for(new i = start; i < end; i++)
    {    
        get_user_name
(players[id][i], sName, charsmax(sName));

        if(id == players[id][i])
            iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \d%s \r*^n", ++a, sName);
    #if defined SUPERADMIN
        else if(!superadmin && get_user_flags(players[id][i]) & ADMIN_IMMUNITY)
    #else
        else if(get_user_flags(players[id][i]) & ADMIN_IMMUNITY)
    #endif
            iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \d%s \y*^n", ++a, sName);
        else
        
{
            iKeys |= (<< a++);
            if(GetBit(g_bitBlockChats, players[id][i]))
                iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \w%s \r (снять заглушку)^n", a, sName);
            else
                iLen 
+= formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \w%s^n", a, sName);
        }    
    
}

    if(!g_BlockTimes[g_iMenuSelectBlock[id]]) 
        iLen 
+= formatex(sMenu[iLen], charsmax(sMenu) - iLen, "^n\y8. \wЗаглушить навсегда^n^n");
    else     iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "^n\y8. \wЗаглушить на %d мин^n^n", g_BlockTimes[g_iMenuSelectBlock[id]]);

    if(end != pnum)
    {
        formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y9. \wДалее^n\y0. \w%s", iPos ? "Назад" : "Выход");
        iKeys |= MENU_KEY_9;
    }
    else formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y0. \w%s", iPos ? "Назад" : "Выход");

    return show_menu(id, iKeys, sMenu, -1, "AmxGag Menu");
}

public GagMenuHandler(id, iKey)
{
    switch(iKey)
    {
        case 7:
        {
            if(++g_iMenuSelectBlock[id] > charsmax(g_BlockTimes)) 
                g_iMenuSelectBlock
[id] = 0;
            ShowGagMenu(id, g_iMenuPos[id]);
        }
        case 8: ShowGagMenu(id, ++g_iMenuPos[id]);
        case 9: if(g_iMenuPos[id]) ShowGagMenu(id, --g_iMenuPos[id]);
        default:
        {
            new sNameAdmin[32], sNamePlayer[32], AdmAuthId[24], UsrAuthId[24];
            new iPlayer = players[id][g_iMenuPos[id] * 7 + iKey];
            
            get_user_name
(id, sNameAdmin, charsmax(sNameAdmin));
            get_user_authid(id, AdmAuthId, charsmax(AdmAuthId));
            get_user_name(iPlayer, sNamePlayer, charsmax(sNamePlayer));
            get_user_authid(iPlayer, UsrAuthId, charsmax(UsrAuthId));
            
            if
(GetBit(g_bitBlockChats, iPlayer))
            {
                UserBlock(iPlayer, 0); 
                iFloodTime
[iPlayer] = 0;
                ChatColor(0, iPlayer, MSG_CHAT_UNBLOCK_ALL, PREFIX, sNameAdmin, sNamePlayer);
                ChatColor(iPlayer, 0, MSG_CHAT_UNBLOCK_PL, PREFIX, sNameAdmin, sNamePlayer);
            }
            else
            
{
                UserBlock(iPlayer, 1, g_BlockTimes[g_iMenuSelectBlock[id]]);
                
                new blocktimeinfo
[32];
                if(!g_BlockTimes[g_iMenuSelectBlock[id]])
                    formatex(blocktimeinfo, charsmax(blocktimeinfo), "навсегда");
                else    formatex(blocktimeinfo, charsmax(blocktimeinfo), "на %d минут(у, ы)", g_BlockTimes[g_iMenuSelectBlock[id]]);
                
                Logging
(g_LogsDir, "mute_", "^"%s<%d><%s><>^" mute %s ^"%s<%d><%s><>^" ", sNameAdmin, get_user_userid(id), AdmAuthId, blocktimeinfo, sNamePlayer, get_user_userid(iPlayer), UsrAuthId);
                
                ChatColor
(0, iPlayer, MSG_CHAT_BLOCK_ALL, PREFIX, sNameAdmin, sNamePlayer, blocktimeinfo);
                ChatColor(iPlayer, 0, MSG_CHAT_BLOCK_PL, PREFIX, sNameAdmin, /*sNamePlayer,*/ blocktimeinfo);
            }
            ShowGagMenu(id, g_iMenuPos[id]);
        }
    }
    return PLUGIN_HANDLED;
}

#if defined MUTEMENU
new g_iMuteList[33];
new plMute[33][32], plNum[33];
public ClCmdMuteMenu(id)
{
    g_iMuteList[id] = 0;
    ShowMuteMenu(id, 0);
    return PLUGIN_HANDLED;
}

ShowMuteMenu(id, iPos)
{
    new sMenu[512], iLen, iKeys, sName[32], a, start, end;
    get_players(plMute[id], plNum[id], "ch"); 
    
    start     
= iPos * 6; 
    end       
= start + 6;
    a    = 0;
    
    if
(start >= plNum[id]) start = iPos = g_iMuteList[id] = 0;
    if(end > plNum[id])      end = plNum[id];
    
    iLen 
= formatex(sMenu, charsmax(sMenu), "\yМеню заглушки \d(%d/%d)^n^n", iPos + 1, (plNum[id] / 6 + ((plNum[id] % 6) ? 1 : 0))), iKeys = MENU_KEY_0|MENU_KEY_7|MENU_KEY_8;

    for(new i = start; i < end; i++)
    {    
        get_user_name
(plMute[id][i], sName, charsmax(sName));

        if(id == plMute[id][i])
            iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \d%s \r*^n", ++a, sName);
        else
        
{
            iKeys |= (<< a++);
            iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y%d. \w%s%s^n", a, sName, g_iMutePlayer[id][plMute[id][i]] ? "\r (снять заглушку)" : "");
        }    
    
}

    iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "^n\y7. \wЗаглушить всех^n");
    iLen += formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y8. \wСнять заглушку со всех^n^n");

    if(end != plNum[id])
    {
        formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y9. \wДалее^n\y0. \w%s", iPos ? "Назад" : "Выход");
        iKeys |= MENU_KEY_9;
    }
    else formatex(sMenu[iLen], charsmax(sMenu) - iLen, "\y0. \w%s", iPos ? "Назад" : "Выход");

    return show_menu(id, iKeys, sMenu, -1, "Mute Menu");
}

public MuteMenuHandler(id, iKey)
{
    switch(iKey)
    {
        case 6:
        {
            for(new i; i < plNum[id]; i++)
                if(id != plMute[id][i])
                    g_iMutePlayer[id][plMute[id][i]] = 1;
            ChatColor(id, 0, MSG_MUTE_ALL_PLAYERS, PREFIX);
        }
        case 7:
        {
            for(new i; i < plNum[id]; i++)
                if(id != plMute[id][i])
                    g_iMutePlayer[id][plMute[id][i]] = 0;
            ChatColor(id, 0, MSG_UNMUTE_ALL_PLAYERS, PREFIX);
        }
        case 8: ShowMuteMenu(id, ++g_iMuteList[id]);
        case 9: if(g_iMuteList[id]) ShowMuteMenu(id, --g_iMuteList[id]);
        default:
        {
            new sNamePlayer[32];
            new iPlayer = plMute[id][g_iMuteList[id] * 6 + iKey];
            
            get_user_name
(iPlayer, sNamePlayer, charsmax(sNamePlayer));

            if(g_iMutePlayer[id][iPlayer])
                ChatColor(id, 0, MSG_UNMUTE_PLAYER, PREFIX, sNamePlayer);
            else     ChatColor(id, 0, MSG_MUTE_PLAYER, PREFIX, sNamePlayer);
            g_iMutePlayer[id][iPlayer] = g_iMutePlayer[id][iPlayer] ? 0 : 1;
            
            ShowMuteMenu
(id, g_iMuteList[id]);
        }
    }
    return PLUGIN_HANDLED;
}
#endif

UserBlock(id, block, btime = 0)
{
    switch(block)
    {
        case 0: IsUserBlocked(id, g_aLoadedData[id][IP], g_aLoadedData[id][STEAMID], 1);
        case 1:
        {
            g_aLoadedData[id][BLOCKTIME] = !btime ? 0 : get_systime() + btime * 60;

            ArrayPushArray(g_aUsersBlocked, g_aLoadedData[id]);
            SetBit(g_bitBlockChats, id);
        #if defined USE_API_VTC
            VTC_MuteClient(id);
        #endif
            client_cmd(id, "-voicerecord");     // типа отключаем войс, ога
        }
    }
}

IsUserBlocked(id, const Ip[], const SteamID[], UnBlock = 0)
{
    static i, ArraySizee, sys; sys = get_systime();
    
    ArraySizee 
= ArraySize(g_aUsersBlocked);
    for(= 0; i < ArraySizee; i++)
    {
        ArrayGetArray(g_aUsersBlocked, i, g_arrData);
        if(!strcmp(g_arrData[IP], Ip) || !strcmp(g_arrData[STEAMID], SteamID))
        {
            if(!UnBlock && (!g_arrData[BLOCKTIME] || g_arrData[BLOCKTIME] > sys))
            {
                g_aLoadedData[id][BLOCKTIME] = g_arrData[BLOCKTIME];
                return i;
            }
            else
            
{
                ArrayDeleteItem(g_aUsersBlocked, i);
                ResetBit(g_bitBlockChats, id);
            #if defined USE_API_VTC
                VTC_UnmuteClient(id);
            #endif
            }
            break;
        }
    }
    return -1;
}

public plugin_end()
{
    if(file_exists(STORAGE)) 
        unlink
(STORAGE);
    
    new ArraySizee
, fp = fopen(STORAGE, "w+");
    if(!fprintf(fp, "; File generated by AMX Gag. [ neygomon | https://neugomon.ru ]^n^n"))
    {
        new err[128]; formatex(err, charsmax(err), "Plugin not write file %s! Users not saved!", STORAGE);
        set_fail_state(err);
    }

    ArraySizee = ArraySize(g_aUsersBlocked);
    for(new i; i < ArraySizee; i++)
    {
        ArrayGetArray(g_aUsersBlocked, i, g_arrData);
        fprintf(fp, "^"%s^" ^"%s^" ^"%d^"^n", g_arrData[IP], g_arrData[STEAMID], g_arrData[BLOCKTIME]);
    }
    if(ArraySizee) log_amx("Successfully saved %d items in %s :)", ArraySizee, STORAGE);
    
    fclose
(fp);
    ArrayDestroy(g_aUsersBlocked);
    TrieDestroy(g_tAllowCmds);
}

stock ChatColor(id, id2, const szMessage[], any:...)
{
    static szMsg[190]; 
    vformat
(szMsg, charsmax(szMsg), szMessage, 4);
    if(id)
    {
        if(!is_user_connected(id)) return;
        pnum = 1;
        pl[0] = id;
    }
    else get_players(pl, pnum, "c");
    
    for
(new i; i < pnum; i++)
    {
        if(id2 == pl[i]) continue;
        
        message_begin
(MSG_ONE_UNRELIABLE, 76, .player = pl[i]);
        write_byte(pl[i]);
        write_string(szMsg);
        message_end();    
    
}
}

Logging(const LogsDir[], const FileName[] = "", const Message[], any:...) {
    new Msg[512], Time[32], File[PATH_STRLEN + 32], pFile;
    vformat(Msg, charsmax(Msg), Message, 4);
    get_time("%Y%m.log", Time, charsmax(Time));
    formatex(File, charsmax(File), "%s/%s%s", LogsDir, FileName, Time);
    pFile = fopen(File, "at");
    get_time("%Y/%m/%d - %H:%M:%S", Time, charsmax(Time));
    fprintf(pFile, "%s: %s^n", Time, Msg);
    fclose(pFile);

Тема перемещена в раздел "Биржа труда" // Subb98
Аватара пользователя
Selpsan
 
Сообщения: 10
Зарегистрирован: 14 мар 2016, 16:29
Благодарил (а): 4 раз.
Поблагодарили: 14 раз.
Языки программирования: Counter-Strike 1.6

Re: Добавить возможность наказывать VIP-игроков

Сообщение Fedcomp » 11 дек 2016, 12:20

Бюджет хоть укажите.
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4936
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 813 раз.
Поблагодарили: 1317 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript / rust


Вернуться в Поиск исполнителей / заказчиков

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3