Иконка ресурса

Плагин АМХХ 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");
}
Назад
Сверху