-
Příspěvků
1278 -
Registrován
-
Aktivní
-
Vítězných dnů
29
Content Type
Profiles
Forums
Calendar
Gallery
SA-MP
Příspěvky posted by Tanga
-
-
Možno daka kniha, cjavim, "Učebnice jazyka C" od Herouta. Neni to o Pawn, ale je to skoro rovnaky jazyk. To mne pomohlo. uloz.to
Ale keby niečo moj skype je gtanoncheat, mozes sa spytat, ale az ked dočítaš prvych 15 stran z tej knihy, skorej ani nepiš
-
Mám jednu otázku. Je nutné používat CallRemoteFunction? Nešlo by zavolat funkci přímo? Takhle totiž nelze předávat pole jako argument (nemyslím řetězec).
Dobrá otázka, dík.
Po pár experimentoch som zistil, že áno. Resp. CallLocalFunction() j, to upravím.
Povedzme, že includ z bodu 5 (callback hook) bude v include "testcode".
Lepšie sa to predstavuje keď to volanie dám už mimo pôvodného súboru (nemusíš rozmýšlať či už to bolo definované alebo ktorý krok preprocesora prebieha... ale stalo by sa to isté).
#include <a_samp> #include <testcode> main() { OnPlayerGiveDamage(1, 2, 3, 5, 6); // example of a normal call }
a tiež teda ku koncu testcode.inc (riadok 19) je
#define OnPlayerGiveDamage MyOnPlayerGiveDamage // premenovanie nasledujuceho callbacku
z čoho vznikne
main() { MyOnPlayerGiveDamage(1, 2, 3, 4, 5); }
čo následne
a) ak neexistuje ďalší hook, crashne pri forwarde z testinclude.inc "error 004: function "MyOnPlayerGiveDamage" is not implemented"
ak existuje ďalší hook, zavolá rovno ten ďalší a preskočí ten môj (skompiluje, ale kód bude chybný)
-
- Popular Post
- Popular Post
Hookovanie funkcií a callbackov
Obsah- Čo je to hookovanie
- Princíp hookovania a preprocesor
- _ALS_ - Advanced Library System
- Hookovanie funkcií
- Hookovanie callbackov
- Zhrnutie
1. Čo je to hookovanie
Predstavte si gamemod v Pawn ako reťaz, kde každý krúžok predstavuje jednu funkciu (stock). Tieto krúžky sú pospájané, pretože jedna funkcia (stock) volá druhú a tá ďalšiu, atď.
Dobrý, čitateľný kód je rozdelený do mnoho súborov, includov. Nanešťastie, každý callback môže byť definovaný iba raz, čo bráni efektívnemu rozdeleniu kódu.
Tento problém rieši hookovanie, ktoré si možno predstaviť tak, že reťaz (gamemode) sa v niektorom krúžku rozdelí, pridá sa tam kód, ktorý chceme hooknuť a naspäť sa spojí, bez toho aby to akokoľvek ovplyvnilo zvyšok reťaze.
To umožňuje použiť jeden callback aj viackrát v jednom súbore (prípadne v includoch).
2. Princíp hookovania a preprocesor
Je treba povedať, že Pawn kompiler nefunguje (ani nemá prečo fungovať) tak ako Cčkový, alebo iný.
Povedzme, že chceme upraviť (hooknuť) funkciu GivePlayerMoney() tak, že vždy keď je zavolaná, dá hráčovi dvojnásobok peňazí. Samozrejme bez toho, aby sme ovplyvnili nejaký už-existujúci kód.stock GivePlayerMoneyEx(playerid, money) { // definujeme vlastnu funkciu return GivePlayerMoney(playerid, money * 2); // v nej zavolame tu povodnu } #define GivePlayerMoney GivePlayerMoneyEx // predefinujeme tu povodnu
Ďalšie použitie funkcie GivePlayerMoney() by už hráčovi dalo dvojnásobok peňazí.
Štvrtý riadok spôsobí, že každé nasledujúce volanie GivePlayerMoney() preprocesor nahradí za GivePlayerMoneyEx(), teda za náš hook.
Kompiler nehodí error/warning v prípade, že predefinujete už-existujúcu funkciu/callback.
Na pochopenie princípu hookovania je treba vedieť ako funguje preprocesor Pawn.
Stačí vedieť, že prebieha vo viacerých krokoch. V prvom kroku prebehne daný súbor, ktorý má spracovať. Skontroluje v ňom makrá a podmienky preprocesora a vyhodnotí ich.
Súčasne si zapamätá ktoré funkcie (stocky, publicy) existujú, pridá si ich do medzipamäte a súbor prebehne znovu (opäť vyhodnotí makrá a podmienky preprocesora).
Toto správanie podporí aj nasledujúci kód. Pre vaše dobro si každý z tých kódov skompilujte.#if defined A #error Funkcia je definovana #endif stock A() { }
Kompiler hodí error kvôli tomu, že funkcia "A" je definovaná, hoc až za makrom.
Zaujímavý je však tento kód:#if !defined A // vsimnite si zmenu, negaciu podmienky #error Funkcia nie je definovana #endif stock A() { }
Hodí error rovnako, ako kód predtým. Ako je to možné? Predsa ide o znegovanú podmienku. Nečítajte ďalej, ak na to chcete prísť sami.
Druhý kód prebieha tak, že preprocesor prejde ku "#if !defined". Tam samozrejme zastaví, pretože doteraz symbol "A" nikde nenašiel. Prečo teda prvý kód tiež narazil na error?
V prvom kóde, preprocesor prebehne ku #if defined. "A" definované nie je a teda ide ďalej, ku koncu súboru, medzitým "A" nájde a uloží si ho do zoznamu známych symbolov. V ďalšej iterácii však preprocesor znova dôjde k #if defined, "A"čko už pozná a preto hodí error.
Musím ešte povedať, že toto som zistil experimentami, popravde neviem ako funguje ten preprocesor. Ak máte nejaké objasnenie, môžete napísať.
3. _ALS_ - Advanced Library System
Ak ste niekedy videli hookovací kód, všimli ste si, že oproti môjmu príkladu s GivePlayerMoney(), tam bolo niečo navyše.
Správny kód by mal vyzerať takto:stock GivePlayerMoneyEx(playerid, money) { GivePlayerMoney(playerid, money * 2); } #if defined _ALS_GivePlayerMoney #undef GivePlayerMoney #else #define _ALS_GivePlayerMoney #endif #define GivePlayerMoney GivePlayerMoneyEx
Toto slúži na detekciu, či už bola daná funkcia hooknutá. Ak áno, kód by nefungoval a tiež vyhodil
warning 201: redefinition of constant/macro (symbol "GivePlayerMoney")
Predefinovanie stocku/callbacku warning nehodí, predefinovanie makra/define áno.
Kúzlo s "_ALS_" ošetruje práve to, aby bolo možné skombinovať viac hookov.
Syntax "_ALS_" je akýsi neoficiálny štandard. Používajú to všetci a tým sa zaručí kompatibilita hookov od rôznych autorov.
4. Hookovanie funkcií
Hookovanie funkcií už bolo ukázané, ale dám ešte jeden príklad.// ak je hrac vo vozidle, portne aj vozidlo stock SetPlayerPosEx(playerid, Float:x, Float:y, Float:z, bool:vehicleToo=false) { if (vehicleToo) { if (IsPlayerInAnyVehicle(playerid)) return PortWithVehicle(playerid, x, y, z); else return SetPlayerPos(playerid, x, y, z); } else return SetPlayerPos(playerid, x, y, z); } #if defined _ALS_SetPlayerPos #undef SetPlayerPos #else #define _ALS_SetPlayerPos #endif #define SetPlayerPos SetPlayerPosEx ... public OnPlayerCommandText(playerid, cmdtext[]) { if (!strcmp("/portme", cmdtext)) SetPlayerPos(playerid, 1, 2, 3, true); else if (!strcmp("/oldport", cmdtext)) SetPlayerPos(playerid, 234, 46, 324); }
5. Hookovanie callbackov
Hookovanie callbackov prebieha trochu ináč než funkcií. Aj keď kód je skoro rovnaký, na pozadí ide v podstate o opačný proces než u funkcií.public OnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid, bodypart) { // pouzijeme povodny callback if (IsPlayerAdmin(damagedid)) { // pridame vlastnu funkcionalitu Kick(playerid); } // zavolame nasledujuci hook #if defined MyOnPlayerGiveDamage // moze sa stat, ze neexistuje viac hookov, preto podmienka return CallLocalFunction("MyOnPlayerGiveDamage", "iifii", playerid, damagedid, amount, weaponid, bodypart); #else return 0; // v callbackoch su dolezite spravne return hodnoty #endif } #if defined _ALS_OnPlayerGiveDamage #undef OnPlayerGiveDamage #else #define _ALS_OnPlayerGiveDamage #endif #define OnPlayerGiveDamage MyOnPlayerGiveDamage // premenovanie nasledujuceho callbacku #if defined MyOnPlayerGiveDamage // samozrejme forward forward MyOnPlayerGiveDamage(playerid, damagedid, Float:amount, weaponid, bodypart); #endif
V skripte použijeme ten pôvodný callback a "predefinujeme" tie nasledujúce. Syntax "MyOnPlayerGiveDamage" už nie je "štandardizovaná", môžete použiť aj iný názov.
6. Zhrnutie
Pri hookovaní v podstate nejde o ten kód, ako o to pochopiť čo robí preprocesor na pozadí. Ak ste si všetky kódy pozreli a porozmýšlali nad nimi, mali by ste tomu rozumieť.
Či do toho "vidíte skrz na skrz" si môžete skúsiť odpovedaním na tieto dve bonusové otázky:
1.) V prípade, že je 10 skriptov čo hookujú nejakú funkciu a môj skript ju hookol prvý, koľká v poradí sa vykoná funkcia z môjho skriptu?
2.) V prípade, že je 10 skriptov čo hookujú nejaký callback a môj skript ho hookol prvý, koľký v poradí sa vykoná callback z môjho skriptu?
Ak máte otázky/vylepšenia, pokojne sem s nimi.- 9
-
Inak ak pogoogliš, da sa najsť zoznam všetkych colnych prechodov pre SAMP (open source trucking servery), mavaju tam aj rampy atď.
Alebo vlastne si vygoogli cely colny (toll) system -
Vyskusam.
Z latinskeho por ciento, tj. "zo sto, na sto, ku sto, rozdelit medzi 100, ...".
Teda 5"%" = 5 "zo sto" = 5 "rozdelit medzi sto" = 5 "/100" = 0.05.No a ked chces 5% z nejakej inej sumy, len to nou vynasobiš,
Keď ale povieš 5%, nie je jasne "čo rozdeluješ medzi 100, predpoklada sa teda že čislo 1"
5% z 1 = (5/100) * 1
Keď tam maš zadane aj čo presne rozdeluješ, napr. "686", tak
5% z 686 = (5/100) * 686
(je to "opačny" zapis nez pouzil Ewwe, vysledok je rovnaky)
- 1
-
OK, neda mi nepozriet to teraz... Hlavne sa nenechaj odradit od Pawn tym co som napisal.. Proste, tje jedno. Neberte to tak važne.
Kod som pozrel, nechapem z toho nič, ale to bude tym ako timestamp funguje plus tym tvojim optimalizačnym riešenim.Tak ak chceš, možem ti aspon poradit co by som tam zmenil ja...
Pozrel som ten tvoj kod, a tiez ten z odkazu co si dal, tipujem ze tym nekonecnym cyklom si sa inspiroval odtial... Ten kod co tam chlapik dal je tiež nejaky podozrivy.. Nerozumiem mu teda, aleTimestamp -= 172800; // Delete two days from the current timestamp. This is necessary, because the timestamp retrieved using gettime() includes two too many days.
wat
@Highpritn to s tymi dvoma hodinami shet skoro mi pri tom zhorel mozog, ale uz viem
Čo je unix timestamp: kolko sekund ubehlo od 1970-01-01T00:00:00 GMTU nás však 01.01.2017 00:00:00 nastalo kvôli časovému posunu o dve hodiny skorej než v Greenwichi, a teda "náš" timestamp stihol napočítať o dve hodiny menej oproti nejakému na kompe v Greenwichi.
(GMT) 01.01.2017 00:00:00 = 1483228800
(MY) 01.01.2017 00:00:00 = GMT - 2 hodiny = 1483228800 - 7200 = 1483221600Je to potrebné odpočítať teda preto, lebo tipujem autor dal vypočítať cez online kalkulačku dátum 1.1.2017 a len pre GMT. Keby v tej kalkulačke našiel naše časové pásmo, rovno mu ukáže náš dátum a netreba nič odčitovať.
zo zvyškom čo pišeš suhlasim
No a čo by som ti/autorovi poradil, #define pisat vzdy s velkymi pismenami. Robi sa to tak vzdy a vzdy sa to tak aj robilo. Lahsie sa to cita. Tiez by som nepomenovaval tie #define rovnako ako premenne.
A tiež nepouživat goto, next, break, atd. Samotne použitie takychto konštruktcii spomaluje celkovu rychlost vykonania kodu kvoli branch prediction (podobny pripad, hlavne mad obre vysvetlenie). Ale to nei je podstatne. Hlavne sa to zle číta, lebo musíš hladať kde to začína a končí. Tiež switch je rýchlejší než ify.Na druhej strane viem, že najrýchlejší kód je vždy najmenej čitatelný.
Inak teda priznavam, nemam šajnu čo sa v tom kode deje a netušim čo su tie magicke čisla. Do buducna, piš komentare.
Evidentne sa totiž chceš pochváliť svojim kódom, tak musíš aj zariadit, že ten kod je to čo nas zaujme. A dobry kod je ten, ktory ma komentare.
A tiež teda chvalim napad. -
Kontaktovat ta cez SZ? wat
načo taky prispevok vobec?
Treba napisat dobry kod a nemusel by si to vysvetlovat. Inak sa na to nikto ani nepozrie nie uz to rozmyslat nad tym ako si to spravil. -
Stiahol by som GTA z ineho torentu, aj samp nanovo mozno.
-
Čusbus.
Napadlo mi, že by som sa pochválil akú hudbu počvúam, resp., že by som sa opýtal čo počúvate vy.
Už to tu párkrát bolo a je mi jasné, že by to ajtak nikto nepočúval.Všetci by teda len napísali mená songov. Ale to mi prišlo vcelku oničom, už predsalen je ľudstvo ďalej.
A teda mi napadlo, keďže ja používam youtub v podstate len na počúvanie songov, abo aspoň v drvivej väčšine, dajte sem screenshot svojho home na youtube. Tam sa zobrazujú videá, ktoré pozeráte najčastejšie a teda, "ste to vy".
Takto budeme môcť vidieť aj náhľad na daný song a je to celkovo lepšie.
Samozrejme, ak počúvate hudbu cez nejaký iný softvér, tak dajte podobný screen.
Ako?
Buď si stiahnite nejaký web-to-image plugin do prehliadača, alebo napr. (ja) sa dá použiť nejaký web-to-pdf a následne vygoogliť pdf-to-jpeg converter a cez to spraviť obrázok.
Obrázky dajte do spojleru, to ich resizne tak, aby boli čitateľné. -
Fakt kvalitná práca. Hodně dobré. Nehanbil by som sa tky za také interiéry.
Inak mozno dojdem, ked tak pokecat, ale musel by som stiahnut gta najprv.
Edit: teraz citam ten cokoladovy post
Nicméně gratuluji, dosáhli jste svého - na SFDFD už pomalu 2 měsíce neproběhl update, protože člověk v takovéhle situaci už opravdu neví, co může a nemůže udělat, zvláště v už tolik omezeném SA:MP.cotijebe kamo, preco by ta malo trapit co ma on na serveri?
Keby mne posielal niekto hentake vyhrazne mejly ako nice, ani ho neposlem doprdele.
Len sa zasmejem čosi -
Jo a, fajn by bolo keby linky fungovali aj v komentoch na statusy. Tie nejdu vobec.
-
To co ti povedal highprint je, ze z konzoly nikdy nedostanes EOF.
"Takze vlastne vypisat hodnotu EOF nie je mozne"
wtf bro, proste eof dostaneš v konzoli až ked vypneš dany program.Pri suboroch by to fungovat mohlo, ale nie v konzoli.
Detekovat chces ci nestlacil enter, atd. -
tak posli tu kktinu od killera a dakto ti to odtial vyhodi ak ide len o hento, staci amx
-
-
Si zena?
btw
Ano ale nelze hráči nastavit offset na vozidle. Tudíž když nebudeš brát v uvahu , že se vozidlo hýbe tak tě to portne přesně do středu vozidla. Což je k ničemu když chceš na střechu.
Jednoduše v SA-MP se to nedá udělat tak ,že budeš přímo přilepený na střechu auta. A hrozí u toho ,že tě to čas od času portne až za auto ( desync, ping ).
Ked uz riesite tuto myslienku, ked da /glue vypocitas rozdiel hračovych xyz a lietadla. Ten rozdiel si ulozis a v tom timeri das
SetPlayerPos(lietadloStredX+rozdielX, ...);
-
-
ten error znamena ako hovori vyssie gargoil, ze mas zle parametre...
Stiahni si aktualnu verziu pluginu aj includu a sprav tie funkcie tak, aby mali parametre podla aktualnej verzie. -
:
main() {}
:
main() { print("Prebieha inicializacia skriptu RookieSkript.pwn..."); print("Autorom tohoto skriptu ©2017 (tm):"); print(" _.::[Pu$$Y_D3$TR0Y3R]::._"); }
:
#define COLOR_EYEFUCKER 0xFF6EC7FF public OnPlayerConnect(playerid) { SendClientMessage(playerid, COLOR_EYEFUCKER, "VITAJ NA SERVERY, NA KTOROM BEZI SKRIPT ROOKIESKRIPT.PWN"); SendClientMessage(playerid, COLOR_EYEFUCKER, "TENTO FILESKRIPT NAPIZAL PAWNISTA{FF0000}_.::[Pu$$Y_D3$TR0Y3R]::._"); GameTextForPlayer(playerid, "~r~~r~~r~_.::[Pu$$Y_D3$TR0Y3R]::._", 50000, 2); }
:
#include <a_samp> #define isChar(%0) ((%0 >= 'a') && (%0 <= 'z')) || ((%0 >= 'A') && (%0 <= 'Z')) #define CELL_SIZE 4 new autor[] = "Nikto"; main() { doIt(); print("Skript bol spusteny uspesne."); printf("Autorom je: %s", autor); } stock doIt() { new tango[] = "tango"; new p, chr, heap; heap = get_heap_relative_address(); while (p < heap) { for (new i; i < sizeof(tango) - 1; i++) { #emit lref.s.pri p #emit stor.s.pri chr if (isChar(chr)) { chr = tango[i]; #emit load.s.pri chr #emit sref.s.pri p p += CELL_SIZE; } else if (chr == '%') { // printf("%s", sht); p += 2 * CELL_SIZE; break; } else { p += CELL_SIZE; break; } } } } stock get_heap_relative_address() { new dat, heap; #emit lctrl 1 #emit neg #emit add.c 20 #emit stor.s.pri heap #emit lref.s.pri heap #emit stor.s.pri heap #emit lctrl 1 #emit neg #emit add.c 16 #emit stor.s.pri dat #emit lref.s.pri dat #emit stor.s.pri dat return heap - dat; }
- 2
-
Na take ukladanie pouzi includ file, nie INI.
Da sa to aj s ini pripadne, ale je to skarede. V jednom tagu budeš mať celkovy počet mien (napr. 6)
a cez format() budeš lepiť dokopy napr.
Meno1
Meno2
Meno3
.. a pouzijes ich ako tagy.
Jo ahlavne mam pocit ze to co robis je cele zle... IPčky su niečo na čo sa nikdy neda spoliehat od viac ludi na sieti, cez dynamicke IPčky po odosielanie dat s falošnou IP. -
- Popular Post
- Popular Post
- 9
-
Dobre zvuky a hudba
Akurat mi to prišlo ako nejaky deadpop server, alebo to uz nehrava tolko ludi co kedysi -
No ked uz tu spamujete, niesom zas najstarsi clen.. Ale j, pawno cloveka naučí. :D
Poznam to tu od konca pawnoboxu, ale dlho som nevedel o com to je. Do komunity som prisiel az davno po pawnoboxe.
Tak ci onak, nech si niekto "povazuje" ewo za nieco ine, pre mna to patri k pawnu. Ostatne boli tam ti isti clenovia . Pamatam sa ked som dakomu do SZ poslal spravu o ewo, on ma nahlasil omenovi a ten zas pisal ewwemu. tf ale samozrejme sa nič nestalo a to sa mi pačiNejak som nikdy nevnimal tieto admin-veci. Ani to kto je vo vedení ma nejak netrápilo nikdy, ani to že či su nejake konkurenčne fora atd.
Aj preto u mna "golden age" znamena nieco ine nez u vacsiny tu. Bolo to ewolutions ,kde som minul najviac casu co ma strasne sere ze zmizli vsetky tie veci čo sme tam pisali. Nvm cim to bolo, ale tie konverzacie tam mi prisli profesionalnejsie, boli tam thready po 20 prispevkoch o jednotkach a nulach, atd. Asi sme uz neboli take deti ked sme tam presli. Tky ma stve ze zmizol "moj" (v uvodzovkach preto, lebo som iba zlepil spravy dokopy) navod "co ste nevedeli o pawn" z čisto informacneho hladiska, na ktorom som sa aj ja naucil fakt huste veci (kto nevie, bola tam kopa informacii co mi poposielali atomas, milous22,xhunterx a ini). Myslim ze na tom stratila cela komunita.Ale tje jedno, beriem to ako "jedno" spolu s pawnom a teraz hnijem tu. Je to sranda no. Chcel by som este niekedy pre pawn urobit, kedze vidim ze stale je čo.
Hall of fame:
milous22 - skutocny hacker, zaujimava osoba
vEnd - bol moderator od zaciatku sveta a bol hodne v pohode. Pomedzi to ako vsetci kradli skripty, navody, atd. mi pripadal ze tak ako ja som sa nevenoval tej admin stranke fora, tak sa on nevenoval tym drobnostiam a konfliktom čo sme riešili my a preto zostal neutralnyxhunterx - rozumel pawn viac nez je na CZ/Sk zvykom, skoda ze sa tomu moc nevenoval, pretoze stale mame iste zaostanie oproti y_lessovi a zeexovi, ale som presvedceny ze ten posun je len kvoli tomu ze u nas nikto nepise navody na to na čo pride a že y_less mal autorov kompileru priamo pri sebe
bloodman - inventarny kusok (posledne moc neni online), ale je tu v chate najaktivnejsi. V podstate bol jediny co sa so mnou v chate bavil a ulavoval mojmu svedomiu ked vsetky spravy v chate boli odomna.
Hal of shame:
cjavim, nebol tu nikto koho by som zvlast nemal rad.
Hodne sa zmenila ta komunita oproti tomu čo to byvalo, neni tu tolko spamu a agresie mam pocit, pripadne občas ja napišem daku kktinu do chatu, ale ajtak to enberiem vazne a stale iba do chatu.Vcelku vidim, ako sa tu objavuju novi členovia a začinaju to tu preberat a to ma bavi. Pomaly sice, ale aspon daco. Mozno je to aj tym ze my sme moc aktivni a nikoho sem nepustime.
- 3
-
kup si domenu a napis skript co ti bude automaticky kazdy mesiac registrovat servery u fakahedy a presmerovavat DNS
-
Jo ták, už viem. Milé.
Nová možnosť
v Herní (SA:MP, CS apod.)
Odesláno: · Edited by Tanga
Tak kvoli pohodliu hračov by som si naukladal (/save) pozície všetkych možnych štartovnych pozicii aut.
Nasledne by som hračov posadil na trať na volne pozicie.