- Код: Выделить всё
[AMXX] Displaying debug trace (plugin "voteban.amxx")
[AMXX] Run time error 4: index out of bounds
[AMXX] [0] de13e63cb466dc14082a08329a1aefa8.sma::ReasonsMenuHandler (line 176)
Как я понял, ошибка возникает, если на стадии выбора причины открыть другое меню и там выбрать пункт, которого нет в причинах. Например, в плагине 6-7 причин, а в другом меню выбрать 7-8 пункт
- Код: Выделить всё
#include <amxmodx>
#define ADMIN_NONE -1
#define LOGS // закоментировать для отключения лога
#if AMXX_VERSION_NUM < 183
#include <colorchat>
#endif
#define MIN_PLAYERS 3 // Минимальное кол-во игроков на сервере для запуска голосования
#define BAN_RATIO 0.6 // Коэффицент голосов для бана. 0.1 - 10% | 1.0 - 100%
#define VB_DELAY 120 // Время(в секундах) между голосованиями. Защита от лалок, которые хотят всех перебанить xD
#define VB_TIME 10.0 // Продолжительность голосования
#define VB_BANTIME 60 // Время бана в минутах
#define ACCESS ADMIN_NONE // Доступ к функциям вотебана. Чтобы разрешить всем использовать поставьте ADMIN_NONE
// Стандартные причины VoteBan. Не указывайте больше 8-ми. Может сломаться менюшка :D
// Пункт "Своя причина" добавляется в конце списка.
new g_aBanReasons[][64] =
{
"AIM",
"WH",
"Неадекват",
"Мешает играть"
}
new g_iReasonsMenu;
new g_iVoteMenu;
new _access, callback, ItemData[3];
new g_iInsider;
new g_iVoteStartTime;
new g_iVoteCount, bool:g_bIsVoted[33];
new g_iVictim;
new g_sBanReason[256];
new g_iVoteBanPlayersNum, g_iVoteBanPlayers[33];
public plugin_init()
{
#define VERSION "1.4"
register_plugin("Lite VoteBan", VERSION, "neygomon");
register_cvar("lite_voteban", VERSION, FCVAR_SERVER | FCVAR_SPONLY);
register_clcmd("say /voteban", "ClCmdVoteban");
register_clcmd("say_team /voteban", "ClCmdVoteban");
register_clcmd("vtb_reason", "ClCmdReason");
}
public plugin_cfg()
{
g_iReasonsMenu = menu_create("\d[\rVoteBan\d] \yВыберите причину бана\w", "ReasonsMenuHandler");
g_iVoteMenu = menu_create("UNNAMED_MENU", "VoteMenuHandler");
menu_setprop(g_iReasonsMenu, MPROP_EXIT, MEXIT_NEVER);
menu_setprop(g_iReasonsMenu, MPROP_PERPAGE, 0);
menu_setprop(g_iVoteMenu, MPROP_EXIT, MEXIT_NEVER);
new num[3];
for(new i; i < sizeof g_aBanReasons; i++)
{
num_to_str(i, num, charsmax(num));
menu_additem(g_iReasonsMenu, g_aBanReasons[i], num);
}
menu_addblank(g_iReasonsMenu, 0);
menu_additem(g_iReasonsMenu, "\yСвоя причина", "69");
menu_additem(g_iVoteMenu, "\rДа", "1");
menu_additem(g_iVoteMenu, "\yНет", "0");
}
public client_disconnected(id)
{
if(g_bIsVoted[id])
{
g_bIsVoted[id] = false;
g_iVoteCount--;
}
}
public ClCmdVoteban(id)
{
#if ACCESS != ADMIN_NONE
if(~get_user_flags(id) & ACCESS)
{
new flag[25]; get_flags(ACCESS, flag, charsmax(flag));
client_print_color(id, 0, "^1[^4VoteBan^1] ^4Доступ запрещен! Разрешено только игрокам с флагами ^3%s^4!", flag);
return PLUGIN_HANDLED;
}
#endif
static players[32], pnum, iVtbDelay;
if(g_iInsider)
return client_print_color(id, 0, "^1[^4VoteBan^1] ^4Голосование ^3уже запущено^4!");
if((iVtbDelay = g_iVoteStartTime + VB_DELAY - get_systime()) > 0)
return client_print_color(id, 0, "^1[^4VoteBan^1] ^4Голосование будет доступно через ^3%d ^4мин. ^3%d ^4сек.", (iVtbDelay / 60), (iVtbDelay % 60));
get_players(players, pnum);
if(MIN_PLAYERS > pnum)
return client_print_color(id, 0, "^1[^4VoteBan^1] ^4Необходимо не менее ^3%d ^4игроков для запуска голосования!", MIN_PLAYERS);
g_iVoteBanPlayersNum = 0;
for(new i; i < pnum; i++)
{
//if(get_user_flags(players[i]) & ADMIN_MENU)
// return client_print_color(id, 0, "^1[^4VoteBan^1] ^4На сервере присутствует ^3администратор^4!");
g_iVoteBanPlayers[g_iVoteBanPlayersNum++] = players[i];
}
return SelectPlayerOnBan(id);
}
public SelectPlayerOnBan(id)
{
new iPlayersMenu = menu_create("\d[\rVoteBan\d] \yВыберите игрока\w", "PlayersMenuHandler");
new iCallBack = menu_makecallback("PlayersMenuCallback");
menu_setprop(iPlayersMenu, MPROP_BACKNAME, "Назад");
menu_setprop(iPlayersMenu, MPROP_NEXTNAME, "Далее");
menu_setprop(iPlayersMenu, MPROP_EXITNAME, "Выход");
new name[32], num[3];
for(new i; i < g_iVoteBanPlayersNum; i++)
{
if(g_iVoteBanPlayers[i] == id) continue;
get_user_name(g_iVoteBanPlayers[i], name, charsmax(name));
num_to_str(g_iVoteBanPlayers[i], num, charsmax(num));
menu_additem(iPlayersMenu, name, num, 0, iCallBack);
}
menu_display(id, iPlayersMenu, 0);
return PLUGIN_HANDLED;
}
public PlayersMenuCallback(id, menu, item)
{
static ItemName[32], ItemNewName[64];
menu_item_getinfo(menu, item, _access, ItemData, charsmax(ItemData), ItemName, charsmax(ItemName), callback);
if(get_user_flags(str_to_num(ItemData)) & ADMIN_IMMUNITY)
{
formatex(ItemNewName, charsmax(ItemNewName), "\d%s \y[\rИммунитет\y]", ItemName);
menu_item_setname(menu, item, ItemNewName);
return ITEM_DISABLED;
}
return ITEM_ENABLED;
}
public PlayersMenuHandler(id, menu, item)
{
if(item == MENU_EXIT)
{
menu_destroy(menu);
return PLUGIN_HANDLED;
}
menu_item_getinfo(menu, item, _access, ItemData, charsmax(ItemData), _, _, callback);
g_iVictim = str_to_num(ItemData);
menu_destroy(menu);
return menu_display(id, g_iReasonsMenu);
}
public ReasonsMenuHandler(id, menu, item)
{
menu_item_getinfo(menu, item, _access, ItemData, charsmax(ItemData), _, _, callback);
new ReasonId = str_to_num(ItemData);
if(ReasonId == 69) client_cmd(id, "messagemode vtb_reason");
else
{
g_sBanReason = g_aBanReasons[ReasonId];
VoteBanAction(id);
}
return PLUGIN_HANDLED;
}
public ClCmdReason(id)
{
#if ACCESS != ADMIN_NONE
if(~get_user_flags(id) & ACCESS)
{
new flag[25]; get_flags(ACCESS, flag, charsmax(flag));
client_print_color(id, 0, "^1[^4VoteBan^1] ^4Доступ запрещен! Разрешено только игрокам с флагами ^3%s^4!", flag);
return PLUGIN_HANDLED;
}
#endif
static sReason[128];
read_args(sReason, charsmax(sReason));
remove_quotes(sReason);
g_sBanReason = sReason[0] ? sReason : "unknown";
return VoteBanAction(id);
}
VoteBanAction(id)
{
static sInsName[32], sVicName[32], sTitle[256];
get_user_name(id, sInsName, charsmax(sInsName));
get_user_name(g_iVictim, sVicName, charsmax(sVicName));
formatex(sTitle, charsmax(sTitle), "\rЗабанить \y%s\w?^n\rПричина\w: \y%s^n\dЗапустил \r%s", sVicName, g_sBanReason, sInsName);
menu_setprop(g_iVoteMenu, MPROP_TITLE, sTitle);
#if defined LOGS
//лог
new title[256]; new time[64];
get_time ("%d.%m.%Y # %H:%M:%S", time, charsmax(time));
formatex(title, charsmax(title), "%s | Запустил игрок %s против %s", time, sInsName, sVicName);
write_file("/addons/amxmodx/logs/voteban.log", title, -1);
//конец
#endif
g_iInsider = id;
g_iVoteStartTime = get_systime();
g_iVoteCount = 0;
arrayset(g_bIsVoted, false, sizeof(g_bIsVoted));
for(new i; i < g_iVoteBanPlayersNum; ++i)
{
if(g_iVoteBanPlayers[i] != g_iVictim)
menu_display(g_iVoteBanPlayers[i], g_iVoteMenu);
}
return set_task(VB_TIME, "VoteBanResults");
}
public VoteMenuHandler(id, menu, item)
{
if(item != MENU_EXIT)
{
menu_item_getinfo(menu, item, _access, ItemData, charsmax(ItemData), _, _, callback);
if(str_to_num(ItemData))
{
g_iVoteCount++;
g_bIsVoted[id] = true;
}
}
return PLUGIN_HANDLED;
}
public VoteBanResults()
{
show_menu(0, 0, "^n", 1); // визуально закрываем меню.
new title[256];
if(is_user_connected(g_iVictim))
{
new iVoteBanMinVotes = floatround(BAN_RATIO * float(g_iVoteBanPlayersNum));
new name[32]; get_user_name(g_iVictim, name, charsmax(name));
if(g_iVoteCount >= iVoteBanMinVotes)
{
new szPrintReason[128];
formatex(szPrintReason, charsmax(szPrintReason), "[VoteBan] %s", g_sBanReason);
server_cmd("amx_ban %d #%d ^"%s^"", VB_BANTIME, get_user_userid(g_iVictim), szPrintReason);
#if defined LOGS
//лог
formatex(title, charsmax(title), "Статус удачно. Причина: %s ^n---", g_sBanReason);
write_file("/addons/amxmodx/logs/voteban.log", title, -1);
//конец
#endif
client_print_color(0, 0, "^1[^4VoteBan^1] ^4Голосование завершено! Игрок ^3%s ^1был ^3забанен^4! ^1[^4Голосов: ^3%d ^1| ^4Необходимо: ^3%d^1]", name, g_iVoteCount, iVoteBanMinVotes);
log_amx("VoteBan SUCCESS. Player ^"%s^" [Reason: ^"%s^"][Vote: %d | MinVote: %d]", name, g_sBanReason, g_iVoteCount, iVoteBanMinVotes);
}
else
{
client_print_color(0, 0, "^1[^4VoteBan^1] ^4Голосование завершено! Игрок ^3%s ^1не был ^3забанен^4! ^1[^4Голосов: ^3%d ^1| ^4Необходимо: ^3%d^1]", name, g_iVoteCount, iVoteBanMinVotes);
log_amx("VoteBan FAILED. Player ^"%s^" [Reason: ^"%s^"][Vote: %d | MinVote: %d]", name, g_sBanReason, g_iVoteCount, iVoteBanMinVotes);
#if defined LOGS
formatex(title, charsmax(title), "Статус НЕудачно. Причина: %s ^n---", g_sBanReason);
write_file("/addons/amxmodx/logs/voteban.log", title, -1);
#endif
}
}
else client_print_color(g_iInsider, 0, "^1[^4VoteBan^1] ^4Наказать не удалось... Игрок покинул сервер :(");
g_iInsider = g_iVictim = 0;
}
Название темы скорректировано, тема перемещена из раздела "Скриптинг" // Subb98