0%
Обязательно ознакомьтесь с правилами форума!
Требуются люди в Команду форума для наполнения сайта ресурсами и полезным контентом. Писать в Telegram: @g_r_e_a_t_z_a_r_a_z_a
Чат для серверодержателей CS 1.6

Чат для серверодержателей Counter-Strike 1.6 а так же владельцев сайтов на движке GameCMS

Сообщество администраторов, разработчиков и владельцев серверов

GameCMS обсуждение Разработка плагинов Администрирование Опытные специалисты Безопасность и оптимизация
Рекламное место

Рекламное место свободно

Разместите свою рекламу прямо здесь!

Активная аудитория Высокая конверсия Доступная цена Эффективная реклама
GameCMS Achievements CS 1.6

CS 1.6 Amxx GameCMS Achievements CS 1.6 1.3

Плагин для учета Достижений ваших игроков.
C++:
/*
GameCMS_Achievs_Core
    1.3
    [+] forward OnAchivesComplete(iClient, idKey)
        *    Выполняется при открытии игроком очередного достижения
        *    @iClient        - индекс игрока
        *    @idKey            - уникальный номер достижения
        *    @noreturn
    [*] поправлен натив CmsCheckPlayerAchive
    [+] добавлено состояние ачивки eAchievedStatus:AchStatusJustCompleted - только что завершено

*/

#include <amxmodx>
#include <amxmisc>
#include <sqlx>
#include <gamecms5>
#include <gamecms_achievs>

new const PLUGIN[] = "GameCMS_Achievs_Core";
new const VERSION[] = "1.3";
new const AUTHOR[] = "zhorzh78";

new cpLogs, cpRegPlayerOnly, cpStorageDays, item_access;
new Trie:trhAchives, Trie:g_Players, Array:arhAchIndex;
new Handle:g_SqlX, AuthIDs[MAX_PLAYERS + 1][MAX_AUTHID_LENGTH/2], regUserId[MAX_PLAYERS + 1];
new const sqlCoreTable[] = "achievs";
new const sqlStatsTable[] = "achievs_stats";
new const sqlPlayersTable[] = "achievs_players";
new const gSoundNewLevel[] = "sound\events\task_complete.wav";
new QueryString[3500], utf_supp[MAX_STRING_LEN], lenS;
new g_fwd_StopAchCore, g_fwd_OnAchievesComplete, retFwd;
enum _:eAchivesData
{
    achUnicId,
    achName[MAX_STRING_LEN*2],
    achRusName[MAX_STRING_LEN*4],
    achValue,
    achAvatar[MAX_STRING_LEN]
}

enum _:eAchPlData
{
    userAch_id,
    userId,
    userValue,
    uFullValue,
    uCurrValue,
    uCollect,
    uCollDate[MAX_INT_LEN*2],
    bool:uModify
}

enum
{
    QueryLoadAchives = 1,
    QueryLoadPlayerAchives,
    QueryPlayerDisconnect
}

public OnAPIPluginStop()
{
    log_amx("Plugin paused. GameCMS_API is not loaded");
    ExecuteForward(g_fwd_StopAchCore, retFwd);
    pause("ad");
}

public OnAPIPluginLoaded(Handle:sqlTuple)
{
    if(!(g_SqlX = sqlTuple))
        return;

    #if AMXX_VERSION_NUM < 183
    utf_supp = "SET NAMES `utf8`; ";
    #else
    SQL_SetCharset(g_SqlX, "utf8");
    #endif

    LoadAchives(LOAD_ALL);

    if(get_playersnum()) //Если игроки зашли ДО соединения с БД
    {
        for(new i = 1; i <= MaxClients; i++)
        {
            if(!is_user_connected(i))
                continue;
            LoadAchives(i);
        }
    }
}

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);

    cpLogs = register_cvar("cms_achives_logs", "1");                //вкл/выкл логов
    cpRegPlayerOnly = register_cvar("cms_achives_reg_only", "1");    //записывать в БД: 1- только зарегистрированных на сайте, 0- всех
    cpStorageDays = register_cvar("cms_achives_storage_days", "170");    //сколько дней хранить неактивных игроков, дней. 0- не удалять
    register_clcmd("say /achievs", "CmdShowAchievesMenu");            //меню просмотра достижений игроков
    g_fwd_StopAchCore = CreateMultiForward("OnAchivesCoreStopped", ET_IGNORE);
    if(FindPluginFunction("OnAchievesCompleted"))
        g_fwd_OnAchievesComplete = CreateMultiForward("OnAchievesCompleted", ET_IGNORE, FP_CELL, FP_CELL);
}

