Ez a szekció lehetővé teszi a felhasználó által írt összes hozzászólás megtekintését. Vedd figyelembe, hogy csak azokba a fórumokba írt hozzászólásokat látod, amelyekhez hozzáférésed van. 31
Képek / Videók / Board James - legjobb kisfilm ever« Dátum: 2013. Április 04. - 18:49:50 »
Ezt most azonnal meg kell néznetek. Nem akarom lelõni a poént:
32
Általános / Rougelike Dungeon-Crawler« Dátum: 2013. Március 02. - 21:16:21 »Ez a már korábban ismertetett telnet-SAMP hibrid továbbfejlesztése: samp plugin segítségével rougelike dungeon-cralwer: a pályát véletlenszerûen generálja. Ez egy debug mód, a valósban a labirintusnak csak egy része (a player körüli, alapértelmezettként 5x5-ös terület), ez elég nagy, hogy egy szobában kb. elláss, de nem elég nagy, hogy minden szörnyet ki tudj védeni. X: kõfal, a pálya széle + (kék): sárfal, a termek széle + (piros): ajtók #: járatok ( : kincs . : padló T: (egyelõre debug) csapda k: kulcs (egyelõre nincs hasznuk) <: feljárat (pálya kezdete) >: lejárat (pálya vége, új pálya generálása) @: játékos A játék menti a statisztikáid (sqlite), amiket ki is ír a pálya aljára (debug módban ez sem látszik). A csapdák léte titok, sokfajta lehet (a nagy T csak a debug miatt van úgy). A lejárat (a következõ pályára vezetõ warp) látható a betöltési táv kétszeresérõl, tehát ha jó nyomon vagy, megtalálhatod hamar. A feljárat (spawn-hely) a térképen folyamatosan látszik, így tájékozódási pontot nyújt, ha esetleg eltévednél (elég nehéz, annyira azért nem jó az algoritmus). 33
Fórum Archívum (Témák/Fórumok) / Re:Melyik tetszik jobban? Város vagy falu?« Dátum: 2013. Március 02. - 21:07:50 »
[mod]x+1. ilyen téma, zárok[/mod]
34
Fórum Archívum (Témák/Fórumok) / Re:Mit nem lehet megcsinálni...« Dátum: 2013. Március 01. - 06:17:20 »Idézetet írta: Anthony date=1362106910\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"34366\" data-ipsquote-contentclass=\"forums_Topic Nekem ér válaszolni?Költõi kérdés volt (amúgy legelsõ sor) Ahhoz képest, hogy Kye nem akarja \"játékmotorrá\" tenni a SAMPot, a pluginokkal el tudnám képzelni, hogy valaki egyszer ír egy SAMP webszervert. 35
Fórum Archívum (Témák/Fórumok) / Mit nem lehet megcsinálni...« Dátum: 2013. Február 28. - 21:32:02 »
Vajon melyik szerver alkalmazásból lett átalakítva ez a telnettel játszható szöveges kalandjáték :hmmm:?
36
Beszélgetés / TAS« Dátum: 2013. Február 09. - 14:32:28 »
Mi a véleményetek a TAS végigjátszásokról? (Aki nem tudná: a TAS egy olyan speedrun, tehát gyors végigjátszás, amiben emulátor, glitchek, frame-by-frame trükkök és egyéb dolgok segítségével méggyorsabb eredményeket érnek el. Természetesen az emulátoros gyorsítások/throttlek és a frameskip nem játszik. Ha SAMP hasonlatba akarnám helyezni, akkor parkour / dm glitchek kategóriájában van.)
Rockman 12 perc 21.34 másodperc alatt. Ha valaki már játszott vele, az tudja, hogy irtózatosan nehéz játék, mondjuk a TAS-ban lazán levágják a pályák háromnegyedét glitchek segítségével. SMB3, 10:25.6 alatt. Ez meg egy 8 világos játék (mondjuk síppal lehet csökkenteni a világok számát). Ez nem egy videó topic, csak egy beszélgetés, hogy szerintetek van-e létjogosultsága az ilyen videóknak, valamint hogy mi a véleményetek róluk. 37
Tanuljunk PAWN nyelvet / Új hooking method« Dátum: 2013. Január 13. - 08:38:09 »
CREDITS
Ez nem az én munkám, és csak egy rövid tutorial lesz. A hivatalos fórumon ipsBruno jött rá erre az új fajta hooking methodra. Az érdekesség az, hogy senki se tudja, hogy mûködik, mivel az #if defined ág a függvény létrehozása elõtt található: tehát akkor még nem is létezett. De mûködik. A MÓDSZER Ismerjük (vagy nem) a y_hookot, az _ALS módszert, az automatás verziót, CallLocalFunction-os verziót, és még rengeteg mást, amivel függvényt lehet hookolni. Ha valaki nem tudná, mi az, valami ilyesmit kell elképzelni:
Azt akarjuk, hogy a fenti függvény az OnGameModeInit lényegi lefutása elõtt fusson le. A legegyszerûbb, és sokak által mai napig használt módszer a következõ:
Ez szép és jó, de könnyen találhatunk hiányosságokat is: például mindig bele kell írni a kódba, és mindig a GameModeInit legelsõ soraként. Ez több hasonlóan beágyazott függvénykönyvtárnál problémás lehet. Na: erre talált egy új modszert a fenti fórumozó:
A GM-ben pedig meghívjuk a következõt:
Ezzel ugyanazt a hatást értük el, elõször a \"Streamer betöltve!\" majd a \"Játékmód betöltve!\" kimenet jelenik meg. A legjobb az egészben az, hogy akkor is mûködik, ha sosem hívódott meg a játékmódban az OnGameModeInit, nem warningol, és persze, hogy nem használ sem automatát, sem CallLocalFunctiont, mivel az egész direktívákból áll, a fordítónak szinte semmi dolga nincs az egésszel: amitõl hihetetlen gyors lesz. 38
Fórum Archívum (Témák/Fórumok) / (Leírás) Az AMX és az AMX-memóriatérkép« Dátum: 2013. Január 12. - 10:09:51 »
KEZDJÜK A RIZSÁVAL
Igen, tudom, hogy van egy teljesen ugyanilyen leírás a hivatalos fórumon, és azt is, hogy ugyanazt fogom gyakorlatilag elmondani kétszer. Viszont fontosnak érzem, hogy azt az alapot kicsit felturbózzam, és megérthetõvé tegyem azok számára is, akik esetleg nem értik elsõre, hogy mi az a LIFO, heap, stack, és a többi. Épp ezért, és az emészthetõség miatt nem állt szándékomban a formális szaknyelv használata. Ez után pedig térjünk rá, hogy ez a cikk lényegében kinek jó: akit érdekel. Ettõl a módod gyorsabb nem lesz, kevesebb bug biztos nem lesz benne, nem is lesz stabilabb, tehát tényleg csak azoknak ajánlom, akiket érdekel, hogy valójában hogy is fut le a kódjuk, amit írnak. AMX Mint ahogy az a deAMX topicban is elhangzott, az AMX rövidítés jelentése Abstract Machine Executor, vagyis absztrakt gép végrehajtó, értve ez alatt azt, hogy ez az a kód, amivel az absztrakt gép végrehajtja az utasításokat. AZ ABSZTRAKT GÉPEK Mi is egy absztrakt gép? Mint azt bizonyára mindenki tudja, a legfontosabb elméleti gép, automata az ún. Turing-gép. Gyakorlatilag egy olyan automata, amely végtelen sok memóriával rendelkezik. De mi is egy automata? Elõször is szögezzük le, hogy a Turing-gép nem létezik, csak egy elméleti modell. Ezért használunk rá nagyon egyszerû, leíró nyelvezetet. A Turing-gép egy olyan gép, amelyhez egy végtelen hosszú papírszalag tartozik. Minden papírszalagon \"betûk\"/\"szimbólumok\" (ez a hivatalos megfogalmazás) találhatók. Egyszerûség miatt tekintsük ezeket nullának és egynek. A gépbe be van programozva egy adott utasítássorozat, amit végrehajt a szalagon, ezt a logikai vezérlõegységbe programozták be. Például tegyük fel, hogy a szalagunkra ez van írva: 0[0]11. Az olvasófej a második nullán áll. Tegyük fel, hogy az az utasítássorozat van beprogramozva, hogy
A következõ utasítás a szalagon lévõ karaktereket 0100-ra változtatja, és nem áll meg. Amennyiben nem ugranánk vissza egyre a következõ változó értéke már nem lenne módosítva. MIÉRT ELÕNYÖS AZ AMX? Az absztrakt gép egy számítógép virtuálisan. Ennek több elõnye van az x86 assemblyvel (tehát a \"tényleges\" natív assemblyvel) szemben:
A REGISZTEREK Az AMX regisztereket használó absztrakt gép. A regiszterek a processzorok elidegeníthetetlen részei a Neumman-elvek óta. Ennek elõnye az, hogy az absztrakt gép utasítása jobban \"rásimul\" a natív kódra, tehát a futásidõ csökken, valamint az utasítások száma csökkenthetõ. Az AMX egy kétregiszteres struktúra, két számításra alkalmas regiszter található meg: a PRI és az ALT. Az alábbi kódot: a = bö 2; Az AMX assemblyjében így kaphatjuk meg:
A REGISZTEREK LISTÁJA
Az AMX fájl memóriaképét, vagyis a memóriában elfoglalt helyét mutatja be az alábbi táblázat. A HEAP és a STACK alapvetõen nincs a bináris fájlban, elõállítását az AMX végzi a PREFIX adatok alapján. Ahhoz, hogy a lenti memóriaképnek megfelelõ bináris kódot kapj, használd a #pragma compress 0 direktívát a scriptedben.
A prefix A prefix rész a kód legelején terül el, és elsõdleges feladata általános metaadatok, pointerek, és a függvények listáját tárolni. A memóriatérképe a következõ (az X-el jelölt dinamikusan változik az adat mennyiségétõl függõen): (a teljes táblázat megtalálható a pawn-imp guide-ben, én ezt a verziót Y_Lesstõl szereztem, köszönöm)
A stringek NULL-delmitáltak (tehát a minden string végén szereplõ \\0 karakter jelzi a string végét), és tömörítettek. A konstansok (különösen a stringkonstansok) a DAT szegmensben tárolódnak, tehát irrelevánsak jelen esetben. A code szegmens A TEXT vagy CODE szegmens egy olyan szegmens egy bináris fájlban, vagy a memóriában, amely a futtatható utasításokat tartalmazza. A CODE szegmensnek a memóriában általában csak 1 példányra van szüksége, mivel megosztható. A CODE szegmens szinte mindig csak olvasható, hogy megakadályozható legyen az, hogy a program véletlen a saját utasításait módosítsa. A data szegmens A DATA szegmens a program virtuális memóriájának egy része, az egész program számára elérhetõ (ti. globális) változókat tárolja. A heap A heap, vagy \"halom\" a memória dinamikusan használható része. A \"halom\" igen deskriptív: hiszen gyakorlatilag a halomra akármikor hozzáadhatunk vagy elvehetünk valamit anélkül, hogy az egész összedõljön. Ha egy új dinamikus változót hozunk létre, lényegében a heap-bõl vesszük el a területet. Mivel a létrehozott változónak lefoglalt memóriaterület sosem ismeretes elõre, a new statement mindig egy pointerrel tér vissza a heapban tárolt pozícióval. A PAWN nyelv nem használ dinamikus változókat, minden változót vagy a DATA (glob), vagy a STACK (lok) szegmensek tárolnak, ezért például a memory leak-ek nem lehetségesek. Azért ide megemlítem, ha valakinek van kedve a memory leakekhez, hogy Y_Less malloc függvénykönyvtárával lehetõséged van \"dinamikus\" memóriát kiosztani (azért idézõjelbe, mert ez sem igazi dinamikus memória, és ez sem a heapben van, csak egyfajta workaround). A stack A STACK, hivatalos magyar nevén \"verem\", deskriptívabb nevén \"rakás\" egy memóriakezelési szerkezet. Mielõtt jobban megvizsgáljuk, nézzük meg az alábbi példát: Tegyük fel, hogy van egy rakás téglád egymáson. Mivel a téglák nehezek és rakásban vannak (tehát mindegyik tégla a másik tetején), ezért lényegében három dolgot tehetsz a téglákkal anélkül, hogy összedõljenek:
A stack egy olyan memóriakezelési struktúra, ami változókat tárol, hasonlóan a tömbökhöz. Viszont míg a tömbökben tetszés szerinti elemet elérhetsz, addig a stack ennél limitáltabb. Lényegében a fenti három dolgot teheted meg a stackkel:
Ahogy a téglás hasonlat is mondja: ha valaki egy téglát rárak a rakásra, akárki, aki levesz egy téglát a legfelsõt fogja levenni. Ez a LIFO-elv: last in-first out. A legelsõ felrakott elem lesz a legelsõ, amit levesznek. Ez, bár szép analógia, lehetne egy jobbat is létrehozni. Vegyünk egy adott számú postaládát: mindegyik egymás fölött, mindegyik csak egy dolgot tarthat magában, mindegyik üresként kezdi, és persze mindegyik az alatta lévõvel össze van ragasztva, így a számuk nem változik. A kérdés: ha a postaládák száma nem változtatható, hogyan kapunk egy stacket? Jelöljük meg egy matricával a legmagasabban lévõ üres postaládát. Minden a matrica alatt lévõ postaláda a stack tagja, minden a matrica fölött lévõ postaláda nem a stack tagja. Ez szinte azonos azzal, hogy mûködik a stack. A stack egy elõre meghatározott mennyiségû memória: a postaládák memóriacímek, és a levelek a memóriacím alatt lévõ adatok. A \"matrica\" a fentebb említett STK regiszter: Stack Index/Stack Pointer, ami mindig a legnagyobb elérhetõ stack címre mutat. Az egyetlen különbség a postaládás hasonlat és a valós stack közt az, hogy ha az adatot el akarjuk tüntetni, nem kell \"kiüríteni\" a postaládát: elég a matricát egyel lejjebb helyezni és az a memóriarész onnantól nem a stack tagja, amíg a következõ memóriarész felül nem írja. Miket rakunk a stackbe? Változókat, paramétereket, és függvényhívásokat. Mivel a globális változók a DATA szegmensbe kerülnek, ezért nekünk lényegében csak azzal kell foglalkoznunk, mi történik a lokális változókkal: tehát a függvényeken belül meghívottakkal. Példaképp tekintsük meg az alábbi kódot:
Ez, a nem mûködõ, viszont példaként tökéletesen használható kódrészlet tökéletes példa a stack bemutatására. Mikoris a main() függvény meghívja a foo függvényt, az alábbi játszódik le (ezt szaknyelven a Standard Entry Sequence-nek hívjuk): Az egyszerûség kedvéért a main()-t fogjuk hívni a meghívó függvvénynek míg a foo()-t a meghívott függvvénynek.
Minden stackre helyezett elem esetén természetesen frissítõdik a STK regiszter helye (ami a stack legfelsõ elemét mutatja). Ha a függvény megáll, lefut a fenti ellentéte, a Standard Exit Sequence
Zárásnak még annyit: hogy azért is futnak a több-threades programok gyorsabban, mert mindegyiknek külön stackje van. A heap és a stack, stack overflow Lehetõség van arra, hogy a stack számára elõre lefoglalt memóriát túllépjük, és beleírjunk a heap-be: ez általában nagy mennyiségû változó esetén következik be, ezt nevezzük stack overflownak. Ez azért lehetséges, mert a heap és a stack ugyanazt a memóriaterületet kapja, de ellentétes irányban kezdõdnek: a heap egyre növekvõ, míg a stack egyre csökkenõ memóriacímeket kap. A stack overflow tényérõl a fordító tájékoztatást ad: mégpedig kiírja, hogy az egyes szegmensek mennyi bájtot foglalnak el, és hogy a HEAP/STACK szegmensnek mekkora a maximális mérete, és mekkora az a méret, amit igényelne ahhoz, hogy minden változó elférjen benne. Ez azért lehetséges, mivel a stack mérete a fordítás során már ismert. Jogosan felmerülhet a kérdés, hogy akkor miért nem kap az AMX automatikusan több memóriát a programhoz: ez a mennyiség limitált és alapjában véve nem túl nagy, tehát megeshet, hogy egy normálisabb módhoz is növelni kell. Ezt a #pragma dynamic direktívával lehet megtenni. (és ennyi, frissítések várhatóak) 39
Fórum Archívum (Témák/Fórumok) / Re:Legális Hosting, Illegális Hosting?« Dátum: 2013. Január 07. - 16:37:57 »
[mod]Inaktív topic. L&A.[/mod]
40
Általános / Központi Stat- vagy szerverrendszer« Dátum: 2013. Január 02. - 17:06:27 »
Azon gondolkdotam, megérné-e csinálni egy központi statrendszert különbözõ típusú szerverekhez. Ez a következõképp zajlana: lenne egy központi web ahova be kéne regisztrálni, mint egy szeró UCPje. Lenne felhasználóneved, jelszavad. Bizonyos szerverek jelentkezhetnének a rendszerbe, akik kapnának egy API ID-t, és egy filterscriptet. Innentõl ha olyan szerveren, ahol ilyen rendszer van beépítve, olyan játékos játszik, akinek a rendszerre van accja, a statjait automatikusan követné és frissítené. A banokat is tárolná és az egész hálózatra érvényesítené, stb.
Persze ebben erõsen bent van az exploit lehetõsége, ezért minden szerver gondosan meg lenne válogatva, és külsõ kapcsolat le lenne tiltva az egyéb szervereknek. A statok esetén a szerverek súlyozva lennének, valamint a tulajok maguk dönthetik el, hogy a ban listát használják-e az õ szerverükön, valamint minden funkciót a szerverek egyesével beállíthatnának, és ezek egy listán látszódnának is. A kérdés az lenne, hogy szerintetek egy ilyen rendszert érdemes lenne-e megscriptelni, és milyen mûfajon belül lenne értelme? 41
Fórum Archívum (Témák/Fórumok) / (Leírás) A DeAMX, és hogy miért "nem mûködik".« Dátum: 2013. Január 02. - 10:37:28 »
BEVEZETÉS
Mostanában a SAMP fórumon nagyon fellendült a gépi kód alacsony szintû programozása. Mivel egy ideje én is foglalkozok ezzel, és a DeAMX mûködése a kezdõ scriptereknek rejtély, ezért írtam meg a tutorialt. A tutorial, hiszen kezdõknek készült, koránt sem teljes és nem feladata a megfelelõ szaknyelv használata. Remélem, aki PAWN-ban scriptel, az tisztába van azzal, hogy a PAWN, mint olyan, egy programozási nyelv. Az általunk kifejezett utasításokat gépi kódokká alakítja. Míg az emberek a szöveges nyelvet egyszerûbben, és hatékonyabban tudják kezelni, a gépek a számokat preferálják. Ezt nevezzük gépi kódnak. Ellentétben a közhiedelemmel, a gépi kód nem teljesen értelmetlen zagyvaság, hiszen akkor a számítógép se értené meg. Ellenben igen nehéz olvasnia egy ismeretekkel nem rendelkezõ felhasználónak. Ahhoz, hogy megértsük a problémát, tudnunk kell, mit nevezünk magas és alacsony szintû programnyelveknek. A magas szintû programnyelvek az emberek számára érthetõbbek, jobban programozhatóak, viszont a fordításuk erõforrásigényesebb, a program futása az alsóbb rétegek miatt általában lassabb. Az alacsonyabb szintû nyelvek az ember számára kevésbbé érthetõbbek, viszont gépi kóddá elõbb fordítódnak (hiszen közelebb állnak hozzájuk), és gyorsabbak. A PAWN, mint olyan, egy magas szintû nyelv, az ember számára könnyen olvasható, és megérthetõ.
A fenti scriptet, ha lefordítjuk, egy futtatható fájlt kapunk (AMX). Az AMX gépi kód, ezért megértése lehetetlen, ha nem ismerjük a felépítését. Ebben segít nekünk az ún. assembly nyelv. Az assembly a legalacsonyabb szintû programozási nyelv: a gépi kód felett állva az egyik legbonyorultabb, de leggyorsabban forduló és a gép számára legésszerûbb nyelv. A PAWN fordító -a kapcsolójával az AMX helyett ASM (assembler) kódot kapunk. Ha valakit érdekel, nyisson egy parancssort rendszergazdaként, navigáljon el a pawno mappájába, majd üsse be a pawncc fájlnév -a parancsot, ahol a fájlnév értelemszerûen a kódunk neve. Ne feledjük, hogy az assembly minden architektúrán változik, az AMX-nek (ami egy absztrakt gép, tehát egy szimulált számítógép) más fajta assemblyje van, mint egy x86-os processzornak. Ha a gépi kódot szeretnétek megtekinteni változatlanul, dobjatok egy #pragma compress 0-t a módban, és a tiszta kódot kapjátok meg a hex editorban. Én is így csináltam a gépi kódokhoz a példákat. A fenti PAWN kód így néz ki az AMX assemblyjében:
És miért mondjuk azt, hogy a gépi kódhoz a legközelebb áll? Egészen egyszerûen azért, mert minden egyes utasítás a gépi kódban megfelel egy két hexadecimális számból álló opkódnak, az utánna álló paraméterek pedig az opkód után álló hexadecimális számoknak.
Látszódik a fenti két kódrészletbõl, hogy az assemblybõl gépi kódot képezni nem éppen komoly munka. Az utasítást az elsõ négy, míg a paramétereket az utolsó négy bájtban tárolja el. Még ha az utasítás (vagy szebben fogalmazva opkód) csak 1 bájtot (0x00 - 0xFF) foglal el, a maradék három bájtot a kötelezõ formátum miatt nullákkal kell kitölteni. Az utasítás négy bájtja és a paraméterek négy bájtja közé húztam egy vonalat, ez az eredeti gépi kódban nincs ott. Látható hogy a break utasítás opkódja 89, a többi nulla csak a kötelezõ 4 bájt kitöltésére van. Ugyanígy a második példánál a 27 a push.c opkódja, majd a 4 üres bájt a kötelezõ formátum miatt van. A paramétere 0F, a maradék három bájt a kötelezõ formátum miatt itt is zérus. A VÁLTOZÓK MIZÉRIÁJA Amennyiben valaki már próbált DeAMX-el kódot visszafejteni, rájöhetett, hogy nem éppen jönnek vissza a változónevek, helyette értelmetlen var0, var4, var16, és egyéb értékeket kap. A helyzet a következõ: a számítógépek nem szeretik a szöveget: bonyorultak, sok memóriát foglalnak, lassítják a kódot, az embereknek viszont jobban megjegyezhetõ, mint egy rakat hexadecimális szám. Viszont a PAWN kód nem arra van, hogy visszafejtsed.
A fenti kód betölti az 0xfffffffc memóriacím alól a változót, csökkenti az értékét eggyel, majd eltárolja az új értéket a memóriacímben. Mellé írtam a gépi kód azon részét, ahol ez lejátszódik. Láthatjuk, hogy a load.s.pri opkódja a 03, követi három üres bájt, majd az FC FF FF FF felel meg a 0xFFFFFFFC-nek. A gépi kódoknál a hexadecimális számok bájtonkénti fordított sorrendben kerülnek be a listára (lásd Anthony kommentjét). Tehát egy ABCDEF12 hexadecimális szám mint 12 EF CD AB kerül bele a gépi kódba. Ezt hívjuk programozási szaknyelven kis endiánnak. A második sorban látjuk, hogy az add.c opkódja 57, követi három üres bájt, majd a -1 signed integer hexadecimális megfelelõje: 0xFFFFFFFF. Arról, hogy ez hogyan lesz végül is, ha valaki tájékozódni akar, javaslom Anthony tutorialját a bináris mûveletekrõl. Végül a módosult értéket ugyanabba a memóriacímbe elraktározzuk. A lényeg, hogy a fenti kód hasonlít ehhez. Mert hogy pont ugyanaz a kettõ:
És akkor mégis mi az a 0xfffffffc, és miért ez, nem \"var\"? MEMÓRIACÍMEK, MEMÓRIA LEFOGLALÁSA Arról már volt szó, hogy a számítógép nem szereti a szöveget, és a PAWN nem arra lett tervezve, hogy visszafejtsék. Ezért eldobja azt, ami nem kell. Vegyük példának az alábbi kódot: new var1; Ezt a DeAMX a következõképpen adja vissza:
Az assembly kódba ugyan nem került bele a három változó, hiszen sosem lettek használva, de kommentekben megtalálhatjuk a nyomát:
Láthatjuk, hogy mind a három változó pontosan 4 bájtot (1 cellát/2 szót) foglal el, hiszen a memóriacímek négyesével növekednek (0, 4, 8, C, 10, 14, 18, 1C, 20, ...). Ez azért van, mivel a korábbi példákból észrevehetjük, hogy a változó korábbi regiszterbe való betöltésekor és módosításakor is egészen pontosan 4 bájtba kellett beírnunk a szám értékét, levonhatjuk tehát a következtetést, hogy a PAWN integer alapból 32 bit = 4 bájt hosszú. Ez azért van, mivel a PAWN-ban minden alapból 1 cella hosszú (ami elméletileg megegyezne a processzorod architektúrájával, a SAMP azonban csak 32 bit hosszú cellákat használ). Minden adattípus a PAWN-ban maximum 4 bájt hosszú. Ezt próbálja meg a DeAMX ábrázolni, mikor a változónknak var0, var4, var8, var12, var16... neveket ad. A konkrét számok, és a látszólagos fordított kiosztásuk oka a relatív memóriacímekben rejlik, mégpedig abban, hogy az. ún stack memóriacímei, ahol a függvények lokális változói tárolódnak, lentrõl felfele kerülnek kiosztásra: ezekrõl kissé bõvebben az AMX és memóriaképe c. tutorial foglalkozik. Ugyanez a helyzet a függvényekkel: memóriacímek alapján azonosítják õket. Az egyetlen kivétel az eljárások esete (callback), melyeknek a helyzete elõre nem tudható, ezért a függvény neve és a függvényre mutató pointer tárolódik el a scriptben. TAGEK Miért van az, hogy a
változó ez lesz fordítás után:
? A megoldás itt is egyszerû: a tagek csak a fordító számára érdekesek, a gépi kódnak nem. A tagek csak a fordító számára fontosak, hogy egyféle mûveletet különbözõ adatokkal különbözõképpen használjon. Miután a fordítás megtörtént az adatok rögzítõdnek az IEEE 754 szabványnak megfelelõen (egy szabvány ami leírja a lebegõpontos számok bináris ábrázolását). Mikor a DeAMX visszafejti a kódot, mivel mind a lebegõpontos számok, mind az integerek ugyanúgy tárolódnak, nem tudja, hogy az adott cím alatt integer, vagy float van, ezért integerré alakítja. A szabvány felépítését nem fogom részletezni, mivel egyrészt bonyorult, másrészt érdektelen a tutoriallal kapcsolatban. Ha valakit nagyon érdekel, keressen rá az interneten a szabványra. ANTI-DEAMX Végül egy gyors mondat az anti-deamx-rõl: ezek mindegyike a compiler hibáját használja ki, egyik sem hivatalos, és ha a SAMP-hoz új compiler jönne ki, akkor egyik se érne sokat. A loopos példa Y_Less tutorialjából van. Észrevételeket szívesen látok. 42
Fórum Archívum (Témák/Fórumok) / krisk« Dátum: 2012. December 18. - 21:05:16 »
Nem vagyok a bemutatkozások híve, nem is nagyon tudok mit magamról mondani, de mivel sok ember írt ilyet, és még nekem nem volt, ezért most megírom.
A nevem titok. Veszprém megyében lakom de életvitelszerûen Székesfehérváron élek. A személyes életemet nem szeretném itt megosztani, mert az nem egy internetes fórum témája, de: a jobb szememre születésem óta súlyos tompalátó vagyok, ez abban realizálódik, hogy 20 centinél távolabb egyáltalán nem látok; azon kívül, hogy nem tudok 3D filmeket nézni, eddig nem akadályozott semmiben (a 3d film amúgy is basszná a szemem, ahogy az alacsony FPS-û játékok is). SAMP-ozni már 0.1 óta elkezdtem, de rendszeresen a 0.2x megjelenése óta játszom. Szinte az egész pályafutásom alatt csak RP szervereken játszottam: a Fay-on kezdtem, ott egy ideig az új modjukat is írtam, aztán LT, aztán Paradise, aztán Core, aztán Foothills, meg pár saját projekt (w0llfram). Az én véleményem a SAMP RP-vel kapcsolatban az, hogy az egyes asztali RPG elemeket (olyanokat, mint karakterlap vagy élettörténet) csak módjával lenne szabad egy normális modba berakni, a játékosoknak kéne tudniuk eljátszani a szerepüket mindenféle szabályzat nélkül. Ennek látszólag ellentmondhat a tény, hogy én magam is írtam egy asztali RP-jellegû modot, de az nem titkoltan arra szolgált, hogy azok, akik ezt kívánják, megkaphatják. A SAMP fórumos karrieremet valamikor 2010 környékén kezdtem. 2013 januárjában kaptam elõször lokális moderátor rangot a Szerverek alfórumba (miután megpályáztam azt), majd Csabi kinevezett lokális moderátornak a Beszélgetések alfórumba. 2013 július elsejétõl pedig mint Globális Moderátor vagyok jelen. Hobbijaim:
Kedvenc játékaim: a kedvenc sorozatom messze a GTA sorozat, ezen felül bizonyos régifajta szöveges kalandjátékok/RPG-k (pl. MUD), a Quantic Dreams játékai (Heavy Rain, Indigo Prophecy), Battlefield sorozat. Van már egy elég hosszan elhúzódó projektem, hogy elkezdek egy szövegalapú RPG-szerûséget írni, de még nem szántam rá magam, hogy elkezdjem. Mostanában a Malibun játszok, az mellett pedig LSRP-n ismét jelentkeztem rendõrségre (olyan március környékén ki**sztak inaktivítás miatt). Kedvenc zenéim: sok van, általában fõleg rock-metal vonalon mozgok, de hallgatok countryt és raget is (fõleg Joplint). Nem vetek meg semmilyen fajta zenét sem, ha tetszik, hallgatom. Ide kéne írjak listát, hogy kiket ismerek, kikkel vagyok jóba, és a többi, de inkább kihagyom, aki tudja, az úgyis tudja. 43
Fórum Archívum (Témák/Fórumok) / (Leírás) tickcount() a fölösleges timerek helyett« Dátum: 2012. December 09. - 09:49:10 »
A FÜGGVÉNY
A tickcount egy olyan függvény, ami a rendszer elindulása óta eltelt idõvel tér vissza ezredmásodpercekkel. tickcount(&granularity=0) &granularity: a visszatérés alkalmával ez az érték adja meg az egy másodpercben lévõ \"tick\"-ek számát. Az UNIX rendszerek esetén ez \"100\", vagyis az érték csak minden 10. ezredmásodpercben frissül. Mivel a függvény így is-úgy is ezredmásodpercekkel tér vissza, ez az érték csak a pontosság ellenõrzésére használható. A ROSSZ PÉLDA Rengeteg RP scriptben láttam (sõt, sokáig én magam is ezt csináltam), hogy amikor egy cselekvést minden x másodpercre akartak korlátozni, a cselekvés végrehajtása után az elõzõleg deklarált bool változónak hamis értéket adtak, majd elindítottak egy x másodperces timert, melynek lefutása után az érték ismét igaz lett. Vegyük példának az alábbi kódot: new bool:JatekosMegteheti[playerid] = true; // ez az a változó, ami meghatározza, hogy a játékos (már) használhatja-e (újra) a cselekvést. Az alábbi kód a MagaACselekvés függvényt korlátozta le: amennyiben valaki lefuttatja a függvényt, a tömbben, ami tárolja a cselekvés végrehajthatóságát (JatekosMegteheti), át lesz állítva az érték hamisra, majd a 10 másodperces timer visszaállítja igazra. A két cselekvés közt nem használható a függvény. A JÓ PÉLDA A tickcount() függvény segítségével ezt a kódot egyszerûbbé tehetjük. Ha a függvényt kétszer meghívjuk, és kivonjuk az utóbbit az elõbbibõl, máris kapunk egy intervallumot a két idõpont közt. new UtolsoEngedelyezes[MAX_PLAYERS]; //ebben fogjuk tárolni az utolsó engedélyezés tickcountját TICKCOUNT(), MINT IDÕMÉRÕ A fenti függvényt akár idõmérõként is használhatjuk. Ha egy cselekvés elején (pl. egy verseny rajtján) beleírjuk egy változóba, majd a végén az aktuális értékbõl kivonjuk az eredetit, megkaphatjuk, hogy a cselekvés mennyi idõbe tellett.
Az ezredmásodperceket pedig már különbözõ scriptek segítségével percekbe vagy órákba konvertálhatjuk. A HÁTRAMARADT IDÕ LEKÉRDEZÉSE Mintegy befejezésként tekintsük meg a \"jó példa\" változói alapján, hogy hogy kérhetjük le, az adott cselekvés hány ezredmásodperc múlva lesz végrehajtható: new mennyiido = 10000 - (tickcount() - UtolsoEngedelyezes[playerid]) Ahol a 10000 a cselekvések közti minimális szünet mennyisége. Ez a leírás még koránt sem teljes, javítások és bõvítések várhatóak EDIT: ADATBÁZISBAN ELTÁROLANDÓ ADATOK Ha ugyenzt a tickcountos mókát az adatbázisodban is akarod használni, akkor egy új, hasonló idõmérõ függvényt kell bevezetni, ez pedig a gettime(). A gettime() egy unix timestamp függvény, azaz az 1970-01-01 00:00:00Z óta eltelt másodpercekkel tér vissza. A mûködési elve hasonló a fentiekben bemutatottakhoz, azzal a nagy különbséggel, hogy mivel adatbázisban tároljuk, ezért a szerver futásidejével visszatérõ függvény nyilván nem jó erre a célra. 44
Játékok / IF projekt« Dátum: 2012. November 01. - 17:06:24 »
Üdv!
Már elképesztõen hosszú ideje tervezgetem egy saját játék készítését, de mivel a grafikai munkálatokhoz nekem sem idõm, sem energiám, sem türelmem nincsen, ezért egy ideig halogattam, és fõleg GTA:SA-ban alkottam sok kicsi, meg nem jelenõ single-jellegû projektet. Aztán a MUD 1-rõl, az egyik legjobb RPG-rõl jutott eszembe, hogy ezt meg lehet csinálni grafika nélkül is. Ezt is halogattam egy csomó ideig, aztán egy személyes esemény közeledte miatt úgy gondoltam, itt az ideje ebbe is belevágni. A múlt héten megbarátkoztam az ADRIFT nevû IF (interaktív fikció)-készítõ programmal, és nekiállok a játéknak, vagy inkább egy Heavy Rain-szerû interaktív könyvnek (nem összetévesztendõ a \"lapozós\" RPG-vel, de hasonló, csak itt tényleg interakcióba léphetsz a dolgokkal, nem csak két lehetõség közül választhatsz). A genre egyik alapvetõ alapelve, hogy nem halhatsz meg, ezért a játéknak gyakorlatilag nincsen \"jó\" és \"rossz\", csak többféle befejezése. Itt egy példa az interakció mélységére, és ez még semmi: ebben a szobában minden egyes tárgyat megvizsgálhatsz, megnézheted az ablakokat, kinyithatod és becsukhatod õket, a két órával az idõt is megtekintheted, a jegyzettömböt és a tollat magaddal viheted, berakhatod a szekrénybe, az ágy alá, a gardróbból kivett ruhákat felveheted, és a többi. És természetesen minden ilyen interakciót kb. 2 perc beállítani a szoftverben, a legtöbb idõt a szöveg megfogalmazása veszi el. Ezért ilyen f***a az IF interaktív könyvekre. Mint ahogyan ezt írtam már korábban, ez elsõsorban egy személyes projekt, tehát nagy valószínûséggel nem fog megjelenni a közeljövõben, maximum egy demó verzió (és amúgy is angolul van az egész), de azért kíváncsi vagyok, hogy mit gondoltok az ilyen jellegû játékokról. 45
Pluginok és Programok / Nativechecker« Dátum: 2012. Szeptember 22. - 08:10:33 »
Nem tudom, ismeritek-e, de én most, miután a pluginokat végigböngésztem, találtam rá. A nativechecker egy nagyon egyszerû plugin, de roppant hasznos: lényege, hogy az idegesítõ \"File or function is not found\" hiba helyett konkrétan elmondja, hogy mi, hol hiányzik.
Windows: http://solidfiles.com/d/5c0a/ Linux: http://solidfiles.com/d/0c45/ Source: http://solidfiles.com/d/8433/ Készítette: wyu. |