Uopsteno o skriptanju.

Započeo .Drakula., Jun 19, 2022, 16:27:34 POSLE PODNE

prethodna tema - sledeća tema

0 članova i 1 gost pregledaju ovu temu.

Pitanje/savjet: Da li ima potreba vrsiti dodatne provere ili ti iste provere vise puta. Videcete u primerima ispod. Milion puta sam video istu stvar da nekolicina radi.
Mislim da ce ova tema pomoci vecini ljudi.

Opširnije:
PRIMER 1
Ako ima u skripti:

public OnPlayerCommandReceived(playerid, cmd[], params[], flags)
{
   if(UlogovanIgrac[playerid] == 0)
   {
      Error(playerid, "Niste ulogovani.");
      return 0;
   }
   else if(PI[playerid][pAdmin] < 1 && PI[playerid][pHelper] < 1 && ACCmd[playerid] == 1)
   {
      Error(playerid, "Komande mozete koristiti svake 2 sekunde.");
      return 0;
   }
   CmdProtect(playerid);
   return 1;
}

Zasto koristiti ovako:

CMD:unprison(playerid, params[])
{
    if(IsPlayerConnected(playerid))  // ZASTO JER IGRAC MORA BITI KONEKTOVAN DA BI BIO ULOGOVAN
    {
           if(UlogovanIgrac[playerid] == 0) return Error(playerid, "Niste ulogovani.");  //ZASTO PONOVO PROVERA DA LI JE ULOGOVAN
           .....
           ....
           ....
   }
   return 1;
}


PRIMER 2
Provere u dialozima:

CMD:fveh(playerid, params[])
{
   if(PI[playerid][pAdmin] < 1 && PI[playerid][pHelper] < 1 && PI[playerid][pPromoter] < 1 && PI[playerid][pVIP] < 1) return Error(playerid, "Upisali ste komandu koja ne postoji.");
   .....
   .....
   .....
   if(PI[playerid][pPromoter] > 0 || PI[playerid][pVIP] > 0)
   {
      ....
      ...
      ...
   }
   else if(PI[playerid][pHelper] > 0) SPD(playerid, D_FIXVEH, DSL, "0, 1", D_POTVRDI, D_ZATVORI); //case 0: case1:
   else if(PI[playerid][pAdmin] < 4 || PI[playerid][pHelper] > 1) SPD(playerid, D_FIXVEH, DSL, "0, 1, 2", D_POTVRDI, D_ZATVORI); //case 0: case1: case:2
   else if(PI[playerid][pAdmin] > 3) SPD(playerid, D_FIXVEH, DSL, "0, 1, 2, 3", D_POTVRDI, D_ZATVORI); //case 0: case1: case2:case3:
   return 1;
}


Zas u dialozima raditi dodatne bezpotrebne provere:

   else if(dialogid == D_FIXVEH && response)
   {
       switch(listitem)
       {
           case 0:
           {
               if(PI[playerid][pAdmin] > 0 || PI[playerid][pHelper] > 0) //zasto
               {
                  ...
                  ....
                  ....
                  ....
            }
            else return Error(playerid, "Niste ovlasceni.");
           }
           case 1:
         {
             if(PI[playerid][pAdmin] > 0 || PI[playerid][pHelper] > 0) SPD(playerid, D_FIXVEH_ID, DSI, "", D_POTVRDI, D_ZATVORI);
            else return Error(playerid, "Niste ovlasceni.");
         }
         case 2:
         {
             if(PI[playerid][pAdmin] > 0 || PI[playerid][pHelper] > 1) SPD(playerid, D_FIXVEH_RADIUS, DSI, "", D_POTVRDI, D_ZATVORI);
            else return Error(playerid, "Niste ovlasceni.");
         }
           case 3:
           {
             if(PI[playerid][pAdmin] > 3)
             {
                ....
                ....
                ....
                .....
            }
            else return Error(playerid, "Niste ovlasceni.");
         }
       }
   }


Dodatno: Zasto raditi takve provere ponovo ako nije potrebno. Primer u dialozina, u komandi je odredjeno KO MOZE DA KORISTI KOMANDU i KOME CE SE KOJI case PRIKAZATI i zasto u dialogu ponovo proveravati ako se igracu nece raditi komanda ili se nece prikazati taj case dialoga.
Poslednja Izmena: Jun 22, 2022, 17:49:15 POSLE PODNE od Deleted User

Prvo za proveru da li je ulogovan. Ukoliko vazi za sve komande, dovoljno je u callback dodati proveru i onda vise ne treba u komandama.

Dialozi su druga stvar zbog nacina na koji rade u samp-u, a to je da server prikaze igracu dialog, posalje mu njegov sadrzaj i ID. Igrac onda odabere sta hoce, i posalje serveru odgovor koji sadrzi input (bilo text, password ili listitem), akciju i ID dialoga. Pri cemu koristeci razne cheatove ili jednostavno u nekoj nestandardnoj situaciju ako je neki bug u pitanju, igrac moze odgovoriti na dialog koji mu nije ni bio prikazan. Tako da provera i u dialogu i u komandi je potrebna.


To receno, u praksi uvek validujes i saniras sve sto treba. Ako funkcija ima playerid argument, i ti koristis taj argument u nekom nizu, uvek moras da ga validujes, i nije bitno sto ces to uraditi lancano 5x. Radije validuj nego da dobijes crash ili jos nesto.
Uvek postoje situacije kad mozes da preskocis validaciju i sanaciju input-a, ali u 99.9% slucajeva nije opravdano preskociti ih posto ne uticu na performanse.

Citat: Deleted User poslato Jun 19, 2022, 17:26:49 POSLE PODNE
ali u 99.9% slucajeva nije opravdano preskociti ih posto ne uticu na performanse.

Sve utice na performanse samo sto je praska na Balkanu da se mikrooptimizuju nebitne stvari.

Sto se tice primjera 2, kao sto je Deleted User rekao, citovi postoje.. Cak sta mislim da ako nemas nikakvu protekciju mozes slobodno da saljes RPC SendDialogResponse. Druga situacija koja moze da se desi je da se nekome skine admin/helper dok su oni u dialogu.

Nisam znao za dialoge.
Logicno mi je da se ne moze prikazati dialog igracu ako ne moze uopste da ga pozove..

Ima li potrebe raditi nesto ovako:


CMD:atp(playerid, params[])
{
new gotoid;
if(sscanf(params, "u", gotoid)) return Cmd(playerid, "/atp [ ID ]");
if(gotoid == INVALID_PLAYER_ID) return Error(playerid, "Igrac nije na serveru."); //zar nije isto
if(UlogovanIgrac[gotoid] == 0) return Error(playerid, "Taj igrac nije prijavljen."); // zar nije isto
....
....

Citat: .Drakula. poslato Jun 20, 2022, 19:59:04 POSLE PODNE
Nisam znao za dialoge.
Logicno mi je da se ne moze prikazati dialog igracu ako ne moze uopste da ga pozove..

Ima li potrebe raditi nesto ovako:


CMD:atp(playerid, params[])
{
   new gotoid;
   if(sscanf(params, "u", gotoid)) return Cmd(playerid, "/atp [ ID ]");
   if(gotoid == INVALID_PLAYER_ID) return Error(playerid, "Igrac nije na serveru."); //zar nije isto
   if(UlogovanIgrac[gotoid] == 0) return Error(playerid, "Taj igrac nije prijavljen."); // zar nije isto
   ....
   ....

Posto se interesujes za razliku od nekih, cisto da objasnim ako slucajno ne znas: SSCANF - String SCAN Format
Funkcija sscanf-a je da uzme string i validuje njegov format onome koji mi ocekujemo. U ovom slucaju ocekujemo u - User. User moze biti ime (string) ili ID (integer). Ako prosledis u params 5, to jest id igraca 5, ne znaci da je taj igrac konektovan, ali jeste validan format u ovom slucaju. Ako prosledis Ime ili deo imena, opet, ne znaci da je igrac validan, ali jeste validan format. Ako prosledis 5.0 (float), format nije validan, sscanf ce da vrati 1, i ti ces vratiti error (Cmd funkciju).

E sad, ako je input format validan, mi ne znamo da li je igrac validan, zato se i proverava da li je jednak INVALID_PLAYER_ID. Inace ovo bi bilo pravilnije da se proveri sa IsPlayerConnected, ali sa sscanf ne znaci posto sscanf trazi u listi konektovanih igraca pa samim time nikad nece vatiti onog koji nije konektovan tako da je dovoljno da se uporedi sa INVALID_PLAYER_ID.

E sad tek kad si proverio da je id igraca validan, tek onda proveravas da li je ulogovan, posto ako je validan to jest konektovan ne znaci da je ulogovan. I ovo je bitno, zato sto da si to proveravao pre, igrac bi mogao biti INVALID_PLAYER_ID koji je vracen iz sscanf posto nije nadjen, a to je id 65535. I to bi onda znacilo da pokusavas da procitas iz 65535 elementa niza koji ne postoji posto verovatno imas definisamo UlogovanIgrac[MAX_PLAYERS] gde ti MAX_PLAYERS nikad nece biti preko 1000 posto je to limit samp-a.


Tako da sve tri provere su razlicite i potrebne. Prvo koritis sscanf da dobijes ID igraca (bilo da prosledis ID, bilo da prosledis ime pa da sscanf pokusa da nadje id), onda proveravas da li je sscanf nasao ID igraca (to jest da li je id validan posto sscanf vraca INVALID_PLAYER_ID ako ne nadje), i tek onda proveravas da li je igrac ulogovan, posto ako je konektovan ne znaci da je i u ulogovan (mozda se tek sad neko connect sa nikom koji postoji a to uopste nije njegov account pa nece ni moci da se login).

Citat: .Drakula. poslato Jun 20, 2022, 19:59:04 POSLE PODNE
Logicno mi je da se ne moze prikazati dialog igracu ako ne moze uopste da ga pozove..

Zamisljaj.. Ti si helper i kucas komandu dostupnu helperima /teleport. U medjuvremenu, dok si ti i dalje u dialogu i biras lokaciju dokle ces ici, ja ti skidam helpera. Problem nastaje sto ti i dalje imas otvoren dialog za teleport iako nisi helper i, s obzirom na to, mozes da se teleportujes na lokaciju koja ti je dostupna kao helperu (a ti to u tom trenutku vise nisi) ukoliko nema provjera u samom OnDialogResponse.

PS. Ovakve situacije su jako rijetke (zapravo mi se nikada nije ni desila jedna za ~10 godina igranja SAMPa) tako da te provjere mozes slobodno izbjegavati.

Hvala puno momci.
Ne znam gde pitati ovakve stvari da otvorio temu.
Ima ni negde gde ja mogu citati ovakve stvari da ne bi morao da otvaram teme.

Ironicno, ovo je forum gde bi trebale da budu takve stvari, ali posto je stanje takvo kakvo je, imamo previse ljudi koji bi sve sad i odma i koji ne zele da nauce nego bi samo da drugi umesto njih odrade sve onda nemozes naci takve stvari.

Ali ovo su ti vecinom principi/osnove programiranja i cista logika. Dokumentacija tu i tamo, sve zavisi od jezika do jezika i onoga sta radis u njemu, neki su vise dokumentovani, neki manje sve zavisi od popularnosti.
Kad naucis osnove, promenive, nizove, funkcije, petlje, onda sve ide lakse posto razumes sta kod radi, i kako da koristis ono sto imas da bi postigao ono sto zelis.

Da bi znao mogucnosti necega moras biti duze vreme u tome, tako je i u samp-u, u sustini stices iskustvo, saznajes za sta postoje funkcije i od toga pokusavas da sklepas ono sto si zamislio. Kako saznajes mogucnosti tako ujedno saznajes i limitacije posto uvek naleces na probleme (programiranje i jeste resavanje zadatog problema).

Ali sto se tice ovakvih tema, slobodno otvaraj, forum je za ovakve stvari, da naucis sam i preneses svoje znanje dalje. Da vise ljudi pokusava nauciti kao i ti, da se interesuje i ponasa normalno ova zajednica bi napredovala a ne degradirala kao sto je trenutno slucaj.

EDIT: Zakljucacu temu posto si dobio odgovore na pitanja, i tema je nekativna. Ukoliko treba da se odkljuca, PM me, ili otvori novu temu, nije problem kad to radis ljudski.
Poslednja Izmena: Jun 22, 2022, 17:48:49 POSLE PODNE od Deleted User