public plugin_cfg()
{
    if(is_plugin_loaded("GameCMS_API") == INVALID_PLUGIN_ID)
    {
        ExecuteForward(g_fwd_StopAchCore, retFwd);
        log_amx("GameCMS_API is not loaded...");
        pause("ad");
    }

    #if AMXX_VERSION_NUM < 183
        MaxClients = get_maxplayers();
    #endif

    arhAchIndex = ArrayCreate();
    trhAchives = TrieCreate();
    g_Players = TrieCreate();
    get_cvar_string("cms_url", SiteUrl, charsmax(SiteUrl));
}

public client_authorized(id)
{
    FnTrieClear(id);
    regUserId[id] = 0;

    if(is_user_bot(id) || is_user_hltv(id))
        return;

    get_user_authid(id, AuthIDs[id], charsmax(AuthIDs[]));

    if(!get_pcvar_num(cpRegPlayerOnly))
        LoadAchives(id);
}

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

    if(get_pcvar_num(cpRegPlayerOnly))
        if(!regUserId[id])
            return;

    WriteAchieves(id);
}

public OnAPIMemberConnected(id)
{
    regUserId[id] = cmsapi_is_user_member(id);

    if(get_pcvar_num(cpRegPlayerOnly))
        LoadAchives(id);
}


public LoadAchives(id)
{
    new Data[2];
    new sqlData[300];
    switch(id)
    {
        case LOAD_ALL:
        {
            new iLen, iDays = get_pcvar_num(cpStorageDays);
            iLen += formatex(sqlData[iLen], charsmax(sqlData) - iLen, "SELECT *, cast(convert(`rus_name` using utf8) as binary) as `russ_name` FROM `%s`;", sqlCoreTable);
      
            if(iDays > 0)
                iLen += formatex(sqlData[iLen], charsmax(sqlData) - iLen, "DELETE FROM `%s` WHERE UNIX_TIMESTAMP(NOW()) > \
                UNIX_TIMESTAMP(DATE_ADD( FROM_UNIXTIME(`last_join`), INTERVAL '%d' DAY));", sqlPlayersTable, iDays);

            Data[0] = QueryLoadAchives;
        }
        default:
        {
            formatex(sqlData, charsmax(sqlData), "SELECT * FROM `%s` WHERE `user_auth` = '%s'", sqlStatsTable, AuthIDs[id]);
            Data[0] = QueryLoadPlayerAchives;
            Data[1] = id;
        }
    }
  
    SQL_ThreadQuery(g_SqlX, "QueryAchives_post", sqlData, Data, sizeof(Data));
}

