PDA

Просмотр полной версии : [Вопрос] Как оптимизировать (уменьшить потребление стэка в команде /ahelp)



ALIT13
21.05.2018, 14:38
new cmd[1650];
switch(listitem)
{
case 0:
{
format(cmd,sizeof(cmd), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
CMDADM1[0],CMDADM1[1],CMDADM1[2],CMDADM1[3],CMDADM1[4],CMDADM1[5],CMDADM1[6],CMDADM1[7],CMDADM1[8],CMDADM1[9],CMDADM1[10],CMDADM1[11],CMDADM1[12],CMDADM1[13],CMDADM1[14]);
ShowPlayerDialog(playerid,9999,DIALOG_STYLE_MSGBOX,"{FF8C00}Êîìàíäû Àäìèíèñòðàòîðà [1] Óðîâíÿ", cmd, "Âûáîð", "");
}
case 1:
{
format(cmd,sizeof(cmd), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
CMDADM2[0],CMDADM2[1],CMDADM2[2],CMDADM2[3],CMDADM2[4],CMDADM2[5],CMDADM2[6],CMDADM2[7],CMDADM2[8],CMDADM2[9],CMDADM2[10],CMDADM2[11],CMDADM2[12],CMDADM2[13],CMDADM2[14]);
ShowPlayerDialog(playerid,9999,DIALOG_STYLE_MSGBOX,"{FF8C00}Êîìàíäû Àäìèíèñòðàòîðà [2] Óðîâíÿ", cmd, "Âûáîð", "");
}
case 2:
{
format(cmd,sizeof(cmd), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%",
CMDADM3[0],CMDADM3[1],CMDADM3[2],CMDADM3[3],CMDADM3[4],CMDADM3[5],CMDADM3[6],CMDADM3[7],CMDADM3[8],CMDADM3[9],CMDADM3[10],CMDADM3[11],CMDADM3[12],CMDADM3[13],CMDADM3[14],CMDADM3[15],CMDADM3[16],CMDADM3[17],CMDADM3[18]);
ShowPlayerDialog(playerid,9999,DIALOG_STYLE_MSGBOX,"{FF8C00}Êîìàíäû Àäìèíèñòðàòîðà [3] Óðîâíÿ", cmd, "Âûáîð", "");
}
case 3:
{
format(cmd,sizeof(cmd), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
CMDADM4[0],CMDADM4[1],CMDADM4[2],CMDADM4[3],CMDADM4[4],CMDADM4[5],CMDADM4[6],CMDADM4[7],CMDADM4[8],CMDADM4[9],CMDADM4[10],CMDADM4[11],CMDADM4[12],CMDADM4[13],CMDADM4[14],CMDADM4[15],CMDADM4[16],CMDADM4[17],CMDADM4[18]);
ShowPlayerDialog(playerid,9999,DIALOG_STYLE_MSGBOX,"{FF8C00}Êîìàíäû Àäìèíèñòðàòîðà [4] Óðîâíÿ", cmd, "Âûáîð", "");
}
case 4:
{
format(cmd,sizeof(cmd), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
CMDADM5[0],CMDADM5[1],CMDADM5[2],CMDADM5[3],CMDADM5[4],CMDADM5[5],CMDADM5[6],CMDADM5[7],CMDADM5[8],CMDADM5[9],CMDADM5[10],CMDADM5[11],CMDADM5[12],CMDADM5[13],CMDADM5[14],CMDADM5[15]);
ShowPlayerDialog(playerid,9999,DIALOG_STYLE_MSGBOX,"{FF8C00}Êîìàíäû Àäìèíèñòðàòîðà [5] Óðîâíÿ", cmd, "Âûáîð", "");
}
}
}

Очень много стека заполняет

