Динамический массив

Сообщения
94
Реакции
64
Помог
5 раз(а)
Ошибка
нет
ОС
Linux
Билд
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
Exe build: 13:12:29 Aug 29 2013 (6153)
ReGamedll
-
Список метамодулей
description      stat pend  file              vers      src  load  unlod
[ 1] SafeNameAndChat RUN - SafeNameAndChat. v1.1 ini ANY ANY
[ 2] dproto_EF RUN - dproto_i386.so v0.9.582 ini Start Never
[ 3] AMX Mod X RUN - amxmodx_mm_i386. v1.8.3-d ini Start ANY
[ 4] POD-Bot mm RUN - podbot_mm_i386.s v3.0B20a ini Chlvl ANY
[ 5] FakeMeta RUN - fakemeta_amxx_i3 v1.8.3-d pl3 ANY ANY
[ 6] MySQL RUN - mysql_amxx_i386. v1.8.3-d pl3 ANY ANY
[ 7] CStrike RUN - cstrike_amxx_i38 v1.8.3-d pl3 ANY ANY
7 plugins, 7 running
Список плагинов
name                    version     author            file             status   
[ 1] FreshBans 1.3.8b kanagava fresh_bans.amxx running
[ 2] Admin Loader 2.9 neygomon admin_loader.am running
[ 3] Admin Commands 1.8.3-dev+ AMXX Dev Team admincmd.amxx running
[ 4] Restrict Weapons 1.8.3-dev+ AMXX Dev Team restmenu.amxx running
[ 5] test test test test.amxx running
5 plugins, 5 running
Исходный код
#include <amxmodx>

enum _:PLAYER_DATA {
STEAMID[30],
KILLS,
KILLS_HS,
DEATHS,
ROUNDS
};

new g_arrStats[33][PLAYER_DATA];
new Array:arrStatsDiscPlayers;
new g_arrDiscData[PLAYER_DATA];

public plugin_init() {
register_plugin("test", "test", "test");
register_clcmd("say /test", "SayTest");
register_clcmd("say_team /test", "SayTest");
register_event("DeathMsg", "EventDeathMsg", "a", "1>0");
register_logevent("LogEventRoundStart", 2, "1=Round_Start");
}

public plugin_cfg() {
arrStatsDiscPlayers = ArrayCreate(PLAYER_DATA);
}

public client_putinserver(id) {
if(is_user_bot(id) || is_user_hltv(id)) {
return PLUGIN_HANDLED;
}
new bool:bFoundStat = false;
new i, aSize = ArraySize(arrStatsDiscPlayers);
new szSteamId[30];
get_user_authid(id, szSteamId, charsmax(szSteamId));
for(i = 0; i < aSize; i++) {
ArrayGetArray(arrStatsDiscPlayers, i, g_arrDiscData);
if(strcmp(g_arrDiscData[STEAMID], szSteamId) == 0) {
bFoundStat = true;
copy(g_arrStats[id][STEAMID], charsmax(g_arrStats[][STEAMID]), g_arrDiscData[STEAMID]);
g_arrStats[id][KILLS] = g_arrDiscData[KILLS];
g_arrStats[id][KILLS_HS] = g_arrDiscData[KILLS_HS];
g_arrStats[id][DEATHS] = g_arrDiscData[DEATHS];
g_arrStats[id][ROUNDS] = g_arrDiscData[ROUNDS];
ArrayDeleteItem(arrStatsDiscPlayers, i);
break;
}
}
if(!bFoundStat) {
arrayset(g_arrStats[id], 0, PLAYER_DATA);
get_user_authid(id, g_arrStats[id][STEAMID], charsmax(g_arrStats[][STEAMID]));
}
return PLUGIN_CONTINUE;
}

public client_disconnected(id) {
if(!is_user_bot(id) || !is_user_hltv(id)) {
ArrayPushArray(arrStatsDiscPlayers, g_arrStats[id]);
}
}

public SayTest(id) {
client_print(0, print_console, "array size = %d", ArraySize(arrStatsDiscPlayers));
for(new i = 0; i < ArraySize(arrStatsDiscPlayers); i++) {
client_print(id, print_console, "STEAMID: %s", g_arrStats[i][STEAMID]);
client_print(id, print_console, "KILLS: %d", g_arrStats[i][KILLS]);
client_print(id, print_console, "KILL_HS: %d", g_arrStats[i][KILLS_HS]);
client_print(id, print_console, "DEATHS: %d", g_arrStats[i][DEATHS]);
client_print(id, print_console, "ROUNDS: %d", g_arrStats[i][ROUNDS]);
client_print(id, print_console, "============================================");
}
client_print(id, print_chat, "Текущие: STEAMID: %s, KILLS: %d, KILL_HS: %d, DEATHS: %d, ROUNDS: %d",
g_arrStats[id][STEAMID],
g_arrStats[id][KILLS],
g_arrStats[id][KILLS_HS],
g_arrStats[id][DEATHS],
g_arrStats[id][ROUNDS]
);
}