public WriteAchieves(id)
{
    new Trie:tmpTrie;
    if(!TrieGetCell(g_Players, AuthIDs[id], tmpTrie))
        return;

    new prNum = ArraySize(arhAchIndex);

    new tmpAchives[eAchivesData], tmpKey;
    new tmpClAchives[eAchPlData];

    QueryString[0] = EOS, lenS = 0;

    static Data[2];
    Data[0] = QueryPlayerDisconnect, Data[1] = id;

    new timestamp = get_systime();
    lenS += formatex(QueryString[lenS], charsmax(QueryString)- lenS,
    "%s INSERT INTO `%s` SET `user_id`='%d',`user_auth`='%s',`last_join`='%d' ON DUPLICATE KEY UPDATE `user_id`='%d', `last_join`='%d';",
    utf_supp, sqlPlayersTable, regUserId[id], AuthIDs[id], timestamp, regUserId[id], timestamp);
  
    for(new i; i < prNum; i++)
    {
        tmpKey = ArrayGetCell(arhAchIndex, i);
        if(!TrieGetArray(tmpTrie, get_id_key(tmpKey), tmpClAchives, sizeof(tmpClAchives)))
            continue;

        if(!tmpClAchives[uModify])
            continue;
  
        TrieGetArray(trhAchives, get_id_key(tmpKey), tmpAchives, sizeof(tmpAchives))
        mysql_insert_string(tmpAchives[achName], charsmax(tmpAchives[achName]));

        new tmpUnic[34];
        formatex(tmpUnic, charsmax(tmpUnic), "%s+%d", AuthIDs[id], tmpKey)

        new QueryBody[350], len;
        if(!tmpClAchives[uFullValue])
            len = formatex(QueryBody, charsmax(QueryBody),
            "%s INSERT INTO `%s` SET `hash_id`=MD5('%s'),`user_id`='%d',`user_auth`='%s',`ach_id`='%d',`ach_name`='%s',`value` = '%d',\
            `curr_value`=`curr_value`+'%d',`ach_collect`='%d',`collect_date`='%s'",
            utf_supp, sqlStatsTable, tmpUnic, regUserId[id], AuthIDs[id], tmpKey, tmpAchives[achName], tmpAchives[achValue],
            tmpClAchives[uCurrValue], tmpClAchives[uCollect], tmpClAchives[uCollDate]);
        else
            len = formatex(QueryBody, charsmax(QueryBody),
            "%s UPDATE `%s` SET `ach_name`='%s',`value` = '%d', `curr_value`=`curr_value`+'%d',`ach_collect`='%d',`collect_date`='%s' WHERE `hash_id`=MD5('%s')",
            utf_supp, sqlStatsTable, tmpAchives[achName], tmpAchives[achValue], tmpClAchives[uCurrValue], tmpClAchives[uCollect], tmpClAchives[uCollDate], tmpUnic);
  
        if((lenS + len)  > charsmax(QueryString) - 10)
        {
            SQL_ThreadQuery(g_SqlX, "QueryAchives_post", QueryString, Data, sizeof(Data));
            QueryString[0]= EOS; lenS = 0;
        }

        lenS +=formatex(QueryString[lenS], charsmax(QueryString)- lenS, "%s; ", QueryBody);
    }

    if(get_pcvar_num(cpLogs) > 1)
        log_to_file("gcms_achives.log", "%s", QueryString);

    SQL_ThreadQuery(g_SqlX, "QueryAchives_post", QueryString, Data, sizeof(Data));
}