DeimoS
21.05.2018, 18:05
CMD:ahelp(playerid)
{
if(!PlayerInfo[playerid][bAdmin]) return 1;

static a_level_1[] =
{
"{FFFFFF}Уровень 1: /atipster /gg /re /pm /admin(/a) /alogin /tp /ap /alock /hp /ram /o /aad /unprison"
};
static a_level_2[] =
{
"Уровень 2: /getstats /fstyle /prison /mute /sp /skin /iwep /slap /goto /kick /money"
};
static a_level_3[] =
{
"Уровень 3: /warehouse /mark /gotomark /gethere /spveh /getip /pgetip /agetipreg /geton /jailed"
};
static a_level_4[] =
{
"Уровень 4: /unban /balance /spawncars /sethp /house /freeze"
};
static a_level_5[] =
{
"Уровень 5: /chat /fuel /warn /fuelcars"
};
static a_level_6[] =
{
"Уровень 6: /setskin /ban /setskill /uval"
};
static a_level_7[] =
{
"Уровень 7: /givemoney /sban /ainfoip /delveh /delvehall /veh /givegun"
};
static a_level_8[] =
{
"Уровень 8: /unbanip /amusic /gotoderby"
};
static a_level_9[] =
{
"Уровень 9: /offwarn /offban /templeader"
};
static a_level_10[] =
{
"Уровень 10: /iban /banip /unwarn /agiverank"
};
static a_level_11[] =
{
"Уровень 11: /gzcolor /setmats /switchmafia /makeleader"
};
static a_level_12[] =
{
"Уровень 12: /edit /startpb /startrace"
};
static a_level_12[] =
{
"Уровень 13-14: /nick /getadmin /addbiz /addeat /adelpos /giverubete /mka /sniat /makehelper /narkopriton /ghetto"
};


switch(PlayerInfo[playerid][bAdmin])
{
case 1:
{
a_level_1[sizeof(a_level_1)-1] = '\0';
}
case 2:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\0';
}
case 3:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\0';
}
case 4:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\0';
}
case 5:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\0';
}
case 6:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\0';
}
case 7:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\0';
}
case 8:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\0';
}
case 9:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\n';
a_level_9[sizeof(a_level_9)-1] = '\0';
}
case 10:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\n';
a_level_9[sizeof(a_level_9)-1] = '\n';
a_level_10[sizeof(a_level_10)-1] = '\0';
}
case 11:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\n';
a_level_9[sizeof(a_level_9)-1] = '\n';
a_level_10[sizeof(a_level_10)-1] = '\n';
a_level_11[sizeof(a_level_11)-1] = '\0';
}
case 12:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\n';
a_level_9[sizeof(a_level_9)-1] = '\n';
a_level_10[sizeof(a_level_10)-1] = '\n';
a_level_11[sizeof(a_level_11)-1] = '\n';
a_level_12[sizeof(a_level_12)-1] = '\0';
}
default:
{
a_level_1[sizeof(a_level_1)-1] = '\n';
a_level_2[sizeof(a_level_2)-1] = '\n';
a_level_3[sizeof(a_level_3)-1] = '\n';
a_level_4[sizeof(a_level_4)-1] = '\n';
a_level_5[sizeof(a_level_5)-1] = '\n';
a_level_6[sizeof(a_level_6)-1] = '\n';
a_level_7[sizeof(a_level_7)-1] = '\n';
a_level_8[sizeof(a_level_8)-1] = '\n';
a_level_9[sizeof(a_level_9)-1] = '\n';
a_level_10[sizeof(a_level_10)-1] = '\n';
a_level_11[sizeof(a_level_11)-1] = '\n';
a_level_12[sizeof(a_level_12)-1] = '\n';
a_level_13[sizeof(a_level_13)-1] = '\0';
}
}
SPD(playerid, 0000, DIALOG_STYLE_MSGBOX, ""SERVER"Команды администратора", a_level_1, "Закрыть", "");
return 1;
}
Вот так реализуй всё. Без постоянного лишнего форматирования и терзания стэка

Daniel_Cortez
21.05.2018, 19:54
Почти то же самое, только без китайского (повторяющегося) кода:

CMD:ahelp(playerid, params[])
{
const AHELP_LEVELS = 13;
static level_cmds[AHELP_LEVELS][] =
{
{ "{FFFFFF}Уровень 1: /atipster /gg /re /pm /admin(/a) /alogin /tp /ap /alock /hp /ram /o /aad /unprison" },
{ "Уровень 2: /getstats /fstyle /prison /mute /sp /skin /iwep /slap /goto /kick /money" },
{ "Уровень 3: /warehouse /mark /gotomark /gethere /spveh /getip /pgetip /agetipreg /geton /jailed" },
{ "Уровень 4: /unban /balance /spawncars /sethp /house /freeze" },
{ "Уровень 5: /chat /fuel /warn /fuelcars" },
{ "Уровень 6: /setskin /ban /setskill /uval" },
{ "Уровень 7: /givemoney /sban /ainfoip /delveh /delvehall /veh /givegun" },
{ "Уровень 8: /unbanip /amusic /gotoderby" },
{ "Уровень 9: /offwarn /offban /templeader" },
{ "Уровень 10: /iban /banip /unwarn /agiverank" },
{ "Уровень 11: /gzcolor /setmats /switchmafia /makeleader" },
{ "Уровень 12: /edit /startpb /startrace" },
{ "Уровень 13-14: /nick /getadmin /addbiz /addeat /adelpos /giverubete /mka /sniat /makehelper /narkopriton /ghetto" }
};

new level = player_info[playerid][pAdmin];
if (level == 0)
return 1;
if (level > AHELP_LEVELS)
level = AHELP_LEVELS;
static const IDX_MINUS_ONE = -1;
for (new i = 1; i < level; ++i)
level_cmds[i][IDX_MINUS_ONE] = '\n';
if (level < AHELP_LEVELS)
level_cmds[level][IDX_MINUS_ONE] = '\0';
return ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, level_cmds[0], !"Ок", "");
}

ziggi
22.05.2018, 00:59
Ещё, если используется Pawn.CMD, то текст с командами можно генерировать автоматически, пример есть здесь: http://pro-pawn.ru/showthread.php?10418-ahelp&p=75856&viewfull=1#post75856

DeimoS
22.05.2018, 12:25
Ещё, если используется Pawn.CMD, то текст с командами можно генерировать автоматически, пример есть здесь: http://pro-pawn.ru/showthread.php?10418-ahelp&p=75856&viewfull=1#post75856

Правда стоит понимать, что такой вариант каждый раз генерирует список команд по новой, что, как по мне, немного глупо, с учётом того, что этот список не будет изменятся во время работы сервера.
Уж лучше раз в 100 лет, при добавлении новой команды, просто внести правку в массив с текстом, чем ради того, чтоб избежать этого самого "раз в 100 лет", заставлять мод делать кучу лишних действий. :pardon:

Daniel_Cortez
22.05.2018, 14:45
Ещё, если используется Pawn.CMD, то текст с командами можно генерировать автоматически, пример есть здесь: http://pro-pawn.ru/showthread.php?10418-ahelp&p=75856&viewfull=1#post75856
В посте по ссылке способ описан как

Самый нормальный вариант
..., но что именно понимается под "нормальным" вариантом? Динамика, "гибкость"? Постом выше DeimoS прекрасно объяснил, насколько она здесь уместна. Отсутствие хардкода с ручным прописыванием каждой команды в списке? Ну так в данном случае всё равно нужен будет массив, в который запишется строка со всеми разрешёнными командами. А нахождение и указание размера, достаточного чтобы вместить все команды - тот же самый хардкод (либо, если указан огромный, заведомо недостижимый размер - нерациональное использование памяти) + лишняя возня с динамикой.

ziggi
22.05.2018, 15:45
Правда стоит понимать, что такой вариант каждый раз генерирует список команд по новой, что, как по мне, немного глупо, с учётом того, что этот список не будет изменятся во время работы сервера.
Уж лучше раз в 100 лет, при добавлении новой команды, просто внести правку в массив с текстом, чем ради того, чтоб избежать этого самого "раз в 100 лет", заставлять мод делать кучу лишних действий. :pardon:

Достаточно формировать все строки при запуске сервера.


В посте по ссылке способ описан как

..., но что именно понимается под "нормальным" вариантом? Динамика, "гибкость"? Постом выше DeimoS прекрасно объяснил, насколько она здесь уместна. Отсутствие хардкода с ручным прописыванием каждой команды в списке? Ну так в данном случае всё равно нужен будет массив, в который запишется строка со всеми разрешёнными командами. А нахождение и указание размера, достаточного чтобы вместить все команды - тот же самый хардкод (либо, если указан огромный, заведомо недостижимый размер - нерациональное использование памяти) + лишняя возня с динамикой.

Нормальный, конечно же, по моему мнению. Почему? Потому что это уменьшит количество телодвижений при добавлении, удалении или изменении команд в будущем. Что касается памяти, да её потребуется больше, но это сущий пустяк. Для достижения функциональности команды /ahelp (которая выше), достаточно создать массив вида commands[AHELP_LEVELS][144] (144 - первое, что пришло в голову). А если команд потребуется больше, то, как вариант, можно при формировании строки сообщать о том, что размер массива нужно увеличить.

DeimoS
22.05.2018, 16:47
Достаточно формировать все строки при запуске сервера.

Только нужно ещё предугадать нужный размер массива, дабы сразу все команды влезали :) В итоге, каждое добавление/удаление команды потребует перерасчёта размера массива.
Ну либо выделять сразу чересчур много памяти и часть массива оставлять пустым, что, опять же, не очень оправдано, с учётом того, что это сделано лишь для того, чтоб избежать единоразового ручного заполнения массива всеми командами.

Нужно смотреть трезво на ситуацию: список команд активно может пополнятся только на первых этапах разработки мода. Впоследствии этот список будет редактироваться, в лучшем случае, раз в пару недель (да и то, либо просто будут изменяться имена команд, либо команды будут добавляться/удаляться). Делать ради этого какое-то автоматическое заполнение, с учётом того, что ради этого потребуется тратить и дополнительное процессорное время, и память, - как по мне, не очень оправдано. Особенно с учётом того, что на написание автозаполнения массива с нуля уйдёт больше времени, чем на ручное заполнение массива всеми командами.

Geebrox
22.05.2018, 18:31
Только нужно ещё предугадать нужный размер массива, дабы сразу все команды влезали :) В итоге, каждое добавление/удаление команды потребует перерасчёта размера массива.
Ну либо выделять сразу чересчур много памяти и часть массива оставлять пустым, что, опять же, не очень оправдано, с учётом того, что это сделано лишь для того, чтоб избежать единоразового ручного заполнения массива всеми командами.

Нужно смотреть трезво на ситуацию: список команд активно может пополнятся только на первых этапах разработки мода. Впоследствии этот список будет редактироваться, в лучшем случае, раз в пару недель (да и то, либо просто будут изменяться имена команд, либо команды будут добавляться/удаляться). Делать ради этого какое-то автоматическое заполнение, с учётом того, что ради этого потребуется тратить и дополнительное процессорное время, и память, - как по мне, не очень оправдано. Особенно с учётом того, что на написание автозаполнения массива с нуля уйдёт больше времени, чем на ручное заполнение массива всеми командами.

Всё это правда, но вот в методе от ziggi есть преимущество, PC_RenameCommand. То есть если у сервера есть изменение название команды прямо из игры, то в твоём случае останется старая название без изменение и это может спутать админов, а в случае ziggi отобразится уже обновленный название команды (как я предполагаю)

DeimoS
22.05.2018, 18:35
Всё это правда, но вот в методе от ziggi есть преимущество, PC_RenameCommand. То есть если у сервера есть изменение название команды прямо из игры, то в твоём случае останется старая название без изменение и это может спутать админов, а в случае ziggi отобразится уже обновленный название команды (как я предполагаю)

