Debugging

Započeo Edo., Decembar 17, 2017, 22:22:59 POSLE PODNE

prethodna tema - sledeća tema

0 članova i 1 gost pregledaju ovu temu.

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
••• Nexus Project Community •••
• Founder & Developer •

Trebao si kodove u [pawn][/pawn]


http://wiki.sa-mp.com/wiki/Debugging

Mogao si ostaviti izvor
Poslednja Izmena: Decembar 18, 2017, 00:18:37 PRE PODNE od Ino42O
Software Developer

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.
Oduvek sam se pitao:
"Zbog cega se ljudi toliko brinu jedni za druge?",
"Zasto ljudi daju sve od sebe da usrece neku osobu?"

Najjednostavnije receno brinu se jer vole tu osobu celim svojim srcem,
daju sve od sebe da je usrece zbog toga sto ne zele da je ikada vide tuznom ili rasplakanom.
#xsarnaaparatima..

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

••• Nexus Project Community •••
• Founder & Developer •

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
••• Nexus Project Community •••
• Founder & Developer •