Debugging pluginuri AMX Mod X - comunitate Rusă scripting amxx

proiectare dop de fază, care se găsește, izolează și elimină erorile - Debugging. Pentru a vedea în cazul în care a apărut eroarea, este necesar:
  • afla valorile curente ale variabilelor;
  • și de a afla ce program se execută pe drum.

AMX Mod X este deja integrat depanator, care ar fi de ajuns pentru a rezolva problemele noastre. Valoarea comenzii Amx_debug ar trebui să fie 1. Mod de depanare pentru un anumit plugin este inclus în modul următor: în fișierul. vizavi /addons/amxmodx/configs/plugins.ini fișa necesară prescrie cuvântul de depanare. de exemplu:


Dupa aceasta schimba harta de pe server sau reporniți serverul (comanda repornire). Acum, jurnalele AMXX (. / Addons / amxmodx / bușteni) vom fi capabili să învețe în detaliu în ce stadiu există un bug în plugin. Activitate erori în directorul jurnalele numit error_X.txt. unde X - este data la care a fost creat fișierul.
Să presupunem că avem un plugin pentru a citi, care se află la intrarea în player-ul la serverul scrie numele în g_Names variabile globale. De asemenea, am înregistrat consola de comandă amx_names_reset pentru a reseta această variabilă prin bucla cu un număr fix de etape. Acest cod este compilat fără erori, dar aceasta nu înseamnă că va funcționa așa cum ar trebui. După lansarea plugin-ul, precum și utilizarea de consolă amx_names_reset comandă în directorul de bușteni, am găsit jurnalul cu erori.

debug.sma:
Cod: Selectați toate #include

PLUGIN #define "Exemplu Debug Plugin"
VERSIUNEA #define "1.0"
#define AUTOR "DJ_WEST"

noi g_Names # 91; 33 # 93; # 91; 32 # 93;

plugin_init publice ()
register_plugin (PLUGIN. VERSION. AUTOR)
register_concmd ( "amx_names_reset". "Names_Reset")
>

client_putinserver publică (id)
noi s_Name # 91; 32 # 93;

get_user_name (id. s_Name. charsmax (s_Name))

g_Names # 91; id # 93; = s_Name

server_print ( "% s intrat în joc". s_Name)
>

publice Names_Reset (id)
pentru (nou i = 1; i <= 33 ; i ++)
g_Names # 91; eu # 93; = ""

server_print ( "Nume reset")
>

Acum ne uităm la bucla nostru:
Cod: Selectați toate
pentru (nou i = 1; i <= 33 ; i ++)
g_Names # 91; eu # 93; = ""

Vedem că bucla se execută de la i = 1 la i <= 33 при этом i используется в g_Names. Но если вспомнить размерность массива g_Names, то понимаем, что когда i дойдет до 33, то это будет за пределами g_Names, следовательно нам нужно исправить код на:
Cod: Selectați toate
pentru (nou i = 1; i <= 32 ; i ++)
g_Names # 91; eu # 93; = ""

Re-compila plug-in, check-l și vezi că totul funcționează bine. Rețineți că aceasta este doar un exemplu de depanare. De fapt, pot exista și alte erori, iar în cazul în care priza este de asemenea mare, căutarea de eroare poate dura mult mai mult.

Nu-mi scrie un PM. Dacă aveți nevoie de ajutor, gratuit. Orice întrebări pe forum.

Opțiuni:
-A alinierea în octeți segmentul de date și stivă
-un cod de ieșire de asamblare
-C # 91 + / - # 93; codare compactă pentru fișier de ieșire (implicit = -)
-c numele sau numărul codepage; ex 1252 pentru Windows Latin-1
-Dpath calea directorului activ
-D0 nici o informație simbolică, fără controale run-time
-d1 # 91; # 93 implicit; run-time controale, nici o informație simbolică
-d2 informații complete de depanare și de verificare dinamică
-d3 informații de depanare completă, verificarea dinamică, nu optimizare
-e set numele de fișier de eroare (compilare liniștită)
-H fereastra de mâner pentru a trimite un mesaj de notificare privind finalizarea
-eu calea pentru includ fișiere
-L crea fișierul listă (preprocesa numai)
-o Numele setului de bază de fișier de ieșire
-p setați numele de fișier „prefixul“
-r # 91; Nume # 93; scrie raportul de referință încrucișată la consola sau la anumite fișiere

Dupa cum se poate vedea în mod implicit este -d1. Pentru că nici o tastă pentru a compila definirea de depanare vechi. În cazul în care opțiunea de a înregistra -D3. informații pentru depanare, puteți obține un pic mai mult.

În cazul în care punctul -d0. depanare de informații nu vor fi. Acest lucru va complica atât demontarea și face imposibilă pentru a depana. De asemenea, dacă activați în setările sau pentru a adăuga pornire depanare, plugin-ul nu va rula deloc în modul de depanare.

