1. Uvod
Å to je debuging?
Debuging je proces dodavanja privremenih (ili ponekad stalnih) poruka u kod kako bi se dobio vizualni prikaz procesa skripte.
Kako mogu ispraviti pogrešku?
PogreÅ¡ke u kodu mogu uzrokovati zaustavljanjem koda kod pogreÅ¡ke i preskoÄiti ostatak koda, ili Äak i zaustaviti ili zamrznuti server. Ove pogreÅ¡ke ne preuzima compiler, jer nisu pogreÅ¡ke prilikom sastavljanja skripte. Primjer pogreÅ¡ke se mogu naći u nastavku.
Može biti teško identificirati i pronaći pogrešku u velikim skriptama.Ovo je tutorial kako ispraviti to :D
Primjer
U ovom primjeru kod neće uzrokovati zamrzavanje ili pad s poslužitelja, ali će uzrokovati zaustavljanje koda pri pogreÅ¡ci, ostavljajući ostatak koda neizraÄ'enim.
new pKillStreak[MAX_PLAYERS]; // Igracev trenutni ubica
new pKillStreakReward[MAX_PLAYERS][5]; // 5 killstreakova se moze uÄoretijebiti po igracu
public OnPlayerDeath(playerid, killerid, reason)
{
if(killerid != INVALID_PLAYER_ID) // If it wasn't suicide, handle the kill
{
new string[128], pName[MAX_PLAYER_NAME], kName[MAX_PLAYER_NAME];
GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
GetPlayerName(killerid, kName, MAX_PLAYER_NAME);
format(string, sizeof(string), "%s (%i) was killed by %s (%i). Reason: %i.", pName, playerid, kName, killerid, reason);
SendClientMessageToAll(COLOR_DARKRED, string);
pKillStreak[killerid]++; // Add one to the killstreak
if(pKillStreak[killerid] == 7) // 7 streak - Give attack helicopter
{
pKillStreakReward[killerid][pKillStreak[killerid]]++; // Add one to "attack helicopter" count (slot 7)
SendClientMessage(killerid, COLOR_GREEN, "[7 KILLSTREAK] - Attack helicopter ready for deployment.");
}
SetPlayerScore(killerid, GetPlayerScore(killerid)+pKillStreak[killerid]); // If they had a 5 killstreak, they'd get 5 score.
GivePlayerMoney(killerid, 1000*pKillStreak[killerid]); // If they had a 5 killstreak they'd get $5000
}
return 1;
}
Sada to nije najdulji dio koda koji je ikada napisan, ali je kratak da bi se izbjegla zbrka. Pokretanje tog koda i dopuÅ¡tajući igraÄu da dobije 7 killstreak zaustavit će kod pogreÅ¡ke (Å¡to će biti navedeno u nastavku). Zbog toga kôd na dnu koji daje rezultat i gotovinu neće se izvrÅ¡iti.
Dodavanje poruka o uklanjanju pogrešaka
Debug poruke obiÄno se dodaju pomoću ispisa () (ili printf ()) ili klijentovih poruka. Za jednostavnost koristit ćemo ispis (). Da biste dodali poruke o uklanjanju pogreÅ¡aka, trebate postaviti ispis () poruke svakih nekoliko redaka izmeÄ'u koda, a zatim pokrenuti kôd. Posljednji ispis () koji će se pojaviti na poslužitelju_log pomoći će vam pronaći kod koji uzrokuje problem gledanjem kod izmeÄ'u navedenog ispisa i sljedećeg.
Ovo je kod s dodavanjem pogrešaka:
new pKillStreak[MAX_PLAYERS];
new pKillStreakReward[MAX_PLAYERS][5];
public OnPlayerDeath(playerid, killerid, reason)
{
printf("OnPlayerDeath(%i, %i, %i)", playerid, killerid, reason);
if(killerid != INVALID_PLAYER_ID)
{
print("OnPlayerDeath: killerid valid");
new string[128], pName[MAX_PLAYER_NAME], kName[MAX_PLAYER_NAME];
GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
GetPlayerName(killerid, kName, MAX_PLAYER_NAME);
print("OnPlayerDeath: names stored");
format(string, sizeof(string), "%s (%i) was killed by %s (%i). Reason: %i.", pName, playerid, kName, killerid, reason);
SendClientMessageToAll(COLOR_DARKRED, string);
print("OnPlayerDeath: message sent");
pKillStreak[killerid]++;
printf("OnPlayerDeath: pKillStreak is now %i", pKillStreak[killerid]);
if(pKillStreak[killerid] == 7) // Attack helicopter
{
print("OnPlayerDeath: 7 killstreak - give attack heli");
pKillStreakReward[killerid][pKillStreak[killerid]]++; // Add one to the count for the current killstreak (for multiple attack helicopters stored)
print("OnPlayerDeath: 7 killstreak - added one to pKillStreakReward for attack heli");
SendClientMessage(killerid, COLOR_GREEN, "[7 KILLSTREAK] - Attack helicopter ready for deployment.");
print("OnPlayerDeath: end of attack heli");
}
print("OnPlayerDeath: Giving score...");
GivePlayerScore(killerid, pKillStreak[killerid]); // If they have a 5 killstreak, give them 5 score.
print("OnPlayerDeath: Score given. Giving cash...");
GivePlayerMoney(killerid, 1000*pKillStreak[killerid]); // If they have a 5 killstreak give them $5000
print("OnPlayerDeath: Cash given.");
}
print("OnPlayerDeath: FINISHED");
return 1;
}
server_log.txt će to prikazati kada igraÄ dobije 7 ubica:
Kao što vidite, postoje funkcije ispisa koje se koriste u cijelom kodu. Kada se kôd izvrši, ispisati poruke o pogreškama na konzolu poslužitelja (i server_log.txt). Tada možete pronaći problem.
[timestamp] OnPlayerDeath(1, 2, 3)
[timestamp] OnPlayerDeath: killerid valid
[timestamp] OnPlayerDeath: names stored
[timestamp] OnPlayerDeath: message sent
[timestamp] OnPlayerDeath: pKillStreak is now 7
[timestamp] OnPlayerDeath: 7 killstreak - give attack heli
But there's nothing after that?! What happened? The script stopped. Lets take a look at the code that is after the final print ('OnPlayerDeath: 7 killstreak - give attack heli'):
if(pKillStreak[killerid] == 7) // Attack helicopter
{
print("OnPlayerDeath: 7 killstreak - give attack heli");
pKillStreakReward[killerid][pKillStreak[killerid]]++; // <<<<<< THIS IS THE PROBLEM
print("OnPlayerDeath: 7 killstreak - added one to pKillStreakReward for attack heli");
SendClientMessage(killerid, COLOR_GREEN, "[7 KILLSTREAK] - Attack helicopter ready for deployment.");
print("OnPlayerDeath: end of attack heli");
}
Postoji samo jedna linija koda izmeÄ'u konaÄnog ispisa koji je pronaÄ'en u server_log.txt i sljedećem, koji je
pKillStreakReward[killerid][pKillStreak[killerid]]++;
Ovo je problem. PKillStreakReward ima samo 5 ćelija, ali pokuÅ¡avamo postaviti osmo mjesto, budući da pKillStreak [killerid] je 7 (polja poÄinju na 0, tako da je 7 u 8.). To se dogaÄ'a:
pKillStreakReward [killerid] [7] ++; // Dodaj jedan u "napada helikopter" count
[Uredi]
Što je sljedeće?
Nakon Å¡to pronaÄ'ete problem, morate upotrijebiti svoje znanje kako biste ga rijeÅ¡ili (ili zatražite pomoć na forumima SA: MP).
"Glavni debuging"
Ako se poslužitelj pada u sluÄajnim vremenima, morat ćete ispraviti cijelu skriptu. Iako ovo na poÄetku može izgledati zastraÅ¡ujuće, kada znate Å¡to da radite, to zapravo ne. To je bilo uzrokovano povratnim pozivom ili timerom. Ono Å¡to trebate uÄiniti je staviti ONE print () na prvu liniju svakog povratnog poziva, na primjer:
public OnPlayerDeath(playerid, killerid, reason)
{
print("DEBUG: OnPlayerDeath");
// code
// code
// code
// code
// code
// code
// code
// code
// code
// code
return 1;
}
Zatim, kada poslužitelj padne, jednostavno pogledaj zapisnike i vidi koja je povratna poziva zadnja. Koji je posljednji ispis tiskan, je povratni poziv koji sadrži pogrešku. Potom možete ponovno otkloniti taj poziv, kao u prvom primjeru.
To je sliÄno onome Å¡to možete oÄekivati ​​u server_log.txt:
[16:49:54] OnPlayerStreamIn
[16:49:54] OnPlayerStateChange
[16:49:54] OnPlayerRequestClass
[16:49:54] OnPlayerRequestClass
[16:49:54] OnPlayerStateChange
[16:49:54] OnPlayerSpawn
[16:49:54] OnPlayerDeath
To je naznaÄilo da neki kod u OnPlayerDeathu uzrokuje ruÅ¡enje poslužitelja.
U nekim sluÄajevima, možda želite ispisati parametre povratnog poziva, za to se printf može koristiti tako:
public OnPlayerDeath(playerid, killerid, reason)
{
printf("DEBUG: OnPlayerDeath(%i, %i, %i)", playerid, killerid, reason);
// code
// code
// code
// code
// code
// code
// code
// code
// code
// code
return 1;
}
BeskonaÄne petlje
Drugi Äesti izvor poslužitelja zamrzava beskonaÄne petlje. dok () može uzrokovati neprekidnu, beskonaÄnu petlju koda koja će zaustaviti poslužitelj da obradi viÅ¡e uputa. Evo primjera beskonaÄne () petlje:
new var = 5; // Create a variable and set it to 5
while(var != 3) // If it's not 3
{
var++; // Add one to it
}
To će uzrokovati beskonaÄnu petlju, jer varijabla nikada neće biti postavljena na 3!
[Uredi]
Poruke klijenta
Kroz ovaj tutorial korišteni su funkcije ispisa i ispisa koji ispisuju tekst na konzolu poslužitelja / zapisnike. Ovo nije uvijek najkorisnija funkcija za upotrebu, kao što biste trebali ići u igri, testirati kôd, a zatim smanjiti da biste provjerili konzolu / zapisnike.
Ovo je mjesto gdje SendClientMessage može biti korisnije, ili možda Äak i textdraws ili igra-tekst. Morat ćete koristiti format, za razliku od printf gdje možete odrediti varijable nakon stringa.
Na primjer, ovaj kod konstantno će prikazati varijablu za igraÄa u OnPlayerUpdateu, pa možete vidjeti je li sluÄajno promijenjen:
new pVariable[MAX_PLAYERS]; // Just used for this example
public OnPlayerUpdate(playerid)
{
new debugStr[32];
format(debugStr, sizeof(debugStr), "~W~pVariable: ~Y~%i", pVariable[playerid]);
GameTextForPlayer(playreid, debugStr, 3000, 3); // Use style 3 always, the rest aren't great for this. Style 5 will refuse to show after a few seconds
}
Or if you wanted to know what a player's variable was when they passed through a race checkpoint:
new pCP[MAX_PLAYERS]; // The current checkpoint the player can see in the race
public OnPlayerEnterRaceCheckpoint(playerid, checkpointid)
{
pCP[playerid]++;
new debugStr[18];
format(debugStr, sizeof(debugStr), "Checkpoint: %i", pCP[playerid]);
// Show next checkpoint, handle finishline etc.
return 1;
}
Eto to bi bio kraj tutoriala,nadam se da ste shvatili ovo :D
Trebao si kodove u [pawn][/pawn]
Citat: Wucha poslato Decembar 17, 2017, 23:31:36 POSLE PODNE
Trebao si kodove u [pawn][/pawn]
Dobro ti kaze Wucha, @tema odlicno.
http://wiki.sa-mp.com/wiki/Debugging
Mogao si ostaviti izvor
Cim sam video da pise sledece:
Citat: pogreškepogreške i posluzitelj
Odma sam shvatio da ti nisi bilo sta od ovoga napisao. Kao sto Ino420 kaze mogao si barem ostaviti izvor.
Citat: Raptorâ,,¢ poslato Decembar 18, 2017, 00:34:41 PRE PODNE
Cim sam video da pise sledece:
Citat: pogreškepogreške i posluzitelj
Odma sam shvatio da ti nisi bilo sta od ovoga napisao. Kao sto Ino420 kaze mogao si barem ostaviti izvor.
@Raptorâ,,¢ Ja nisam rekao da sam ja pisao samo sam preveo jer ne znaju svi engleski,eli eto nek doda moderator gore izvor
Takodje vidi se da je google translate,dosta nejasnih stvari :) Tutorijali služe da se nauÄi neÅ¡to,a evo ja nakon Äitanja ovog tutorijala znam puno manje nego Å¡to sam znao dosad xD
Citat: Paul Castellano poslato Decembar 18, 2017, 13:39:41 POSLE PODNE
Takodje vidi se da je google translate,dosta nejasnih stvari :) Tutorijali služe da se nauÄi neÅ¡to,a evo ja nakon Äitanja ovog tutorijala znam puno manje nego Å¡to sam znao dosad xD
@Paul Castellano Jako duhovito s tvoje strane :D