public QueryAchives_post(failstate, Handle:query, const error[], errornum, const postData[], DataSize)
{
    if(SQL_Error(error, errornum, failstate))
        return;

    new id = postData[1];
    switch(postData[0])
    {
        case QueryLoadAchives:    //load achives
        {
            new tmpAchives[eAchivesData], tmpId[7], iNum;
            while(SQL_MoreResults(query))
            {
                tmpAchives[achUnicId] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "unic_id"));
                num_to_str(tmpAchives[achUnicId], tmpId, charsmax(tmpId));
                if(TrieGetArray(trhAchives, tmpId, tmpAchives, sizeof(tmpAchives)))
                {
                    SQL_ReadResult(query, SQL_FieldNameToNum(query, "name"), tmpAchives[achName], charsmax(tmpAchives[achName]));
                    SQL_ReadResult(query, SQL_FieldNameToNum(query, "russ_name"), tmpAchives[achRusName], charsmax(tmpAchives[achRusName]));
                    SQL_ReadResult(query, SQL_FieldNameToNum(query, "ach_img"), tmpAchives[achAvatar], charsmax(tmpAchives[achAvatar]));
                    tmpAchives[achValue] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "value"));
          
                    mysql_escape_string(tmpAchives[achName], charsmax(tmpAchives[achName]));
                    mysql_escape_string(tmpAchives[achRusName], charsmax(tmpAchives[achRusName]));
              
                    #if AMXX_VERSION_NUM < 183
                        TrieDeleteKey(trhAchives, tmpId)
                    #endif

                    TrieSetArray(trhAchives, tmpId, tmpAchives, sizeof(tmpAchives));
                    iNum++;
                }
          
                SQL_NextRow(query);
            }
      
            if(get_pcvar_num(cpLogs))
                log_to_file("gcms_achives.log", "[Core] Loaded achives: %d from %d", iNum, SQL_NumResults(query));
        }
        case QueryLoadPlayerAchives:    //client putinserver
        {
            new Trie:tmpTrie = TrieCreate();
            TrieSetCell(g_Players, AuthIDs[id], tmpTrie);
      
            new tmpPlAchives[eAchPlData], tmpId[7];
            new nums = SQL_NumResults(query);
      
            if(!nums)
                return;

            while(SQL_MoreResults(query))
            {
                tmpPlAchives[userAch_id] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "ach_id"));
                num_to_str(tmpPlAchives[userAch_id], tmpId, charsmax(tmpId));
                if(TrieKeyExists(trhAchives, tmpId))
                {
                    tmpPlAchives[userId] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "user_id"));
                    tmpPlAchives[uFullValue] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "curr_value"));
                    tmpPlAchives[uCollect] = SQL_ReadResult(query, SQL_FieldNameToNum(query, "ach_collect"));

                    #if AMXX_VERSION_NUM < 183
                        TrieDeleteKey(tmpTrie, tmpId)
                    #endif
                    TrieSetArray(tmpTrie, tmpId, tmpPlAchives, sizeof(tmpPlAchives));
                }
          
                SQL_NextRow(query);
            }
      
            if(get_pcvar_num(cpLogs))
                log_to_file("gcms_achives.log", "[Core] Loaded achives for player [%s]: %d", AuthIDs[id], nums);
        }
        case QueryPlayerDisconnect:    FnTrieClear(id); //client disconnected
    }
}

FnTrieClear(id)
{
    new Trie:tmpTrie;
    if(TrieGetCell(g_Players, AuthIDs[id], tmpTrie))
        TrieDestroy(tmpTrie);

    TrieDeleteKey(g_Players, AuthIDs[id]);
}

public plugin_end()
    if(arhAchIndex)
        ArrayDestroy(arhAchIndex);


/*======== Меню игроков =========*/
public CmdShowAchievesMenu(id)
{
    new MenuCB = menu_makecallback("Menu_callback");
    new PlayersMenu = menu_create("\yДостижения игрока", "MuteMenu_Handler", 1);

    new pID, szpID[3], players[MAX_PLAYERS], pnum;
    get_players(players, pnum, "ch");

    for (new i; i < pnum; i++)
    {
        pID = players[i];

        num_to_str(pID, szpID, charsmax(szpID));
        menu_additem(PlayersMenu, "", szpID, 0, MenuCB);
    }

    menu_setprop(PlayersMenu, MPROP_BACKNAME, "\yНазад");
    menu_setprop(PlayersMenu, MPROP_NEXTNAME, "\yДалее");
    menu_setprop(PlayersMenu, MPROP_EXITNAME, "\yВыход");

    menu_display(id, PlayersMenu, 0);
    return PLUGIN_CONTINUE;
}