În consecință, diferite dimensiuni, și plug-in-uri cu aceste opțiuni. Cu cât sunt mai depanare de informații, „mai greu“ plugin-ul.

Pentru a pune o întrebare în mod corect, trebuie să știți mai mult de jumătate din răspunsul.
Cerberus - amxbans de înlocuire și multe altele

Ai încredere, dar verifică
Dupa cum am scris aici, cheia standard este d1, dar pentru unele disassemblers motiv pot vizualiza informații simbolice. Desenați un mic experiment - compila standardul plug-in „compile.exe“ și propriul său cu chei diferite, și apoi despachetați fișierele din care rezultă amxx 32 de biți parte (poate fi 64, dar nu are sens).

Fișierele ca un atașament să se uite prin HeksEditor - care vrea să vadă cum este de fapt arata ca totul

Se poate observa că „kz_scout2 Compiler.amx“ și „kz_scout2 D2.amx“, la fel ca și „compile.exe“ folosește doar deducem că de fapt opțiunea o- în incapacitate de plată -D2 cheie este, mai degrabă decât cum să scrie -d1

Deși este posibil să se facă un criteriu suplimentar: d2 adaugă informații simbolice - care include o listă a fișierelor utilizate în compilarea (în „kz_scout2 Compiler.amx“ văzut calea completă la codul sursă la momentul compilarii: D) „șirul“ cu pozițiile lor, „A“ - numele funcțiilor , variabile și domeniul de aplicare a acestora de DPI, tag-uri, și nu destul de clar pentru mine până la câmpuri de tip gunoi „Automat“ și „stat“. Toate acestea sunt înregistrate în sfârșitul fișierului, deci este destul de vizibile atunci când se compară fișiere
Conform acestei imagini de disc a fost otkompilit:
1 fișier, 8 linii, patru variabile (MYSTATIC, id, givescout, plugin_init), 15 etichete (float, bool, orice etc.), 1 "Automat", 0 "stat".

Se pare că cineva a editat compilator și lazhanulsya (Tu chiar le dezabona despre acest „bug“)

PS Prin modul în care descrierile opțiunilor de compilare au Trebuie să fiți înregistrat pentru a vedea link-uri. și nu pot fi, de asemenea, remarcat faptul că cheia implicită este de fapt alta.

#include
#include

/ ** sări peste autoloading, deoarece este opțional * /
#define AMXMODX_NOAUTOLOAD
#include

Noul g_menuPosition # 91, # 33, 93;
noi g_menuPlayers # 91, 33 # 93; # 91; # 32 93;
Noul g_menuPlayersNum # 91, # 33, 93;
Noul g_menuOption # 91, # 33, 93;

Noul g_menuSelect # 91, 33 # 93; # 91; # 93 254;
Noul g_menuSelectNum # 91, # 33, 93;

#define MAX_CLCMDS 24

Noul g_clcmdName # 91; MAX_CLCMDS # 93; # 91; # 32 93;
Noul g_clcmdCmd # 91; MAX_CLCMDS # 93; # 91; # 93 254;
Noul g_clcmdMisc # 91; MAX_CLCMDS # 93; # 91; # 93 2;
noi g_clcmdNum

plugin_natives publice ()
set_module_filter ( "module_filter")
set_native_filter ( "native_filter")
>

plugin_init publice ()
register_plugin ( "Jucătorii Menu", AMXX_VERSION_STR, "AMXX Dev Team")
register_dictionary ( "common.txt")
register_dictionary ( "admincmd.txt")
register_dictionary ( "plmenu.txt")


register_clcmd ( "amx_laccmdmenu", "cmdlaccmdmenu", ADMIN_KICK, "- display-uri client meniul cmds")


register_menucmd (register_menuid ( "Client cmds Menu"), 1023, "actionlaccmdmenu")

Noul clcmds_ini_file # 91; 254 # 93;
get_configsdir (clcmds_ini_file, 253)
Formatul (clcmds_ini_file, 253, "% s / clcmdslac.ini", clcmds_ini_file)
load_settings (clcmds_ini_file)

/ * Meniul cmds client * /

actionlaccmdmenu publică (id, cheie)
comutator (cheie)
Cazul 7:
++g_menuOption # 91; ID # 93;
g_menuOption # 91; ID # 93; % = G_menuSelectNum # 91; id # 93;
displaylaccmdmenu (id, g_menuPosition # 91; id # 93;)
>
caz 8: displaylaccmdmenu (id, ++ g_menuPosition # 91; id # 93;)
caz 9: displaylaccmdmenu (id, --g_menuPosition # 91; id # 93;)
default:
jucător nou = g_menuPlayers # 91; ID # 93; # 91; g_menuPosition # 91; ID # 93; * 7 + tasta # 93;
noi steaguri = g_clcmdMisc # 91; g_menuSelect # 91; id # 93; # 91; g_menuOption # 91; id # 93; # 93; # 93; # 91; # 93 1;

în cazul în care (is_user_connected (jucător))
nouă comandă # 91, # 93 512;, authid # 91; 32 # 93;, numele # 91; 32 # 93;, userid # 91; 32 # 93;

înlocuiți (comandă, charsmax (comanda), "%% userid", userid)
înlocuiți (comandă, charsmax (comanda), "%% authid", authid)
înlocuiți (comandă, charsmax (comanda), "% name%", nume)

în cazul în care (steaguri 1)
server_cmd ( "% s", comandă)
server_exec ()
> else if (steaguri 2)
client_cmd (id, "% s", comanda)
else if (steaguri 4)
client_cmd (jucător, "% s", comanda)
>

în cazul în care (steaguri 8)
displaylaccmdmenu (id, g_menuPosition # 91; id # 93;)
>
>

displaylaccmdmenu (id, pos)
în cazul în care (pos <0)
întoarcere

Noul menuBody # 91; 512 # 93;
nou b = 0
noi am
nume nou # 91; 32 # 93;
nou început = pos * 7

dacă (start> = g_menuPlayersNum # 91; id # 93;)
start = pos = g_menuPosition # 91; id # 93; = 0

Noul len = format (menuBody, 511, g_coloredMenus. "\ y% L \ R ./.^ n \ w ^ n". "% L ./.^n^n", id, "CL_CMD_MENU", pos + 1 , (g_menuPlayersNum # 91; id # 93; / 7 + ((g_menuPlayersNum # 91; id # 93;. 7%) 1. 0)))
nou end = pornire + 7
noi chei = MENU_KEY_0 | MENU_KEY_8

if (end> g_menuPlayersNum # 91; id # 93;)
end = g_menuPlayersNum # 91; id # 93;

pentru (nou a = a începe; o i = g_menuPlayers # 91; id # 93; # 91; a # 93;
get_user_name (i, numele, 31)

în cazul în care (g_menuSelectNum # 91 ;! ID # 93; || (acces (i, ADMIN_IMMUNITY) i! = id))
++b

if (g_coloredMenus)
len + = format (menuBody # 91; len # 511;, 93-len, "\ d ..% s ^ n \ w", b, nume)
altfel
len + = format (menuBody # 91; len # 511;, 93-len "#% s ^ n", nume)
> Chei Else | = (1<

if (is_user_admin (i))
len + = format (menuBody # 91; len # 511;, 93-len, g_coloredMenus "..% s \ r * ^ n \ w" "..% s * ^ n" ++ b, numele ..)
altfel
len + = format (menuBody # 91; len # 511;, 93-len "..% s ^ n" ++ b, nume)
>
>

if (g_menuSelectNum # 91; id # 93;)
len + = format (menuBody # 91; len # 511;, 93-len "^ n8% s ^ n", g_clcmdName # 91; g_menuSelect # 91; id # 93; # 91; g_menuOption # 91; id # 93 ; # 93; # 93;)
altfel
len + = format (menuBody # 91; len # 511;, 93-len "^ n8% L ^ n", id, "NO_CMDS")

if (end = g_menuPlayersNum # 91 ;! id # 93;)
format (menuBody # 91; len # 511;, 93-len "^ n9% L ^ n0% L ..", id, "MAI", id, pos "ÎNAPOI" "EXIT" ..)
chei | = MENU_KEY_9
>
altfel
format (menuBody # 91; len # 511;, 93-len "^ n0% L", id, pos "ÎNAPOI" "EXIT" ..)

show_menu (id, chei, menuBody, -1, "Client cmds Menu")
>

cmdlaccmdmenu publică (id, nivel, cid)
if (! cmd_access (id, nivel, cid, 1))
reveni PLUGIN_HANDLED

pentru (nou a = 0; o if (acces (id, g_clcmdMisc # 91; a # 93; # 91; 0 # 93;))
g_menuSelect # 91; ID # 93; # 91; g_menuSelectNum # 91; ID # 93; # 93 ++; = o

displaylaccmdmenu (id, g_menuPosition # 91; id # 93 = 0)

load_settings (szFilename # 91; # 93;)
if (! file_exists (szFilename))
return 0

text nou # 91; # 93 256;, szFlags # 91; 32 # 93;, szAccess # 91; 32 # 93;
nou o, pos = 0

în timp ce (g_clcmdNum în cazul în care (text # 91; 0 # 93; == ';') continua

if (parse (text, g_clcmdName # 91; g_clcmdNum # 93; 31, g_clcmdCmd # 91; g_clcmdNum # 253;, 93, szFlags, 31, szAccess, 31)> 3)
în timp ce (înlocuiți (g_clcmdCmd # 91; g_clcmdNum # 93;, 253, "\", "") "^")
// nu fac nimic
>

g_clcmdMisc # 91; g_clcmdNum # 93; # 91; # 93 1; = Read_flags (szFlags)
g_clcmdMisc # 91; g_clcmdNum # 93; # 91; 0 # 93; = Read_flags (szAccess)
g_clcmdNum ++
>
>