public LogEventRoundStart() {
new iPlayers[MAX_PLAYERS], iCountPlayers, iPlayer;
get_players(iPlayers, iCountPlayers, "ch");
for(new i; i < iCountPlayers; i++) {
iPlayer = iPlayers[i];
g_arrStats[iPlayer][ROUNDS]++;
}
}

public EventDeathMsg() {
new killer = read_data(1);
new victim = read_data(2);
if(killer != victim) {
if(read_data(3) == HIT_HEAD) {
g_arrStats[killer][KILLS_HS]++;
}
g_arrStats[killer][KILLS]++;
}
g_arrStats[victim][DEATHS]++;
}

public plugin_end() {
ArrayDestroy(arrStatsDiscPlayers);
}
Проблема заключается в том, что мне надо при перезаходе на сервер возвращать статистику игроку обратно. Для этого я использую динамический массив, в который при дисконнекте записываю данные игрока. При заходе опять на сервер, данные с массива должны возвращаться по стимид, а уже после удалять эту запись с динамического массива. В моем случае данные возвращаются, но не удаляется запись с динамического массива и почему-то его размерность изначально не 0 а 1. Подскажите что я делаю не так, тестирую всё с ботами.
 
В этой теме было размещено решение! Перейти к решению.
Сообщения
1,176
Реакции
2,144
Помог
57 раз(а)
А зачем в данном случае использовать DynArray и гнать перебор по всем записям? Я могу ошибаться, но если вы храните данные по ключу, то логичнее использовать Trie
 
Сообщения
94
Реакции
64
Помог
5 раз(а)
BlackSignature, конечно спасибо за наводку, но мне надо точно знать с помощью чего я могу решить данный вопрос, так как потом мне надо будет всё это дело переносить в базу. а в массиве я думаю больше 20 элементов не будет храниться, так как это делается не для паблик сервера и игроки не так часто заходят и выходят, поэтому скорость работы и с помощью чего реализоваться не важно, главное чтобы работало.
 
Сообщения
1,176
Реакции
2,144
Помог
57 раз(а)
BlackSignature, конечно спасибо за наводку, но мне надо точно знать с помощью чего я могу решить данный вопрос, так как потом мне надо будет всё это дело переносить в базу. а в массиве я думаю больше 20 элементов не будет храниться, так как это делается не для паблик сервера и игроки не так часто заходят и выходят, поэтому скорость работы и с помощью чего реализоваться не важно, главное чтобы работало.
А что вы имели ввиду под размерностью? ArraySize? Если да, то каким образом вы её проверяли. Зайдя на сервер, т.е. через "say /test"?
Я опять же могу ошибаться, но мне помнится, что для форварда client_disconnected условие прохождения игроком putinserver не является обязательным. Т.е. если вы начали connect, произошёл drop > вызов client_disconnected и кода в нём, и затем уже вы заходите на сервер.

И если я прав, у вас при триггере disconnected про'push'атся данные, но если игрок не пройдёт putinserver, эти данные не удалятся. Т.е. теоретически могут появиться дубликаты с одним и тем же стимидом (в т.ч. числе вообще с пустым значением).
 
Сообщения
219
Реакции
183
Помог
3 раз(а)
Dager, Откройте ReGunGame. Там реализована система сохранения информации игрока после выхода. Всё что надо можно там найти.
 
Сообщения
94
Реакции
64
Помог
5 раз(а)
BlackSignature, вот это объяснение уже поинтересней будет так как я этого не знал, тогда вопрос как мне переделать этот код, чтобы этого не происходило? А проверял размерность тупо зайдя на сервер с пару ботами сразу писал через "say /test" и мне array size = 1 пишет, при этом никто не заходит и не выходит.
 
Сообщения
1,176
Реакции
2,144
Помог
57 раз(а)
Dager, ну например
Код:
new bool:g_bConnected[MAX_PLAYERS + 1];

public client_putinserver(id)
{
   g_bConnected[id] = true;
}

public client_disconnected(id)
{
   if(!g_bConnected[id]) return;

   // Здесь ваш код

   g_bConnected[id] = false;
}
Ботам/hltv в putinserver можно просто не выдавать g_bConnected. Это избавит от необходимости доп. проверок в disconnected.
 
Последнее редактирование:
Сообщения
94
Реакции
64
Помог
5 раз(а)
BlackSignature, переписал код вот таким образом
C++:
#include <amxmodx>

enum _:PLAYER_DATA {
    STEAMID[30],
    KILLS,
    KILLS_HS,
    DEATHS,
    ROUNDS
};

new g_arrStats[33][PLAYER_DATA];
new Array:arrStatsDiscPlayers;
new g_arrDiscData[PLAYER_DATA];
new bool:g_bConnected[33];