public Menu_callback(id, menu, item)
{
    new szData[3], callback, pID, szName[MAX_NAME_LENGTH], szFmtName[MAX_NAME_LENGTH*2];
    menu_item_getinfo(menu, item, item_access, szData, charsmax(szData),_,_, callback);

    pID = str_to_num(szData);
    get_user_name(pID, szName, charsmax(szName));

    szData[0] = cmsapi_is_user_member(pID);
    formatex(szFmtName, charsmax(szFmtName), "%s%s", szData[0] ? "\y" : "\r", szName);
          
    menu_item_setname(menu, item, szFmtName);
}

public MuteMenu_Handler(id, menu, item)
{
    if (item == MENU_EXIT)
    {
        menu_destroy(menu);
        return PLUGIN_HANDLED;
    }

    new item_callback, szData[7];
    menu_item_getinfo(menu, item, item_access, szData, charsmax(szData), _, _, item_callback);

    new pID = str_to_num(szData);

    new motd[MAX_STRING_LEN*4];
    formatex(motd, charsmax(motd), "http://%s/modules_extra/cms_achievs/index.php?auth=%s", SiteUrl, AuthIDs[pID]);
    show_motd(id, motd,"Достижения");

    new imenu, newmenu, menupage;
    player_menu_info(id, imenu, newmenu, menupage);

    menu_display(id, menu, menupage);
    return PLUGIN_HANDLED;
}


/*==============================================================*/
public plugin_natives()
{
    set_native_filter("native_filter");
    register_native("CmsActivateAchive", "native_CmsActivateAchive");
    register_native("CmsGetAchiveInfoByKey", "native_CmsGetAchiveInfoByKey");
    register_native("CmsGetAchivesCount", "native_CmsGetAchivesCount");
    register_native("CmsGetAchivesIndexes", "native_CmsGetAchivesIndexes");
    register_native("CmsCheckPlayerAchive", "native_CmsCheckPlayerAchive");
    register_native("CmsGetPlayerAchive", "native_CmsGetPlayerAchive");
}

public native_filter(const name[], index, trap)
    return !trap ? PLUGIN_HANDLED : PLUGIN_CONTINUE;


public native_CmsActivateAchive()
{
    new tmpAchives[eAchivesData];
    tmpAchives[achUnicId] = get_param(1);

    if(TrieSetArray(trhAchives, get_id_key(tmpAchives[achUnicId]), tmpAchives, sizeof(tmpAchives)))
        if(ArrayPushCell(arhAchIndex, tmpAchives[achUnicId]))
            return 1;

    return 0;
}

/**
*    Получение данных о достижении по его уникальному номеру
*
*    @idKey        - уникальный номер достижения
*    @RusName[]    - название достижения на русском
*    @nameLen    - размер буфера для записи названия
*    @Avatar[]    - название (имя файла) картинки (аватара)
*    @avaLen     - размер буфера для записи названия аватара
*    @return        Возвратит количество действий, необходимое для открытия достижения
*
native CmsGetAchiveInfoByKey(idKey, RusName[], nameLen, Avatar[], avaLen)
*/

public native_CmsGetAchiveInfoByKey()
{
    new itemNum = get_param(1);
    if(!itemNum)
        return 0;

    new tmpAchives[eAchivesData]
    if(TrieGetArray(trhAchives, get_id_key(itemNum), tmpAchives, sizeof(tmpAchives)))
    {
        set_string(2, tmpAchives[achRusName], get_param(3));
        set_string(4, tmpAchives[achAvatar], get_param(5));
        return tmpAchives[achValue];
    }

    return 0;
}

public native_CmsGetAchivesCount()
    return ArraySize(arhAchIndex);

public native_CmsGetAchivesIndexes()
{
    new nHandle[MAX_INT_LEN];
    formatex(nHandle, charsmax(nHandle), "%d", arhAchIndex);

    return str_to_num(nHandle);
}

public native_CmsCheckPlayerAchive()
{
    new id = get_param(1);
    new achKey[MAX_INT_LEN], status = AchStatusNone;
    new iAchKey = get_param(2);
    num_to_str(iAchKey, achKey, charsmax(achKey));

    if(!achKey[0] || !id)
        return status;

    new Trie:tmpTrie;
    if(!TrieGetCell(g_Players, AuthIDs[id], tmpTrie))
        return status;

    new tmpAchives[eAchivesData]
    if(!TrieGetArray(trhAchives, achKey, tmpAchives, sizeof(tmpAchives)))
        return status;

    new tmpClAchives[eAchPlData];
    if(TrieGetArray(tmpTrie, achKey, tmpClAchives, sizeof(tmpClAchives)))
    {
        if(tmpClAchives[uCollect])
        {
            return AchStatusCompleted;
        }
    }

    new val = get_param(3);
    tmpClAchives[uCurrValue] += val ? val : 1;

    if(tmpClAchives[uFullValue] + tmpClAchives[uCurrValue] >= tmpAchives[achValue])
    {
        tmpClAchives[uCollect] = 1;
        format_time(tmpClAchives[uCollDate], charsmax(tmpClAchives[uCollDate]), "%Y-%m-%d %H:%M:%S");
        status = AchStatusJustCompleted;

        if(!bool:get_param(4))
            FnOnAchivesComplete(id, tmpAchives[achUnicId], tmpAchives[achRusName], tmpAchives[achAvatar]);
  
        if(get_pcvar_num(cpLogs))
            log_to_file("gcms_achives.log", "Игрок %s открыл достижение %s", AuthIDs[id], tmpAchives[achRusName]);

        if(g_fwd_OnAchievesComplete)
            ExecuteForward(g_fwd_OnAchievesComplete, retFwd, id, iAchKey);
    }
    else
        status = AchStatusInProgress;
  
    tmpClAchives[uModify] = true;
  
    #if AMXX_VERSION_NUM < 183
        TrieDeleteKey(tmpTrie, achKey);
    #endif

    TrieSetArray(tmpTrie, achKey, tmpClAchives, sizeof(tmpClAchives));
    return status;
}

//native CmsGetkPlayerAchive(plId, achID, &currValue = 0, &maxValue = 0);    //проверка ачивки
public native_CmsGetPlayerAchive()
{
    new id = get_param(1);
    new achKey[MAX_INT_LEN], status = AchStatusNone;
    num_to_str(get_param(2), achKey, charsmax(achKey));

    if(!achKey[0] || !id)
        return status;

    new Trie:tmpTrie;
    if(!TrieGetCell(g_Players, AuthIDs[id], tmpTrie))
        return status;

    new tmpAchives[eAchivesData];
    if(!TrieGetArray(trhAchives, achKey, tmpAchives, sizeof(tmpAchives)))
        return status;

    new tmpClAchives[eAchPlData];
    if(TrieGetArray(tmpTrie, achKey, tmpClAchives, sizeof(tmpClAchives)))
    {
        set_param_byref(3, (tmpClAchives[uFullValue] + tmpClAchives[uCurrValue]));
        set_param_byref(4, tmpAchives[achValue]);

        if(tmpClAchives[uCollect])
            return AchStatusCompleted;
        return AchStatusInProgress;
    }

    return status;
}

public FnOnAchivesComplete(id, Key, RusName[], Avatar[])
{
    new Name[MAX_NAME_LENGTH];
    get_user_name(id, Name, charsmax(Name));

    client_cmd(0, "play %s", gSoundNewLevel);
    client_print_color(0, 0, "^1Игрок ^4%s ^1открыл достижение ^4%s", Name, RusName);

    if(get_pcvar_num(cpRegPlayerOnly))
        if(!regUserId[id])
            client_print_color(id, 0, "^4Достижения не сохраняются! ^1Для сохранения, зарегистрируйся на ^4%s", SiteUrl);

    client_print_color(id, 0, "^1Для просмотра достижений пиши ^4/achievs");
}
Верх Низ