Эмм, ну если у тебя в моде подразумевается изменение имён команд, то естественно ты должен это учесть и уже либо делать массив, где будет хранится новое имя и из которого оно будет попадать в список команд, либо, в случае с Pawn.CMD, пользоваться функционалом плагина.

Но ты хоть раз видел сервер, где меняются названия команд? Я - нет. Просто потому что адекватное применение подобному не придумать. Удаление/переименование команд в плагине сделано просто как дополнительный функционал и не более.


То, о чём ты говоришь - это, скорее, исключение из правил, которое подразумевает совершенно иной подход. Аргументом это считать как-то странно.

Geebrox
22.05.2018, 18:41
Эмм, ну если у тебя в моде подразумевается изменение имён команд, то естественно ты должен это учесть и уже либо делать массив, где будет хранится новое имя и из которого оно будет попадать в список команд, либо, в случае с Pawn.CMD, пользоваться функционалом плагина.

Но ты хоть раз видел сервер, где меняются названия команд? Я - нет. Просто потому что адекватное применение подобному не придумать. Удаление/переименование команд в плагине сделано просто как дополнительный функционал и не более.


То, о чём ты говоришь - это, скорее, исключение из правил, которое подразумевает совершенно иной подход. Аргументом это считать как-то странно.

Раз ты не видел, то это не значит, что таких серверов нет) Нужно учитывать каждую деталь, при написание кода, чтобы в будущем не было "траблов". Я не говорю, что метод ziggi превосходит твою, я говорю, что у него есть преимущества.

То, о чём я говорю - это исключение из правил? Не думаю, да я и не аругемнтировал, я описал преимущества, но не говорил, что превзойдёт.

А то, что ты жалеешь память - вот это странно, как то ты сам говорил, что в нынешнее времена пренебрежение памятью ради удобства - это норма (вроде). Мы не живём в 90х, чтобы 1мб памяти решало многое.

Daniel_Cortez
22.05.2018, 19:46
Всё это правда, но вот в методе от ziggi есть преимущество, PC_RenameCommand. То есть если у сервера есть изменение название команды прямо из игры, то в твоём случае останется старая название без изменение и это может спутать админов, а в случае ziggi отобразится уже обновленный название команды (как я предполагаю)
В таком случае сводится на нет аргумент об одноразовом формировании строк :)

DeimoS
22.05.2018, 20:17
Раз ты не видел, то это не значит, что таких серверов нет)

Твои слова лишь подтверждают то, что если этой функцией и пользуется кто-то, то только в очень узких кругах.



Нужно учитывать каждую деталь, при написание кода, чтобы в будущем не было "траблов".

Эмм, каких "траблов"? Если ты вдруг решишь сделать возможность изменять имя команды, то и "динамическая" подгрузка этого имени в /ahelp так же должна быть как само собой разумеющееся.
Хотя даже тут гораздо выгоднее будет просто через strfind найди команду, удалить её через strdel и вписать новое имя через strins, чем городить непонятный скрипт с подгрузкой, на написание которого, повторюсь, уйдёт гораздо больше времени, в итоге. При этом, такой скрипт не даст возможности сделать описание команд.



То, о чём я говорю - это исключение из правил? Не думаю

Ну так тогда предоставь примеры широкого применения переименования команд. Если их не будет, то, соответственно, и описанный тобой случай можно считать единичным.


А то, что ты жалеешь память - вот это странно, как то ты сам говорил, что в нынешнее времена пренебрежение памятью ради удобства - это норма (вроде). Мы не живём в 90х, чтобы 1мб памяти решало многое.

Одно дело - пренебрегать памятью с пользой (то бишь, не ужимать функциональность или читаемость кода ради того, чтоб сэкономить 22 байта). Совсем другое - нерациональное разбрасывание памятью, оправданное собственной ленью и самообманом.

DeimoS
23.05.2018, 15:40
Раз уж автор не даёт о себе знать, видимо, вопрос решён. Если нет - пиши в личку, открою тему.
Закрыто.