public plugin_init() {
    register_plugin("test", "test", "test");
    register_clcmd("say /test", "SayTest");
    register_clcmd("say_team /test", "SayTest");
    register_event("DeathMsg", "EventDeathMsg", "a", "1>0");
    register_logevent("LogEventRoundStart", 2, "1=Round_Start");
}

public plugin_cfg() {
    arrStatsDiscPlayers = ArrayCreate(PLAYER_DATA);
}

public client_putinserver(id) {
    if(is_user_bot(id) || is_user_hltv(id)) {
        g_bConnected[id] = false;
        return PLUGIN_HANDLED;
    }
    g_bConnected[id] = true;
    new bool:bFoundStat = false;
    new i, aSize = ArraySize(arrStatsDiscPlayers);
    new szSteamId[30];
    get_user_authid(id, szSteamId, charsmax(szSteamId));
    for(i = 0; i < aSize; i++) {
        ArrayGetArray(arrStatsDiscPlayers, i, g_arrDiscData);
        if(strcmp(g_arrDiscData[STEAMID], szSteamId) == 0) {
            bFoundStat = true;
            copy(g_arrStats[id][STEAMID], charsmax(g_arrStats[][STEAMID]), g_arrDiscData[STEAMID]);
            g_arrStats[id][KILLS] = g_arrDiscData[KILLS];
            g_arrStats[id][KILLS_HS] = g_arrDiscData[KILLS_HS];
            g_arrStats[id][DEATHS] = g_arrDiscData[DEATHS];
            g_arrStats[id][ROUNDS] = g_arrDiscData[ROUNDS];
            ArrayDeleteItem(arrStatsDiscPlayers, i);
            break;
        }
    }
    if(!bFoundStat) {
        arrayset(g_arrStats[id], 0, PLAYER_DATA);
        get_user_authid(id, g_arrStats[id][STEAMID], charsmax(g_arrStats[][STEAMID]));
    }
    return PLUGIN_CONTINUE;
}

public client_disconnected(id) {
    if(!g_bConnected[id]) {
        return;
    }
    ArrayPushArray(arrStatsDiscPlayers, g_arrStats[id]);
    g_bConnected[id] = false;
}

public SayTest(id) {
    client_print(0, print_console, "array size = %d", ArraySize(arrStatsDiscPlayers));
    for(new i = 0; i < ArraySize(arrStatsDiscPlayers); i++) {
        client_print(id, print_console, "STEAMID: %s", g_arrStats[i][STEAMID]);
        client_print(id, print_console, "KILLS: %d", g_arrStats[i][KILLS]);
        client_print(id, print_console, "KILL_HS: %d", g_arrStats[i][KILLS_HS]);
        client_print(id, print_console, "DEATHS: %d", g_arrStats[i][DEATHS]);
        client_print(id, print_console, "ROUNDS: %d", g_arrStats[i][ROUNDS]);
        client_print(id, print_console, "============================================");
    }
    client_print(id, print_chat, "Текущие: STEAMID: %s, KILLS: %d, KILL_HS: %d, DEATHS: %d, ROUNDS: %d",
        g_arrStats[id][STEAMID],
        g_arrStats[id][KILLS],
        g_arrStats[id][KILLS_HS],
        g_arrStats[id][DEATHS],
        g_arrStats[id][ROUNDS]
    );
}

public LogEventRoundStart() {
    new iPlayers[MAX_PLAYERS], iCountPlayers, iPlayer;
    get_players(iPlayers, iCountPlayers, "ch");
    for(new i; i < iCountPlayers; i++) {
        iPlayer = iPlayers[i];
        g_arrStats[iPlayer][ROUNDS]++;
    }
}

public EventDeathMsg() {
    new killer = read_data(1);
    new victim = read_data(2);
    if(killer != victim) {
        if(read_data(3) == HIT_HEAD) {
            g_arrStats[killer][KILLS_HS]++;
        }
        g_arrStats[killer][KILLS]++;
    }
    g_arrStats[victim][DEATHS]++;
}

public plugin_end() {
    ArrayDestroy(arrStatsDiscPlayers);
}
побегал с ботами пару раз перезашел и всё работает как надо, модеры тему пока не закрывайте, проверю завтра с людьми скажу окончательный результат
12 Фев 2018
gyxoBka, спасибо за подсказку, обязательно посмотрю
 
Сообщения
94
Реакции
64
Помог
5 раз(а)
Sonyx, честно, ни разу не видел чтобы кто-то использовал этот 2-й аргумент)
 
Сообщения
94
Реакции
64
Помог
5 раз(а)
wopox1337, я понимаю, что он появился в 1.8.3 версии, но сколько пересмотрел плагинов разных авторов и никто этим 2-м аргументом не пользуется, если есть пример было бы неплохо глянуть. Что касается темы, ее можно закрыть, проверил с одним человеком на работоспособность без ботов, все данные при перезаходе возвращаются как надо.
 
Сообщения
2,713
Реакции
2,995
Помог
59 раз(а)

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу