Üzenetek megjelenítése

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.


Témák - tonyo

Oldalak: 1 2 [3] 4
31
Hamarosan nyíló szerverek / Szabályzat
« Dátum: 2012. December 27. - 16:11:00 »
Szabályzat
 
Üdvözletem!Ebben az alfórumban a hamarosan nyíló szervereknek a bemutatására lehet témát nyitni. Mivel ez a téma is a fórum legforgalmasabb részeihez tartozik, így a következõ szabályzatot halálosan komolyan kell vennünk, hogy fent tartsuk a fórum ezen részének színvonalát és hogy elkerüljük a veszekedéseket. A szabályzat be nem tartása esetén nagyon komoly büntetés is kiosztható a moderátorok által. Mivel elég sok szervernek nyitnak itt témát, ezért a népszerûbb, jobban várt szervereket kiemeljük. Ha egy téma megnyílik, áthelyezésre kerül a megfelelõ fórumrészbe.


A szabályzat témanyitásra vonatkozó pontjai:
 
  • A téma neve egyezzen meg a szerver nevével!

  • A szerver alap információinak kiírása kötelezõ! (Név,Szerver típusa)

  • Csak saját szervereket tegyél közzé! ( Nem saját szervernek csak a készítõ engedélyével nyithatsz témát )

  • A témában fel kell tüntetni a szerver készítõjét, tulajdonosait stb...

  • A szerverrõl leírást kell írni! Mivel ezek a szerverek még nem nyíltak meg, így azt írjátok bele, amit terveztek a szerverre. (Ha a moderátorok szerint nem megfelelõ a leírás, felszólítanak, és ezután 24 órád van a leírás bõvítésére. Ha ezt nem teszed meg, 30% warn-t kapsz, valamint a téma zárásra kerül, az elérhetõségek pedig el lesznek távolítva.)Kiegészítés!

  • A negatív véleményeket is fogadd el!

  • Ha publikus tesztet szervezel,akkor annak a Rendezvények fórumban kell témát nyiss,ne itt!

  • Egy szervernek csak egy témája lehet. Több témát, többszörös hirdetést egy szervernek nem tudunk elfogadni és a moderátorok a másodtémákat törölni fogják (A témanyitót 30% warn-al jutalmazzuk!).

  • A moderátorok a témákat moderálják és figyelnek a kulturált viselkedésre. A téma nyitója bármikor kérheti a téma lezárását.

  • Ha egy téma le van zárva, akkor a moderátoroknak joga van eltávolítani annak minden elérhetõségét (pl. webcím).


  • Amennyiben egy téma szabálysértés miatt zárásra kerül, az adott szervernek nem nyitható új téma 48 órán belül! 48 óra elteltével a lezárt téma újranyitása is kérvényezhetõ, amennyiben a javított leírást Privát üzenetben elküldi a témanyitó egy moderátornak.




A szabályzat hozzászólásokra vonatkozó pontjai:
 
  • Kiemelném, hogy a Globális Fórumszabályzat, hozzászólásokra vonatkozó pontjai a Szerverek fórumrészben, és minden alfórumában IS érvényesek!

  • A bizonyíték nélküli vádaskodásokat, személyeskedéseket, OFFokat bármilyen igazságtartalma is van, de az nem bizonyított (bárki mondhat bármit...) a moderátornak joga van törölni.Kiegészítés!

  • Kerüld az OFF-ot (Témától eltérõ hozzászólás), felesleges hozzászólásokat (Pl. Amik csak hangulatjelekbõl állnak.) valamint a bumpot (azaz hónapos témákba ne szóljatok hozzá, mert lehet hogy a szerver készítõje már nem foglalkozik vele.) A nem megfelelõ hozzászólások törlésre kerülnek!

  • A társalgás kizárólag a szerverrõl,annak tulajdonosairól,ESETLEG nagyon kicsikét hostjáról, weblapjáról szólhat, vagy olyan dologról ami összefügg a szerverrel. (Tervek megvitatása, ötletek adása)

  • Ha egy moderátor vagy adminisztrátor törli a hozzászólásod akkor a következõ hozzászólásod ne csak annyiból álljon hogy valaki törölte, mert az is törölve lesz.
    A hozzászólásod törlésének mindig megvan az oka, errõl ne is kérj tájékoztatást, hogy miért lett törölve, inkább újból olvasd el a fórum szabályait.

  • A moderálási feladatokat hagyjátok meg a moderátorok számára. A leírás elbírálása az õ feladatuk. Emellett, ha egy moderátor a téma átszerkesztésére hívja fel a témanyitót, szigorúan tilos a további hozzászólás írása a témába! Ez alól csak a moderátorok, és a téma nyitója kivétel. Mindenki más hozzászólását szó nélkül törölni fogják a moderátorok, visszaesõk figyelmeztetve (warn) lesznek! (minimum 10%)


Figyelem: Bármennyi hozzászólásszámmal lehet témát nyitni!


Felhasznált scriptek, modok:
Amennyiben a szerver elkészítése során publikus (itt, vagy a hivatalos fórumon publikált) forrást használtok fel, kötelezõ feltüntetni:
 
  • Mod esetében:
    • eredeti név, akármennyire is módosítva lett

    • készítõ(k) neve, amennyiben ismert

    • forrás link


    • Script, kódrészlet illetve map esetében:

     
    • készítõ(k) neve, amennyiben ismert

    • forrás link



Magyarázat: A forrás link ne csak egy letöltési link legyen! Amennyiben lehetséges, ezen a fórumon, vagy a hivatalos fórumon lévõ topicra mutató link kell legyen! Fájlmegosztó oldalakra mutató linket nem fogadunk el!
Amennyiben valaki jelzi, hogy a szervereden publikus elemeket használtál fel, és elmulasztottad ezt a leírásban jelezni, a moderátorok figyelmeztetésben részesítenek (minimum 10% warn), valamint felszólítanak a hiányosság 24 órán belüli pótlására. Amennyiben ezt nem teszed meg, a téma zárásra kerül, az elérhetõségeket pedig eltávolítjuk.
Amennyiben úgy veszed észre, hogy valamely szerveren publikált elemet használtak fel és ezt nem jelezték a leírásban, jelezd ezt egy moderátor felé, az adott elem publikációs témájának (itteni, vagy hivatalos fórumon lévõ topicra mutató) linkjével együtt.


Leírás:
Ne feledjétek, hogy ez nem apróhirdetés, hanem bemutatás. Ezek a szerverek ugyan még csak tervek, azonban sok játékost már itt megfoghattok, egy jó leírással. Próbáljátok megragadni õket, hiszen sokkal jobb úgy szervert készíteni, ha vannak mögöttetek támogató játékosok, akik besegítenek tesztekkel, ötletekkel, véleményekkel. Késõbb belõlük hû játékosok lehetnek. Sok szerver ezzel alapozta meg késõbbi hírnevét, itt szerezték meg a leghûségesebb játékosaikat. Ebben a fázisban már meg lehet ragadni a játékosokat. Amennyiben még nem tudtok mit írni, inkább várjatok a témanyitással addig, amíg ki nem körvonalazódnak a tervek, hogy milyen szervert is akartok pontosan.


Vádaskodás
Megvádolni egy szervert valamivel, pl. hogy lopott a mód kizárólag bizonyítékokkal lehetséges.
A bizonyíték nélküli vádaskodás rágalomnak számít, amiért figyelmeztetést is kaphatsz.
Amennyiben a moderátorok szerint elég bizonyíték gyûlik össze egy komoly vádra, (lopott mód) a témát zárjuk és eltávolítjuk az elérhetõségeket.
Ennek alapvetõ feltétele, hogy JÁRTÁL A SZERVEREN! A legjobb bizonyítékok a képek, esetleg log fájlok...
Bizonyíték nélkül kritizálni RÁGALOM. Fentebb le lett írva ennek a következménye.


Büntetési formák:
 
  • A hozzászólás azonnali törlése.

  • A warn (figyelmeztetési szint) növelése minimum 10%-al.

  • Végsõ esetben a felhasználó elnémítása a fórumrészben.




Ha úgy gondolod, a Te szervered tényleg megérdemli azt, hogy ide kikerüljön akkor nyiss bátran neki témát, majd a moderátorok úgyis eldöntik hogy a szerver bemutatása megfelel-e a feltételeknek. Ha megfelel nincs semmi gond, ha viszont nem felel meg, akkor felszólítják a témanyitót, hogy 24 órán belül szerkessze a hozzászólását a feltételnek megfelelõen.
A szabályzat nem ismerése nem mentesít a betartása alól! A szabályzat visszamenõlegesen is érvényes.

32
Fórum Archívum (Témák/Fórumok) / Szabályzat
« Dátum: 2012. December 27. - 16:04:33 »
Szabályzat
 
A következõ szabályzatot halálosan komolyan kell vennünk,hogy fent tartsuk a fórum ezen részének színvonalát és hogy elkerüljük a veszekedéseket.A szabályzat be nem tartása esetén nagyon komoly büntetés is kiosztható a moderátorok által.


A szabályzat témanyitásra vonatkozó pontjai:
 
  • A téma neve egyezzen meg a szerver nevével!

  • Házi szervernek ne nyiss témát, csak is hostosnak! A host nevét kötelezõ feltüntetni!

  • A szerver alap információinak kiírása kötelezõ! (IP,Név,Slot)

  • A témában fel kell tüntetni a szerver készítõjét, tulajdonosait stb...

  • A szervernek rendes LEÍRÁST kell csinálni,nem elég 5 soros kis szöveg! (Ha a moderátorok szerint nem megfelelõ a leírás, felszólítanak, és ezután 24 órád van a leírás bõvítésére. Ha ezt nem teszed meg, 30% warn-t kapsz, valamint a téma zárásra kerül, az elérhetõségek pedig el lesznek távolítva.)Kiegészítés!

  • Csak saját szervereket tegyél közzé! ( Nem saját szervernek csak a készítõ engedélyével nyithatsz témát )

  • A negatív véleményeket is fogadd el!

  • RP szervereknek a megfelelõ alfórumban nyithatsz témát!

  • Ha partyt szervezel,akkor annak a Rendezvények fórumban kell témát nyiss,ne itt!

  • Egy szervernek csak egy témája lehet. Több témát, többszörös hirdetést egy szervernek nem tudunk elfogadni és a moderátorok a másodtémákat törölni fogják (A témanyitót 30% warn-al jutalmazzuk!).

  • A felhasználóknak joga van véleményeket írni a szerverrõl, HA VOLTAK FENT, vagy van régebbi tapasztalatuk. Amennyiben egy felhasználó anélkül fogalmaz meg véleményt, hogy járt volna a szerveren, a téma nyitója kérheti a hozzászólás törlését.

  • A moderátorok a témákat moderálják és figyelnek a kulturált viselkedésre. A téma nyitója bármikor kérheti a téma lezárását.

  • Ha egy téma le van zárva, akkor a moderátoroknak joga van eltávolítani annak minden elérhetõségét.


  • Amennyiben egy téma szabálysértés miatt zárásra kerül, az adott szervernek nem nyitható új téma 48 órán belül! 48 óra elteltével a lezárt téma újranyitása is kérvényezhetõ, amennyiben a javított leírást Privát üzenetben elküldi a témanyitó egy moderátornak.




A szabályzat hozzászólásokra vonatkozó pontjai:
 
  • Kiemelném, hogy a Globális Fórumszabályzat, hozzászólásokra vonatkozó pontjai a Szerverek fórumrészben, és minden alfórumában IS érvényesek!

  • A bizonyíték nélküli vádaskodásokat, személyeskedéseket, OFFokat bármilyen igazságtartalma is van, de az nem bizonyított (bárki mondhat bármit...) a moderátornak joga van törölni.Kiegészítés!

  • Kerüld az OFF-ot (Témától eltérõ hozzászólás), felesleges hozzászólásokat (Pl. Amik csak hangulatjelekbõl állnak.) valamint a bumpot (azaz hónapos témákba ne szóljatok hozzá, mert lehet hogy a szerver készítõje már nem foglalkozik vele.) A nem megfelelõ hozzászólások törlésre kerülnek!

  • Jogod van véleményeket írni a szerverrõl, HA VOLTÁL FENT, vagy van régebbi tapasztalatod. Amennyiben nem jártál a szerveren, ne vonj le következtetést. Amennyiben mégis, a moderátornak joga van törölni a hozzászólásodat, egy szóbeli figyelmeztetés után pedig figyelmeztetést kaphatsz.

  • Ha egy moderátor vagy adminisztrátor törli a hozzászólásod akkor a következõ hozzászólásod ne csak annyiból álljon hogy valaki törölte, mert az is törölve lesz.
    A hozzászólásod törlésének mindig megvan az oka, errõl ne is kérj tájékoztatást, hogy miért lett törölve, inkább újból olvasd el a fórum szabályait.

  • A moderálási feladatokat hagyjátok meg a moderátorok számára. A leírás elbírálása az õ feladatuk. Emellett, ha egy moderátor a téma átszerkesztésére hívja fel a témanyitót, szigorúan tilos a további hozzászólás írása a témába! Ez alól csak a moderátorok, és a téma nyitója kivétel. Mindenki más hozzászólását szó nélkül törölni fogják a moderátorok, visszaesõk figyelmeztetve (warn) lesznek! (minimum 10%)


Figyelem: Bármennyi hozzászólásszámmal lehet témát nyitni!


Leírás:
Ne feledjétek, hogy ez nem apróhirdetés, hanem bemutatás. Leginkább egy PC Guru-s játék teszthez tudnám hasonlítani, az sem 5 darab igénytelen sorból áll. Nem 5 sor kell, de 50 oldal sem, találjátok meg a köztest ami megragadja a játékosokat, a lényeget írjátok le, vagy amit úgy éreztek fontos. Felesleges alapvetõ szabályok, fogalommagyarázatok bemásolása. Nem csak a mennyiséget nézzük, hanem a tartalmat is. Gondolj arra, hogy ez alapján fogják elsõ ránézésre megítélni a szerveredet, és eldönteni, hogy érdemes-e felmenniük.


Vádaskodás
Megvádolni egy szervert valamivel, pl. hogy lopott a mód kizárólag bizonyítékokkal lehetséges.
A bizonyíték nélküli vádaskodás rágalomnak számít, amiért figyelmeztetést is kaphatsz.
Amennyiben a moderátorok szerint elég bizonyíték gyûlik össze egy komoly vádra, (lopott mód) a témát zárjuk és eltávolítjuk az elérhetõségeket.
Ennek alapvetõ feltétele, hogy JÁRTÁL A SZERVEREN! A legjobb bizonyítékok a képek, esetleg log fájlok...
Bizonyíték nélkül kritizálni RÁGALOM. Fentebb le lett írva ennek a következménye.


Büntetési formák:
 
  • A hozzászólás azonnali törlése.

  • A warn (figyelmeztetési szint) növelése minimum 10%-al.

  • Végsõ esetben a felhasználó elnémítása a fórumrészben.




Ha úgy gondolod, a Te szervered tényleg megérdemli azt, hogy ide kikerüljön akkor nyiss bátran neki témát, majd a moderátorok úgyis eldöntik hogy a szerver bemutatása megfelel-e a feltételeknek. Ha megfelel nincs semmi gond, ha viszont nem felel meg, akkor felszólítják a témanyitót, hogy 24 órán belül szerkessze a hozzászólását a feltételnek megfelelõen.
A szabályzat nem ismerése nem mentesít a betartása alól! A szabályzat visszamenõlegesen is érvényes.

33
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: Térkép Szin parancs
« Dátum: 2012. Október 23. - 14:03:34 »
A téma át lett helyezve a következõbe: Segítségkérés.
http://sampforum.hu/index.php?topic=33377.0" class="bbc_link">http://http://sampforum.hu/index.php?topic=33377.0

34
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: ImportRPG elõkészületek
« Dátum: 2012. Október 22. - 00:40:41 »

35
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: Scripter
« Dátum: 2012. Október 08. - 16:17:56 »

36
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: Farmos munka
« Dátum: 2012. Október 06. - 18:38:53 »
A téma át lett helyezve a következõbe: Szkript kérések.
http://sampforum.hu/index.php?topic=32819.0" class="bbc_link">http://http://sampforum.hu/index.php?topic=32819.0

37
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: Auto Controller
« Dátum: 2012. Szeptember 23. - 14:56:49 »
A téma át lett helyezve a következõbe: Szkript kérések.
http://sampforum.hu/index.php?topic=32355.0" class="bbc_link">http://http://sampforum.hu/index.php?topic=32355.0

38
A témát ideiglenesen eltávolítottam. Innentõl a dolgot átadom egy glob modnak/adminnak, ehhez én már kevés vagyok, majd valaki magasabb rangú eldönti, hogy mi legyen a téma sorsa (törlés vagy takarítás)

39
Fórum Archívum (Témák/Fórumok) / Re:Cold Role Play Gaming
« Dátum: 2012. Augusztus 28. - 09:31:03 »
[mod]Bõvüljön is. 3 napod van, ha addig nem bõvíted, akkor zárásra kerül.[/mod]


[mod]Örülök a sok önjelölt moderátornak, de szerintem leírtam neki hogy bõvítse, felesleges ezt túlragozni... Felesleges hsz-ek törölve..[/mod]

40
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: Survival RPG
« Dátum: 2012. Augusztus 17. - 22:16:17 »
A téma át lett helyezve a következõbe: RP/GF szerverek.
http://sampforum.hu/index.php?topic=30630.0" class="bbc_link">http://http://sampforum.hu/index.php?topic=30630.0

41
Fórum Archívum (Témák/Fórumok) / ÁTHELYEZVE: West Roleplay szerver
« Dátum: 2012. Augusztus 11. - 00:20:16 »
A téma át lett helyezve a következõbe: RP/GF szerverek.
http://sampforum.hu/index.php?topic=12665.0" class="bbc_link">http://http://sampforum.hu/index.php?topic=12665.0

42
SA-MP: Szerverfejlesztés / Anti RakSAMP script
« Dátum: 2012. Augusztus 07. - 15:22:04 »
Üdv.
Hétvégén rám írt Ystee, hogy tudok-e valami jó kis védelmet RakSAMP ellen, mert amiket eddig talált, egyik sem mûködött. Nos, engem érdekelt a téma, ezért hát beszereztem a RakSAMP-ot(forrással...), és elkezdtem tanulmányozni(a forrást). A program nagy részét már értem, mi mit is csinál, így hát nekiálltam elkészíteni egy \"anti-bot\" rendszert hozzá. Elõször gpci-vel próbálkoztam, de hamar kiderült, hogy minden indításnál egy random sztringet generál, amit átad a samp-nak, mint kliens azonosító, ebbõl az irányból tehát nem jártam sikerrel. Ezután elkezdtem nézni, mi alapján lehetne még detektálni, hogy most botról van-e szó. Sajnos arra jutottam, hogy csatlakozáskor még semmibõl, ugyan is ugyanúgy Raknet alapú a program mint a SA:MP, és nagyon jól van összerakva(baromi jól tudja szimulálni, egy rendes kliens csatlakozását), de...
Néztem Network Stat-ot, pozíciókat, ezt-azt.. majd miután ismét a forrásban nézelõdtem, találtam egy \"hibapontot\". Mikor ezt leellenõriztem, a sejtésem helyesnek bizonyult, kedves botunk spawnolásakor nem hívódik meg az OnPlayerSpawn callback. Így már nem is volt nehéz, egy \"anti-RakSAMP\" scriptet írni. Amit még menet közben találtam hozzá, azt még beleírtam, így többféle megoldás is van benne, ezek idõ közben születtek, de ameddig a spawnos dologra nem jöttem rá, addig sajnos ezek nem mûködtek.
A végeredmény ez a script lett
 
// -------------------------------------------------------------------------- //
// File:   antiraksamp.pwn
// Desc:   A sscript célja a RakSAMP botok kirugása
// Author:   Anthony
// Lic:      GNU Public License (http://www.gnu.org)
// -------------------------------------------------------------------------- //
//SA:MP függvénykönyvtár beágyazása
#include <a_samp>
//Forward a timerünknek
forward BotCheck(playerid);
//Változó a timer id-nek
new timer;
// -------------------------------------------------------------------------- //
public OnFilterScriptInit()
{
//Timer elindítása, azonosítójának eltárolása a \'timer\' változóban
    timer = SetTimer(\"BotCheck\", 1000, true);
//Tájékozatjuk a szerver tulajt, hogy a script betöltõdött, elindult
printf(\"-------------------------------------\");
printf(\"| Anti-RakSAMP by Anthony - Loaded! |\");
    printf(\"-------------------------------------\");
return 1;
}
// -------------------------------------------------------------------------- //
public OnFilterScriptExit()
{
//Timer megsemmisítése
KillTimer(timer);
//Tájékoztatjuk a szerver tulajt, hogy a script leállt
printf(\"---------------------------------------\");
printf(\"| Anti-RakSAMP by Anthony - Unloaded! |\");
    printf(\"---------------------------------------\");
return 1;
}
// -------------------------------------------------------------------------- //
public OnPlayerConnect(playerid)
{
//Csatlakozáskor 0-ra állítjuk a PVar-t
SetPVarInt(playerid, \"Spawned\", 0);
return 1;
}
// -------------------------------------------------------------------------- //
public OnPlayerDisconnect(playerid)
{
//Lecsatlakozáskor töröljük a PVar-t
DeletePVar(playerid, \"Spawned\");
return 1;
}
// -------------------------------------------------------------------------- //
public OnPlayerSpawn(playerid)
{
//Beállítjuk a PVar-t
SetPVarInt(playerid, \"Spawned\", 1);
return 1;
}
// -------------------------------------------------------------------------- //
//Timerünk fõ része
public BotCheck()
{
new pname[MAX_PLAYER_NAME];
//For ciklussal végigmegyünk minden lehetséges játékos ID-n
for(new i=0; i < MAX_PLAYERS; i++)
{
    //Ellenõrizzük, hogy van-e ilyen játékos
if(IsPlayerConnected(i))
{
    //Lekérjük a játékos nevét
    GetPlayerName(i, pname, MAX_PLAYER_NAME);
    //A STATE csak akkor nem PLAYER_STATE_NONE, ha már lespawnolt a játékos,
    //tehát ellenõrizzük, hogy tényleg spawnolt-e
   if(GetPlayerState(i) != PLAYER_STATE_NONE && GetPVarInt(i, \"Spawned\") == 0)
   {
       //Ha ide jutottunk, akkor már 100% hogy bottal van dolgunk, mert
      //nem hívódott meg rá az OnPlayerSpawn callback, ezért hát kickeljük
       Kick(i);
       //Tájékoztatjuk a tulajt, hogy a játékos egy bot volt
       printf(\"%s egy BOT... volt.(State)\", pname);
       //A ciklust a következõ játékos id-re \"ugrasztjuk\"
       continue;
   }
    //A STATE csak akkor nem PLAYER_STATE_NONE, ha már lespawnolt a játékos,
    //ellenõrizzük a CameraMode-t
   if(GetPlayerState(i) != PLAYER_STATE_NONE && GetPlayerCameraMode(i) > 100)
   {
       //Ha ide jutottunk, 99,9% a valószínûsége, hogy bottal van dolgunk
       //ezért hát kickeljük
       Kick(i);
       //Tájékoztatjuk a tulajt, hogy a játékos egy bot volt
       printf(\"%s egy BOT... volt.(CameraMode)\", pname);
       //A ciklust a következõ játékos id-re \"ugrasztjuk\"
       continue;
   }
   //Létrehozunk 3 float változót
   new Float:x, Float:y, Float:z;
   //Lekérjük a kamera pozíciót
   GetPlayerCameraPos(i, x, y, z);
   //A STATE csak akkor nem PLAYER_STATE_NONE, ha már lespawnolt a játékos,
    //ellenõrizzük a kamera pozíciót
   if(GetPlayerState(i) != PLAYER_STATE_NONE && x == 0.0 && y == 0.0 && z == 0.0)
   {
       //Ha ide jutottunk, 100% a valószínûsége, hogy bottal van dolgunk,
       //mert egy játékosnak sosem lesz 0,0,0 a kamera pozícója (kivéve
      // ha mi magunk helyeztük oda), ezért hát kickeljük
       Kick(i);
       //Tájékoztatjuk a tulajt, hogy a játékos egy bot volt
       printf(\"%s egy BOT... volt.(CameraPos)\", pname);
       //A ciklust a következõ játékos id-re \"ugrasztjuk\"
       continue;
   }
   //Lekérjük a kamera vektorokat
   GetPlayerCameraFrontVector(i, x, y, z);
   if(GetPlayerState(i) != PLAYER_STATE_NONE && (x > 1000.0 || y > 1000.0 || z > 1000.0))
   {
       //Ha ide jutottunk, 100% a valószínûsége, hogy bottal van dolgunk,
       //mert egy játékosnak sosem kapunk 1000-nél nagyobb FrontVector
      //értéket, ezért hát kickeljük
       Kick(i);
       //Tájékoztatjuk a tulajt, hogy a játékos egy bot volt
       printf(\"%s egy BOT... volt.(CameraFrontVector)\", pname);
       //A ciklust a következõ játékos id-re \"ugrasztjuk\"
       continue;
   }
}
}
}
// -------------------------------------------------------------------------- //

 
Bizonyíték a mûködésre:
Spoiler for Log részlet:
[14:36:57]   Loading filterscript \'antiraksamp.amx\'...
[14:36:57] -------------------------------------
[14:36:57] | Anti-RakSAMP by Anthony - Loaded! |
[14:36:57] -------------------------------------
[14:36:57]   Loaded 2 filterscripts.
[14:36:57]
----------------------------------
[14:36:57]   Running LVDM ~MoneyGrub
[14:36:57]          Coded By
[14:36:57]             Jax
[14:36:57] ----------------------------------
[14:36:57] Number of vehicle models: 48
[14:37:04] Incoming connection: 127.0.0.1:64259
[14:37:04] [join] Bot1 has joined the server (0:127.0.0.1)
[14:37:07] [part] Bot1 has left the server (0:2)
[14:37:07] Bot1 egy BOT... volt.(State)
[14:37:09] Incoming connection: 127.0.0.1:64260
[14:37:09] [join] Bot1 has joined the server (0:127.0.0.1)
[14:37:10] [part] Bot1 has left the server (0:2)
[14:37:10] Bot1 egy BOT... volt.(State)
[14:37:25] Incoming connection: 127.0.0.1:64261
[14:37:25] [join] Bot1 has joined the server (0:127.0.0.1)
[14:37:26] [part] Bot1 has left the server (0:2)
[14:37:26] Bot1 egy BOT... volt.(State)
[14:37:40] Incoming connection: 127.0.0.1:64262
[14:37:40] [join] Bot1 has joined the server (0:127.0.0.1)
[14:37:40] [part] Bot1 has left the server (0:2)
[14:37:40] Bot1 egy BOT... volt.(State)
[14:37:41] Incoming connection: 127.0.0.1:64263
[14:37:42] [join] Mason_Lovell has joined the server (0:127.0.0.1)
[14:37:55] Incoming connection: 127.0.0.1:62477
[14:37:55] [join] Bot1 has joined the server (1:127.0.0.1)
[14:37:56] [part] Bot1 has left the server (1:2)
[14:37:56] Bot1 egy BOT... volt.(State)
[14:38:10] Incoming connection: 127.0.0.1:62478
[14:38:10] [join] Bot1 has joined the server (1:127.0.0.1)
[14:38:11] [part] Bot1 has left the server (1:2)
[14:38:11] Bot1 egy BOT... volt.(State)
[14:38:25] Incoming connection: 127.0.0.1:62479
[14:38:25] [join] Bot1 has joined the server (1:127.0.0.1)
[14:38:26] [part] Bot1 has left the server (1:2)
[14:38:26] Bot1 egy BOT... volt.(State)
[14:38:40] Incoming connection: 127.0.0.1:62480
[14:38:40] [join] Bot1 has joined the server (1:127.0.0.1)
[14:38:41] [part] Bot1 has left the server (1:2)
[14:38:41] Bot1 egy BOT... volt.(State)
[14:38:55] Incoming connection: 127.0.0.1:62481
[14:38:55] [join] Bot1 has joined the server (1:127.0.0.1)
[14:38:56] [part] Bot1 has left the server (1:2)
[14:38:56] Bot1 egy BOT... volt.(State)
[14:39:10] Incoming connection: 127.0.0.1:53072
[14:39:11] [join] Bot1 has joined the server (1:127.0.0.1)
[14:39:11] [part] Bot1 has left the server (1:2)
[14:39:11] Bot1 egy BOT... volt.(State)
[14:39:25] Incoming connection: 127.0.0.1:53073
[14:39:26] [join] Bot1 has joined the server (1:127.0.0.1)
[14:39:26] [part] Bot1 has left the server (1:2)
[14:39:26] Bot1 egy BOT... volt.(State)
[14:39:41] Incoming connection: 127.0.0.1:53074
[14:39:41] [join] Bot1 has joined the server (1:127.0.0.1)
[14:39:42] [part] Bot1 has left the server (1:2)
[14:39:42] Bot1 egy BOT... volt.(State)
[14:39:56] Incoming connection: 127.0.0.1:51681
[14:39:56] [join] Bot1 has joined the server (1:127.0.0.1)
[14:39:56] [part] Bot1 has left the server (1:2)
[14:39:56] Bot1 egy BOT... volt.(State)
[14:40:09] [part] Mason_Lovell has left the server (0:1)
[14:40:11] Incoming connection: 127.0.0.1:62120
Mason_Lovell az én vagyok, vígan szaladgáltam, miközben a botokat kickelgette a rendszer.

44
Ezt a témát már jóval régebben meg akartam írni, mert tudom, hogy sokan hallottak a bitmûveletekrõl, de a nagy többség nem igazán tudja mire is jó, és hogyan kell használni. A téma elsõ felében a bitmûveleteket fogom taglalni, ez egy fõként elméleti rész lesz, míg a második felében gyakorlatban is megmutatom, mire is jó ez az egész, többek között elmagyarázom hogyan is mûködik az a bizonyos 4 függvény, mely egy jármû állapotát állíthatjuk be(encode_lights, encode_tires, encode_doors, encode_panels), és még pár apróbb érdekességet mutatok ezzel kapcsolatban.
Elõször is el kell fogadni egy dolgot: ez nem kezdõknek való. A bitmûveletek nem alapszintû tudást igényelnek, és hál\' Istennek, elég ritkán van rájuk szükség. Azonban, a SA:MP-ban is tudjuk hasznosítani, többféleképpen is. Erre majd késõbb kitérek.


Tartalomjegyzék
 

  • 1. Bitmûveletek


    1. Bitmûveletek
     


    1.1 Bevezetés
    A bitmûveletek arra használhatóak, hogy az egész számok bitjeit külön-külön kezelhessük. Mint írtam, erre egy átlag \"programozónak\" (a pawn scripter nagyon messze áll a programozótól...) elég ritkán van szüksége, de vannak helyzetek, mikor jól jöhet ha ismerjük. A bitmûveletek megértéséhez elõször is tisztában kell lennünk a kettes számrendszerrel.


    1.2 A kettes (bináris) számrendszer
    A kettes vagy bináris számrendszerben az 1-es és a 0-s számjegyekkel ábrázoljuk a számokat. Digitális áramkörökben is a kettes számrendszerrel való számolást a legegyszerûbb megoldani, ezért szinte biztosak lehetünk benne, hogy manapság a számítógépekben, és szinte minden modern elektronikai eszközben ilyen számrendszert használnak  programok.
    Arról nem igazán szeretnék írni, hogy hogyan is lehet számolni kettes számrendszerben, egyrészt mert erre nem lesz feltétlen szükségünk (persze nem árt ha megértjük), másrészt akit érdekel az úgyis utána fog nézni, rengeteg jó forrás, leírás található errõl a neten.


    1.3 Részletesebben a bitekrõl a Pawn-ban
    A bit az információ alapegysége a számítástechnikában. Kétféle értéke lehet: 0(hamis) és 1(igaz). A név az angol binari digit, vagyis bináris számjegy kifejezésbõl származik.
    Manapság rengeteg programozási nyelv létezik, melyek eltérnek abban, hogy hány bites változókat használnak az adott nyelvben. A Pawn egy 32 bites programozási nyelv, vagyis minden változó 4 bájt(byte), vagyis 32 bit(bit). Ebbõl joggal következtethetünk arra, hogy a 232-1 a maximális legnagyobb eltárolható érték. Azért kell a -1, mert 0-tól indítjuk a számolást. Ez azt jelentené, hogy a maximális eltárolható érték 4,294,967,295. Ez azonban nem így van.
    Hogy miért is nem, ahhoz elõször is jöjjön egy kis háttérinfó. A legtöbb(minden) programozási nyelv esetén találkozhatunk integer változókkal. Ezeknek 2 típusát különböztetjük meg. Léteznek az úgynevezett elõjeles egész változók(signed integers), és léteznek elõjel nélküli(más néven pozitív) egész változók(unsigned integers). A különbség a kettõ között, hogy még egy elõjeles egész változóban eltárolhatsz negatív értéket is, addig az pozitív egész változóban nincsenek negatív számok. Utóbbinak tehát 4,294,967,295 a maximális eltárolható értéke. A Pawn azonban nem az utóbbi típust használja.
    A Pawn elõbbi, vagyis elõjeles egész változókat (signed integers) használ. 1 bitet fenntart a 32-bõl az elõjel számára(pozitív, vagy negatív). Ezt a bitet szokás MSB-nek(Most significant bit) hívni. Ha ez a bit be van kapcsolva, akkor a szám negatív, ha ki vna kapcsolva, akkor a szám pozitív. Így már egybõl érthetõ, hogy miért is 231-1 a maximális eltárolható érték, és nem pedig 232-1. Ebbõl következik tehát, hogy a Pawn-ban az integer változók értékkészlete: -231(-2,147,483,648) és 231-1(2,147,483,647) közötti számok.
    Ha egy változó létezik, akkor abban minden esetben, mind a 32 bit \"használtban\" van. A bináris számok elé bármennyi 0-t írhatunk, az értéke nem változik. Ez azt jelenti, hogy figyelembe kell vennünk, hogy ha nekünk az 1-es szám van eltárolva, mely alapból a bináris számrendszerben 1, az a Pawnban 00000000000000000000000000000001-ként lesz eltárolva. Ez késõbb még fontos lesz!
    A késõbbiekben szükségünk lesz még egy háttér információra. A Pawn egy úgynevezett 2-es komplementer rendszert használ, hogy elõállítsa a negatív számokat. Akik jártasak a C-ben, azon belül is a bitmûveletekben, azok tudják mit is jelent ez. Nem olyan bonyolult, tehát: fogjuk az alap számot, és minden bitet kicserélünk az ellentétére. Tehát az egyeseket 0-ra, a nullákat 1-esre. Végül a számhoz hozzáadunk egyet, és ezzel meg is kaptuk a negatív számot.
    Itt egy példa:
     
    00000000000000000000000000000001//
    1
    11111111111111111111111111111110//
    minden bit komplementerét vesszük
    11111111111111111111111111111111//
    hozzáadtunk egyet, így megkaptuk a -1-et.
    [/quote]


1.4 Operátorok
A bitekkel mûveleteket végezhetünk, ehhez különbözõ operátorok állnak rendelkezésünkre. Lentebb minden operátort egyesével ki fogok fejteni, azt is, hogy mit csinál, és leírom az igazságtáblázatukat is. Konkrétan a következõ operátorok állnak rendelkezésünkre:
 
  • Bitenkénti (bitek közötti) ÉS

  • Bitenkénti (bitek közötti) VAGY

  • Bitenkénti (bitek közötti) KIZÁRÓ VAGY

  • Bitenkénti (bitek közötti) NEGÁLÁS

  • Biteltolás (arithmetic shift, shiftelés) operátor(ok)

  • Logikai biteltolás (logical shift, logikai shiftelés) operátor


Az elsõ négy felsorolt operátor tartozik a logikai operátorok közé, még az utolsó elõtti(igazából utolsó elõtti kettõ, mert tolhatjuk jobbra, illetve balra, azaz 2 shiftelõ operátor lesz), és az utolsó biteltolási mûvelet. Az operátorok a számok azonos helyi értékû bitjei között mûködnek, a számok minden egyes bitjére.


1.4.1 Bitenkénti (bitek közötti) ÉS mûvelet
A bitenkénti ÉS mûvelet (AND, &) egy logikai operátor. Fontos, hogy nem összekeverendõ az \"&&\" logikai operátorral! Hasonlít rá, de ez a mûveleteket bitenként végzi. Ez az operátor csak akkor ad eredményül 1-et, ha mindkét bit 1, minden más esetben az eredmény 0. Igazság táblázata:
 
A
B
A&B
0
0
0
1
0
0
0
1
0
1
1
1
[/quote]
Példának nézzük meg, mi történik, ha a bitenkénti ÉS operátort alkalmazzuk, a 11 és a 7 esetén. A 11 bináris számrendszerben 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11&7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 & 00000000000000000000000000000111. Az átláthatóság kedvéért most egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
 
00000000000000000000000000001011
&00000000000000000000000000000111
00000000000000000000000000000011
[/quote]
Eredményül tehát 00000000000000000000000000000011-et kaptunk, ami a kettes számrendszerben a 3-asnak felel meg. A következõ 2 sor tehát ugyanazt jelenti:
 
Bin:
00000000000000000000000000001011
&
00000000000000000000000000000111
=
00000000000000000000000000000011
Dec:
11
&
7
=
3
[/quote]
Még néhány példa, de ezeket már nem részletezem:
 
00000000000000000000000000000011 & 00000000000000000000000000000101 = 00000000000000000000000000000001
00000000000000000000000001110110 & 00000000000000000000000001011001 = 00000000000000000000000001010000
[/quote]


1.4.2 Bitenkénti (bitek közötti) VAGY mûvelet
A bitenkénti VAGY mûvelet (OR, |) egy logikai operátor. Fontos, hogy nem összekeverendõ a \"||\" logikai operátorral! Hasonlít rá, de ez a mûveleteket bitenként végzi. Ez az operátor akkor ad eredményül 1-et, ha legalább az egyik bit 1. Ha egyik bit sem 1, akkor 0-t ad eredményül, ha mindkét bit 1, akkor is 1 az eredmény. Igazság táblázata:
 
A
B
A|B
0
0
0
1
0
1
0
1
1
1
1
1
[/quote]
Példának nézzük meg, mi történik, ha a bitenkénti VAGY operátort alkalmazzuk, szintén a 11 és a 7 esetén. A 11 bináris számrendszerben mint már írtam 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11 | 7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 | 00000000000000000000000000000111. Az átláthatóság kedvéért ismét egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
 
00000000000000000000000000001011
|00000000000000000000000000000111
00000000000000000000000000001111
[/quote]
Eredményül tehát 00000000000000000000000000001111-et kaptunk, ami a kettes számrendszerben a 15-nekk felel meg. A következõ 2 sor tehát ugyanazt jelenti:
 
Bin:
00000000000000000000000000001011
|
00000000000000000000000000000111
=
00000000000000000000000000001111
Dec:
11
|
7
=
15
[/quote]
Megint néhány példa:
 
00000000000000000000000000000011 | 00000000000000000000000000000101 = 00000000000000000000000000000111
00000000000000000000000001110110 | 00000000000000000000000001011001 = 00000000000000000000000001111111
[/quote]


1.4.3 Bitenkénti (bitek közötti) KIZÁRÓ VAGY mûvelet
A bitenkénti KIZÁRÓ VAGY mûvelet (XOR, ^) egy logikai operátor. Ez az operátor nagyon hasonlít a VAGY operátorra, az a fõ különbség a kettõ között, hogy amennyiben mindkét bit 1-es, akkor a KIZÁRÓ VAGY operátor 0-t ad eredményül, a többi esetben ugyanúgy viselkedik mint a VAGY operátor. Igazság táblázata:
 
A
B
A^B
0
0
0
1
0
1
0
1
1
1
1
0
[/quote]
Példának nézzük meg, mi történik, ha a bitenkénti KIZÁRÓ VAGY operátort alkalmazzuk, szintén a 11 és a 7 esetén. A 11 bináris számrendszerben mint már írtam 00000000000000000000000000001011-nek felel meg, a 7 pedig 00000000000000000000000000000111-nek. Tehát a 11 ^ 7, az ugyaz mint ha ezt írnám: 00000000000000000000000000001011 ^ 00000000000000000000000000000111. Az átláthatóság kedvéért ismét egymás alá fogom írni a 2 számot, hogy áttekinthetõbb legyen, és az eredményt pedig a 3. sorba:
 
00000000000000000000000000001011
^00000000000000000000000000000111
00000000000000000000000000001100
[/quote]
Eredményül most 00000000000000000000000000001100-t kaptunk, ami a kettes számrendszerben a 12-nek felel meg. Érdekes, hogy teljesen más eredményt kapunk, pedig lényegében ugyanazt az eredményt adja az operátor, - kis különbséggel ugyebár - mint a VAGY operátor.A következõ 2 sor tehát ugyanazt jelenti:
 
Bin:
00000000000000000000000000001011
^
00000000000000000000000000000111
=
00000000000000000000000000001100
Dec:
11
^
7
=
12
[/quote]
Megint néhány példa:
 
00000000000000000000000000000011 ^ 00000000000000000000000000000101 = 00000000000000000000000000000110
00000000000000000000000001110110 ^ 00000000000000000000000001011001 = 00000000000000000000000000101111
[/quote]
Ezzel kapcsolatban egy érdekességet mutatnék meg. Vegyünk 2 számot. A látványosság kedvéért én példának a 118-at és a 89-et veszem.
 
1. szám: 00000000000000000000000001110110 = 118
2. szám: 00000000000000000000000001011001 =  89
Mûvelet elvégzése: 00000000000000000000000001110110 ^ 00000000000000000000000001011001 = 00000000000000000000000000101111 =  47
1. szám az eredmény, 2. szám az eredeti 2. szám: 00000000000000000000000001011001 =  89
Eredmény: 00000000000000000000000000101111 ^ 00000000000000000000000001011001 = 00000000000000000000000001110110 = 118
[/quote]
Vagyis visszakaptuk a kiindulási állapotot ;)


1.4.4 Bitenkénti (bitek közötti) NEGÁLÁS
A bitenkénti NEGÁLÁS (NOT, ~) az utolsó logikai operátor, melyet meg fogok mutatni. Ez az operátor eléggé eltér az eddigiektõl, leginkább abban, hogy ezt a mûveletet nem 2 bitre alkalmazzuk, hanem csak 1-re. Szokás komplementer-operátornak is hívni(konyhanyelven). Lényegében az 1-esekbõl 0-t, a 0-kból 1-est csinál. Igazság táblázata:
 
A
~A
0
1
1
0
[/quote]
Példának nézzük meg, mi történik, ha a bitenkénti NEGÁLÁST alkalmazzuk a 7-es számra. A 7 bináris számrendszerben mint már írtam 00000000000000000000000000000111-nek felel meg. Tehát a ~7, az ugyaz mint ha ezt írnám: ~00000000000000000000000000000111. Nézzük tehát, mi történik:
 
~00000000000000000000000000000111
11111111111111111111111111111000
[/quote]
Eredményül most 11111111111111111111111111111000-t kaptunk, ami a kettes számrendszerben a -8-nak felel meg. A következõ 2 sor tehát ugyanazt jelenti:
 
Bin:
~
00000000000000000000000000000111
=
11111111111111111111111111111000
Dec:
~
7
=
-8
[/quote]
Megint néhány példa:
 
~00000000000000000000000000000101 = 11111111111111111111111111111011
~00000000000000000000000001110110= 11111111111111111111111110001010
[/quote]
Ehhez kapcsolódóan lenne itt egy fontos megjegyzendõ dolog. Aki nem érti, hogy miért -8 a megoldás, az nem olvasta el elég rendesen a \"Részletesebben a bitekrõl a Pawn-ban\" részt.


1.4.5 Biteltolás (arithmetic shift, shiftelés) operátor(ok)
A shift operátorok(<<, >>) a bitek tologatására használhatóak. A << balra tol, a >> jobbra. Bal oldalt található a szám, amit tologatni kívánunk, jobb oldalt pedig az, hogy mennyivel szeretnénk eltolni.
1.4.5.1 Jobbra toló operátor(>>):
Ez az operátor a szám bitjeit jobbra tolja a megadott mértékkel. Egy bittel való eltolás, 2-vel való osztásnak felel meg. Nézzünk egy példát:
 
00000000000000000000000000001000//8
>>2
00000000000000000000000000000010//2
[/quote]
Láthatjuk, hogy semmi más nem történt, mint minden bitet 2-vel hátrébb mozgattunk. Az így \"megüresedett\" bitek helyére pedig 0-k kerültek. Lényegében az történt, hogy az utolsó 2 bit kiesett, az így megmaradt biteket 2-vel hátrébb csúsztattuk, majd az elsõ 2, így \"üres\" bit 0 értéket kapott.
Nézzünk egy példát negatív számmal:
 
11111111111111111111111111110000//-8
>>2
11111111111111111111111111111100//-2
[/quote]
Láthatjuk, hogy itt fontos szerepe van az MSB-nek. Ettõl függ ugyanis, hogy 0-k vagy 1-esek kerülnek a \"megüresedett\" bitek helyére. Fontos tehát megjegyezni, hogy a jobbra shiftelés megtartja a számok elõjelét, nem változtat azon!
1.4.5.2 Balra toló operátor(<<):
Ez az operátor a szám bitjeit balra tolja a megadott mértékkel. Egy bittel való eltolás, 2-vel való szorzásnak felel meg. Nézzünk egy példát:
 
00000000000000000000000000001000//8
<<2
00000000000000000000000000100000//32
[/quote]
Itt megint könnyedén észrevehetõ mi is történt. Minden bitet fentebb \"toltunk\" 2-vel. Azok a bitek, amelyek ezáltal a 32. bit elé kerültek, kiesnek. Az így megüresedett bitek 0-kkal egészültek ki. Eddig nem túl bonyolult. Azonban figyeljünk oda, ha túl sokáig shiftelünk egy pozitív számot, akkor az utolsó érték, melyet fel tud venni a változónk (mielõtt még túlcsordulás miatt elérné a 0-t), az egy negatív szám!
Nézzük mi történik negatív számok esetén:
 
11111111111111111111111111111000//-8
<<2
11111111111111111111111111100000//-32
[/quote]
Láthatjuk hogy a balra shifteléskor a szám mindig 0-kkal egészítõdik ki, legyen az akár negatív, akár pozitív. Nem veszi figyelembe az MSB értékét, így ha túl sokat shiftelünk, akkor elõfordulhat, hogy a szám elveszti negatív értékét, és eléri a 0-t.


1.4.6 Logikai biteltolás (logical shift, logikai shiftelés) operátor
Elõször is le kell tisztázni, hogy logikai shiftelésbõl csak egy létezik, jobbra logikai shiftelés(>>>). Sokban hasonlít a jobbra shiftelõ operátorra (>>), azonban van egy fontos különbség.
Nézzük az elsõ példát:
 
00000000000000000000000000001000//8
>>>2
00000000000000000000000000000010//2
[/quote]
Eddig nem igazán tapasztalhattunk semmi változást, minden pont ugyanúgy zajlott, mint a jobbra shiftelésnél(>>).
Nézzük mi történik negatív szám esetén:
 
11111111111111111111111111111000//-8
>>>2
00111111111111111111111111111110 //1073741822
[/quote]
Itt már láthatjuk a különbséget. Logikai shiftelés esetén az üres bitek helyére bekerülõ érték nem függ az MSB-tõl, hanem mindig 0. Emiatt soha nem kaphatunk eredményül negatív számot, logikai shiftelés esetén.


1.5 Elsõ fejezet vége
Nos, ezennel átvettünk mindent, amit érdemes tudni a bitmûveletekrõl. Megmutattam az alapok, hogy hogyan épülnek fel a változók, valamint átvettük a fõ operátorokat. Eddig csak színtiszta elmélet volt. A következõ részben megmutatom, hogyan hasznosíthatjuk mindezt a gyakorlatban, vagyis mire is jó az a sok marhaság, amit eddig leírtam.


2. Gyakorlati példák, érdekességek
 


2.1 Áttekintés, mikrõl is lesz még szó
Az alábbiakban még pár dolgot szeretnék mutatni. Elõször is néhány \"függvénnyel\" fogok foglalkozni, majd mutatok még egy-két érdekességet. Konkrétan megmutatom, hogyan tudjuk egy jármû minden \"paneljének\" adatát kiíratni, részletesen(erre alapból nincs lehetõség, és a függvények is mind \"encode\" függvények, én viszont mutatok egy-egy decode \"verziót\" is.)
Az alábbi 4 függvénnyel fogok foglalkozni:
 
  • encode_tires

  • encode_panels

  • encode_doors

  • encode_lights


De elõbb egy kis háttérinfó:
A Pawnban a forrásban megadhatunk bináris számokat ugyanúgy, ahogyan Hex számokat is megadhatunk. Ehhez a \"0b\" prefixet kell használnunk. Tehát ha bináris számunk az 1011 és ezt akarjuk adni értékül egy változónak, azt így tehetjük meg:
 
new var = 0b1011;

 


2.2 encode_tires
Háttér információ:
A SA:MP-ban egy jármû abroncsainak adataid 4 bit tárolja. Az elsõ bit a jobb hátsó, a második bit a jobb elsõ, a harmadik bit a bal hátsó, a negyedik bit pedig a bal elsõ abroncsról tárol információt. Mivel 4 bitben eltárolhatóak az információk, így decimális formában 0-15 értékekkel is be lehet állítani a jármûvek abroncsait. 16-tól kezdve az értékek már ismétlõdni kezdenek, szóval a 16-nál az eredmény ugyanaz mint 0-nál, 17-nél ugyanaz mind 1-nél, és így tovább. Ez érthetõ, ha tudjuk hogyan épül fel a kettes számrendszer.(Ne felejtsük el, a biteket hátulról számozzuk!)
Nos nézzük hogyan néz ki a kód:
 
encode_tires(tire1, tire2, tire3, tire4)
{
    return tire1 | tire2 << 1 | tire3 << 2 | tire4 << 3;
}

 
Láthatjuk, hogy bekérjük a 4 abroncs adatát(vagyis hogy ép[0], vagy kidurrant[1]), majd egy sima bitenkénti VAGY mûvelet és biteltolás kombinálásával visszatérünk az eredménnyel. A kódban a tire1 felel meg a jobb hátsó abroncsnak, a tire2 a jobb elsõ, a tire3 a bal hátsó, és a tire4 a bal elsõnek.
Nézzünk egy konkrét példát. Tegyük fel, hogy én a hátsó 2 abroncsot ki akarom durrantani, még az elsõ kettõt épre akarom beállítani. Ez esetben így néz ki a dolog:
 
encode_tire(1,0,1,0);

 
Ha kiíratnánk konzolba a visszatérési értéket (%d-vel), 5-öt kapnánk. Miért is? Az 5 bináris alakja 0101. Hoppá, ha megnézzük ez pont fordítottja annak, amit mi megadtunk számjegyekként, csak már konkrét bináris számként. Nézzük hogyan is történhetett mindez, mit is csináltunk. A függvény a következõ mûveletet végzi:
 
tire1 | tire2 << 1 | tire3 << 2 | tire4 << 3

 
Konyhanyelven úgy magyarázhatnánk el a dolgot, hogy ez a kód egymás mellé pakolgatja a megadott számokat, fordított sorrendben. Na de mi most nem a konyhanyelv miatt vagyunk ebben a leírásban, szóval nézzük a kódunkat. Lényegében ez futott le, a konkrét értékeinkkel nézve:
 
1 | 0 << 1 | 1 << 2 | 0 << 3

 
Bármily furcsa is, ez egy mûvelet, melyen szépen végig halad sorban a program. Elõször is írjuk át az egészet bináris alakba(az egyszerûség kedvéért most csak 4 bitet fogok kiírni):
 
0001 | 0000 << 1 | 0001 << 2 | 0000 << 3

 
Na erre se mondtuk volna rá a tutorial elsõ részének elolvasása elõtt, hogy ez egy mûveletsor. A rendszer elsõnek az eltolásokat végzi el (olyan ez mint a 2*3+2*4+2*5 mûveletben elõször a szorzásokat végezzük el, és csak utána adunk össze, ha nincs zárójel), és csak utána a bitenkénti VAGY mûveleteket, ezért mi is így fogunk tenni. Emlékezzünk, eltoláskor az \"üres\" bitek 0 értéket fognak felvenni. Végezzük el külön csak az eltolásokat:
 
0000 << 1 = 0000
0001 << 2 = 0100
0000 << 3 0000

 
Nos, ha ezeket elvégeztük, akkor nézzük, hogy is áll most a kódunk:
 
0001 | 0000 | 0100 | 0000

 
Négy azonos mûvelet van hátra, így hát a program innen más szépen sorban fog haladni. Tegyünk mi is így. Elsõ tehát a 0001 | 0000 mûvelet elvégzése. Emlékeztetõül, a bitenkénti VAGY mûvelet akkor ad 0-t eredményül, ha mind a kettõ érték 0, minden más esetben 1-et. Végezzük el külön az elsõ bitenkénti VAGY mûveletet:
 
0001 | 0000 = 0001

 
Nem volt bonyolult, nézzük tehát hogy áll akkor most a teljes mûveletünk:
 
0001 | 0100 | 0000

 
Haladunk szépen tovább, elvégezzük a 0001 | 0100 mûveletet.
 
0001 | 0100 = 0101

 
Nincs mit magyarázni rajta, egyszerû bitenkénti VAGY mûvelet volt ez is. Már csak ez van hátra:
 
0101 | 0000

 
Nos, ez sem lesz egy bonyolult mûvelet:
 
0101 | 0000 = 0101

 
Ezzel meg is kaptuk a végeredményt, ami nem más, mint a 0101 (tízes számrendszerben 5). Mivel azonban eléggé kusza lett így a számításunk, nézzük egyben hogyan is néz ki az egész, ha nem bontom ennyire részekre:
 
0100 | 0000 << 1 | 0001 << 2 | 0000 << 3
v
0001 | 0000 | 0100 | 0000
v
0001 | 0100 | 0000
v
0101 | 0000
v
0101

 
Nos, ezennel láthattuk a gyakorlatban is, hogyan mûködik a függvény. Kijelenthetjük tehát, hogy a függvény a számokat a sorrendjüknek megfelelõ számú bitbe helyezi. Mivel azonban a biteket hátulról számozzuk, így az 1,0,1,0 bemenetek végeredménye 0101 lesz. Így már nem is olyan bonyolult :)
Na, ha már ilyen sokáig eljutottunk, akkor felhasználhatjuk ezt a kódot arra, hogy az alapjait figyelembe véve elkészítsük a decode változatot. Mivel 4 értékkel térünk vissza, ezért paraméterként kell majd 4 változó, melyeknek módosíthatjuk az értékét, illetve 1 paraméter pedig a dekódolandó szám. A függvényünk \"címsora\" tehát így néz ki:
 
decode_tires(tires, &tire1, &tire2, &tire3, &tire4)

 
Hogy példánk ne csak elmélet legyen, a tires változó legyen az elõbbi 0101 értékkel egyenlõ.
Na akkor menjünk tovább. Bemeneti értékünk ugye a \"tires\" változóban lesz eltárolva, így ezzel fogjuk a mûveleteket végezni. Kezdjünk el gondolkozni. Hogyan is tudnánk ellenõrizni egy adatot. Legegyszerûbb ha a bitenkénti ÉS mûveletet alkalmazzuk. Miért is? Nos, a bitenkénti ÉS mûvelet ugye akkor ad eredményül 1-et, ha mind a 2 érték egy. Tehát ha min egy számot összehasonlítunk a 1-el(binárisan ugye 00000000000000000000000000000001, akkor az eredményünk lényegében arról fog tájékoztatni, hogy az elsõ bit 0, vagy 1. Nem is olyan bonyolult ez. Nézzük akkor az elsõ bitet. Arra emlékezhetünk még, hogy az elsõ bit a tire1, vagyis jobb hátsó abroncs adatait tárolja. Tehát:
 
tire1 = tires & 1;

 
Vagy konkrétan a példánk esetében:
 
tire1 = 0101 & 0001

 
Mivel a bitenkénti ÉS mûvelet akkor ad 1-et eredményül, ha mind a kettõ bit 1, akkor már láthatjuk is, hogy miért elegendõ az elsõ bitet szemügyre venni. Mivel mind a 2 helyen az elsõ bit 1, ezért a tire1 változónk értéke is 1(0001) lesz. Egyszerû és nagyszerû, máris megkaptuk a jobb hátsó abroncs állapotát.
Gondolkozzunk hát tovább. Nekünk most arra van szükségünk, hogy a 2. bit értékét megkapjuk. Hogyan kaphatjuk ezt meg? Legegyszerûbb megoldás, ha a tires változót jobbra shifteljük 1-el, majd ismételten bitenkénti ÉS mûveletet végzünk. Nézzük tehát, hogyan is nézne ez ki:
 
tire2= tires >> 1 & 1;

 
Vagy konkrétan a mi példánkban:
 
tire2 = 0101 >> 1 & 0001
v
tire2 = 0010 & 0001

 
Ismételten bitenkénti ÉS mûvelet, és az eredményünk 0, mivel csak az egyik bit 1, a másik 0, így a bitenkénti ÉS mûvelet eredménye is 0. Ezen az elven megcsináljuk a maradék 2 abronccsal is:
 
tire3= tires >> 2 & 1;
tire4= tires >> 3 & 1;

 
Vagy a mi esetünkben konkrét példánkkal:
 
tire3 = 0101 >> 2 & 0001 // azaz: --> 0001 & 0001 = 1
tire4 = 0101 >> 3 & 0001 // azaz: --> 0000 & 0001 = 0

 
A teljes kódunk tehát:
 
decode_tires(tires, &tire1, &tire2, &tire3, &tire4)
{
    tire1 = tires & 1;
    tire2 = tires >> 1 & 1;
    tire3 = tires >> 2 & 1;
    tire4 = tires >> 3 & 1;
}

 
A konkrét példánkban a 4 változónk értéke a függvény lefutása után:
 
tire1: 1
tire2: 0
tire3: 1
tire4: 0

 
Ha összehasonlítjuk, ezek pont azok az értékek, mint amiket az encode függvényben megadtunk, tehát úgy tûnik jól dolgoztunk ;)


2.3 encode_lights
Ez a rész lesz a legrövidebb. Az egész lámpás rész pontosan ugyanarra a sémára épül mint az abroncsok. Az adott bitek ugyanazon a \"helyen\" lévõ lámpa adatait szolgáltatják, ugyanúgy 0 az ép, és 1 a sérült lámpák állapot azonosítója, és ugyanúgy 1-1 bit tárolja az értékeket.
Maga a kód:
 
encode_lights(light1, light2, light3, light4)
{
    return light1 | light2 << 1 | light3 << 2 | light4 << 3;
}

 
Láthatjuk hogy halál pontosan ugyanaz mint az encode_tires, csak más változónevekkel. Így hát a decode függvény is ugyan az lesz, csak a változóneveket kell módosítanunk:
 
decode_lights(lights, &light1, &light2, &light3, &light4)
{
    light1 = lights & 1;
    light2 = lights >> 1 & 1;
    light3 = lights >> 2 & 1;
    light4 = lights >> 3 & 1;
}

 
Ha megnézzük látjuk, hogy teljesen ugyan az a séma, ugyan az a felépítés, minden megegyezik, ezért nem is írtam le újból ugyanazt, amit egyszer már kifejtettem.


2.4 encode_panels
Háttér információ:
A SA:MP 7 panelrõl tárol adatokat. Egy panel adatait 4 bit írja le. Nos, ennél több infóra nekünk most nincs szükségünk, az elõzõ kód alapján ezen kód is megérthetõ, így az encode verzióhoz nem is nagyon szeretnék magyarázatot fûzni. A különbség az encode_tires-hez képest, hogy itt 4-essével shiftelünk, mivel 1 panel adatait 4 bit tárolja.
Maga a kód:
 
encode_panels(flp, frp, rlp, rrp, windshield, front_bumper, rear_bumper)
{
    return flp | frp << 4 | rlp << 8 | rrp << 12 | windshield << 16 | front_bumper << 20 | rear_bumper << 24;
}

 
Nézzünk egy decode verziót, ehhez a kódhoz. Alapjaiban ugyanazon a vonalon kell elindulnunk, mint a decode_tires esetében. Itt most 7 visszatérési értékünk lesz, és 1 bemeneti érték. Tehát így néz ki a függvény header:
 
decode_panels(panels, &flp, &frp, &rlp, &rrp, &windshield, &front_bumper, &rear_bumper)

 
A folytatásban megint csak az elõbbi verziót kell alapul vennünk, azonban itt lesz egy kis különbség. Egyértelmû, hogy mivel 1 panel adatait 4 bit tárolja, így a 4 bitet nekünk egyben kell lekérni, és egyben kell vele visszatérnünk. Megint csak a bitenkénti ÉS mûveletet fogjuk alkalmazni, azonban mivel 4 bitrõl van szó, így egy olyan számmal kell összehasonlítanunk, mely bináris alakban 1111. Ez a szám nem más, mint a 15. Hogy miért ez kell?
Ha egy bitsorozat tartalmát ki szeretnénk másolni egy másik változóba, akkor a bitenkénti ÉS mûveletre vna szükségünk. A bitenkénti ÉS mûvelet akkor ad 1-et eredményül, ha mindkét bit 1, ha valamelyik 0, akkor a visszatérés már 0 lesz. Ergó tehát, ha egy csupa 1-esekbõl álló bitsorozattal vetjük össze az eredeti bitsorozatunkat, akkor lényegében lemásoljuk a sorozatot, egy másik változóba, hisz eredményül mindig az eredeti sozatot fogjuk visszakapni. Íme néhány példa:
 
0101 & 1111 = 0101
1111 & 1111 = 1111
0000 & 1111 = 0000
1011 & 1111 = 1011

 
Láthatjuk tehát, hogy ha csupa 1-est tartalmazó bitsorozattal hasonlítjuk össze az eredeti számunkat, akkor lényegében egy másolatot készítünk. Mivel nekünk erre a 4 bitre van szükségünk a 32-bõl, így pontosan ezt kell tennünk, ezen 4 bitet lemásolni egy másik változóba, hogy késõbb ezt majd egy másik függvénnyel még jobban darabokra szedhessük.
Íme tehát akkor a kódunk elsõ sora:
 
flp = panels & 15;

 
Mivel 4-esével vizsgáljuk a biteket, így lényegében annyit kell még változtatnunk az elõzõ kódon(decode_tires), hogy az 1-esével növekvõ shiftelések helyett 4-esével shifteljünk. Azaz a 2. panel adatainak lekérdezése:
 
frp = panels >> 4 & 15;

 
Innen pedig már csak mindig további 4 shiftelést el kell végeznünk, és szépen végig haladhatunk a panels változó bitjein, és megkaphatjuk minden panel adatait külön-külön.
 
rlp = panels >> 8 & 15;
rrp = panels >> 12 & 15;
windshield = panels >> 16 & 15;
front_bumper= panels >> 20 & 15;
rear_bumper = panels >> 24 & 15;

 
Ezennel minden panel adatait megkaptuk. Ezután már akár a decode_tires függvényt felhasználva szét lehet szedni az adatokat darabokra, de akár egy saját névvel, és más változó nevekkel ellátott másik függvényt is létre lehet hozni a decode_tires mintájára.
Tehát az egész kód egyben:
 
decode_panels(panels, &flp, &frp, &rlp, &rrp, &windshield, &front_bumper, &rear_bumper)
{
    flp = panels & 15;
    frp = panels >> 4 & 15;
    rlp = panels >> 8 & 15;
    rrp = panels >> 12 & 15;
    windshield = panels >> 16 & 15;
    front_bumper= panels >> 20 & 15;
    rear_bumper = panels >> 24 & 15;
}

 
Igazából a függvény ugyanarra a sémára épül mint a decode_tires, csak annyi a különbség, hogy 4 bitenként kapjuk az adatokat, nem pedig egyesével, mivel itt minden panelnek 4 adatát tudjuk majd még lekérdezni. Nem tudom lehet-e még ehhez a részhez hozzáfûzni valamit, szóval szerintem ugorjunk.


2.5 encode_doors
Háttér információ:
A SA:MP képes minden jármû 4 \"ajtajának\" állapotát tárolni. Ezek az \"ajtók\"(Doors-t hogy fordíthatnám jobban?) konkrétan a motorháztetõ, csomagtartó, vezetõoldali ajtó, és anyósülés oldali ajtó. A 2 hátsó ajtó állapotát jelenleg még nincs lehetõségünk lekérdezni.
Amikor lekérdezzük egy jármû \"ajtajának\" adatait, azt a SA:MP 4 bájtként(32 bit) adja vissza. Ebbõl a 4 bájtból 1 bájt(8 bit) jut minden egyes objektumra. Vagyis minden egyes objektum adatait 8 bit tárolja. Vagyis tárolhatná...
A SA:MP csak az elsõ 3 bitet használja, a további bitek üresek lesznek, nincs funkciójuk, talán majd késõbb lesz. Az elsõ bit azt tárolja, hogy az objektum zárt[0], vagy nyitott[1](nem az jelenti, hogy bezárt, hanem becsukott/kinyitott) állapotban van-e. A második bit azt adja meg, hogy az objektum ép[0] vagy sérült[1]. A 3. bit arról tájékoztat, hogy az adott objektum rajta van-e még a jármûvön[0] vagy már leesett[1]. A többi bit mint mondtam üres. Ez majd a decode függvénynél lesz fontos.
Nézzük tehát a konkrét kódot:
 
encode_doors(bonnet, boot, driver_door, passenger_door, behind_driver_door, behind_passenger_door)
{
    #pragma unused behind_driver_door
    #pragma unused behind_passenger_door
    return bonnet | boot << 8 | driver_door << 16 | passenger_door << 24;
}

 
A 2 hátsó ajtóval nem foglalkozunk, mivel azok jelenleg még nem támogatottak ugyebár, de a kód készítõje gondolt a jövõre is, vagy fogalmam sincs miért adta meg ezt a két paramétert is, hisz ígyis-úgyis módosítani kell a kódon... Ha behoznak még 2 ajtót, akkor az 1 bájtos tárolással már 6 bájt lenne, de 1 változó maximum 4 bájt lehet, tehát a kódot úgyis módosítani kell, ha meg arra gondoltak, hogy legalább a paramétereket nem kell majd szegény scriptereknek minden sorban átírni, az megint hülyeség, hisz ki adna értéket olyan paraméternek, amely nincs használva?...
Nos mindegy, nem a kritizálásért vagyunk most itt. Ha megnézzük, a kód 8-as shiftelést használ, mivel egy objektum adatait 8 bit tárolja. A mûködési elv ugyanaz, mint az elõzõ encode függvényeknél, így erre nem kívánok megint kitérni.
Nézzük azonban hogyan írnánk ehhez egy decode függvényt. Mikor megkérdeztem errõl ismerõsömet, õ azt mondta, ugyanúgy mint az elõzõ, decode_panels függvénynél, csak 8-as shiftelést használunk, és 15 helyett 255-el végezzük a bitenkénti ÉS mûveletet. 255-el? minek?
No erre is ki fogok térni késõbb, de haladjunk a szokásos módon. 1 bemeneti paraméterünk van, és 4 kimeneti, vagyis a header rész a következõ:
 
decode_doors(doors, &bonnet, &boot, &driver_door, &passenger_door)

 
Ezzel meg is vagyunk, itt nem látok különösebb magyarázni valót. Én most nem fogok törõdni a 2 nem létezõ ajtóval, ha egy jövõbeni verzióban netán azokat is behoznák mint lekérdezhetõ objektum, akkor ígyis-úgyis módosítani kell majd a kódot, addig meg úgysincs rá szükségünk.
Nos, mint az eddigi decode függvényeknél, elsõ feladatunk egy shiftelés mentes bitenkénti ÉS mûvelet elvégzése. Az egyik megoldás a következõ:
 
bonnet = doors & 255;

 
Lehet így is. Azonban véleményem szerint felesleges itt egy ekkora számmal \"szenvednünk\". Miért használjunk ekkora számot, és ezáltal bonyolítsuk feleslegesen a kódunkat, ha nekünk a 8 bitbõl csak az elsõ 3 lesz ami adatot tárol? Bõven elegendõ egy olyan szám, amely bináris alakja 111. Ez nem más, mint a 7. Tehát a következõ megoldás ugyanúgy helyes:
 
bonnet = doors & 7;

 
A két kód pontosan ugyanazt az eredményt fogja visszaadni, semmi különbség a kettõ között. Csupán elsõ esetében nagy számmal dolgozunk, még második verzió esetén csak akkorával, amekkora szükséges.
A kód többi részében csak 8-as shifteléssel végigcammogunk a doors változó többi bitjén is:
 
boot = doors >> 8 & 7;
driver_door = doors >> 16 & 7;
passenger_door = doors >> 24 & 7;

 
A teljes kód egyben:
 
decode_doors(doors, &bonnet, &boot, &driver_door, &passenger_door)
{
    bonnet = doors & 7;
    boot = doors >> 8 & 7;
    driver_door = doors >> 16 & 7;
    passenger_door = doors >> 24 & 7;
}

 
A kód pont ugyanazon az elven épül fel, mint az összes többi decode függvényünk, csak épp a benne használatos értékek az \"ajtó\" objectumok adatstruktúrájához vannak igazítva.


2.6 Egyéb ötletek gyakorlati alkalmazásra, hasznosításra
Joggal felmerülhet a kérdés, hogy ennyi? Emiatt rágtuk végig magunkat ezen néhány tízezer karakteren? Nem. Nem ennyi. A SA:MP-ban rengeteg felhasználási módja lehet még a bitmûveleteknek. Mutatok is néhány dolgot, mire jók még.
2.6.1 RGBA->HEX; HEX->RGBA konvertálások
Nos, bármily \"hihetetlen\", erre is használható. Miért is? Nos, 16-os számrendszerben 0-9, valamint A-F \"szánjegyek\" léteznek. A hexadecimális számjegy decimális értékben 0-15 lehet. Ha megnézzük bináris értékeket, 0-15 az 4 bittel leírható, hiszen a 15 az bináris alakban 1111. De ha józan paraszti ésszel belegondolunk is. 16 az 24. Így tehát 1 hexadecimális érték, az 4 bináris értékkel írható le. Ebbõl már sejthetõ, hogy itt is shiftelésre lesz szükségünk. Naná :) Mivel 4 bit ír le egy hexadecimális számjegyet, így 4-esével kell majd shiftelnünk.
Mi is az az RGBA?
RGBA: A színek olyan meghatározási módja, melyben a 3 alapszín([r]ed, [g]reen, lue) mellett egy 4. érték, az úgynevezett [a]lpha is szerepel, amely az áttetszõséget adja meg. A legtöbb program(pl. paint, PS), és pl. a css(külön függvénnyel!) is elfogadja ezen értékeket decimális számokként(0-255) is, a SA:MP-ban azonban hexadecimális alakban kell megadnunk. Bármily furcsa a következõ 4 sor pont ugyan azt jelenti:


\"Normál\" RGB alak(pl. paint, photoshop): Piros: 0, Zöld: 255, Kék: 255
CSS alak(függvénnyel): rgba(0, 255, 255, 1);
Pawn alak(1): 0x00FFFFFF
Pawn alak(2): 16777215

 

Ó igen, a Pawn-ban decimális számokként is megadhatjuk a színeket, hisz a program mindent bináris számrendszerbe fog átszámolni. De akár bináris alakban is megadhattuk volna:



Pawn alak(3): 0b111111111111111111111111

 

Az, hogy mi a Pawn-nak hexadecimális alakban szoktuk megadni, annak az egyetlen oka, hogy így a leginkább \"átlátható\", és ez egy amúgy is elfogadott módja (mármint a hexadecimális számmal való megadás) a színek leírásának a számítástechnikában.


Nos, mivel 1 szín 0 és 255 közötti értéket tartalmaz a piros, zöld és kék színekbõl, ez hexadecimálisan 2 számjeggyel leírható: 00-FF. Az FF értéke 255, aki nem hiszi, számoljon utána :D (16
2-1)

2 hexadecimális számjegy az pedig 8 bináris számjeggyel leírható(00000000-11111111). Így már láthatjuk, hogy 8-as shiftelésre lesz szükségünk. Másra nincs is szükségünk, az RGBA->HEX konverter elkészítéséhez.




stock RGBAToHex( r, g, b, a )
{
return a | b << 8 | g << 16 | r << 24;
}

 

Az, hogy miért fordított sorrendben kellett megadnunk az értékeket, az megint csak azzal magyarázható, hogy a biteket hétköznapi értelemben véve visszafelé számozzuk.


Egy ellentét, azaz HexToRGBA függvény megírása sem túl bonyolult, ugyan ezt kell csinálnunk, csak visszafelé.



stock HexToRGBA( colour, &r, &g, &b, &a )
{
a = colour & 0xFF;
b = (colour >> 8 ) & 0xFF;
g = (colour >> 16 ) & 0xFF;
r = (colour >> 24 ) & 0xFF;
}

 

A 0xFF-et természetesen decimális értékkel is megadhatjuk(255).


No akkor lehet ugye RGBA-t ARGB-be is konvertálni, az így néz ki:



RGBAToARGBHEX(r,g,b,a)
{
return (r & 0xff) << 24 | (g & 0xff) << 16 | (b & 0xff) << 8 | a & 0xff;
}

 

Ez máris egy újabb felhasználási módja a bitmûveleteknek. De, mutatok még :)


2.6.2 Boolen változók helyett Integer

Az al-al-alcímet elolvasva joggal felmerülhet a kérdés, hogy ez meg hogy jön ide. Nos ez úgy jön ide, hogy most egy kis memóriatakarékosságról fogok itt regélni. Adhattam volna azt is címnek, hogy miért ne használjunk boolean változókat, ha legalább 5 igaz/hamis értéket el akarunk tárolni.


Nos akkor egy kis memórialecke. Azt már tisztáztuk, hogy az integer változók 32 bitesek, vagyis 4 bájtot foglalnak le a memóriában maguknak. A boolean típusú változókról azonban még nem volt szó. Mivel 1 értéket tárolnak csak, az is csak igaz vagy hamis lehet, így joggal gondolhatnánk, hogy 1 bit a mérete. Azonban nem...


1 boolean változó 8 bitet, azaz 1 bájtot foglal le magának a memóriában. Hogy ez miért így van, az a számítógépek memóriahasználatával magyarázható. Manapság nincs mód arra, hogy a memóriában egyetlen bitet módosítsunk, csak 8-as \"csomagokban\", vagyis bájtonként tudjuk ezt megtenni. Hogy ez miért van így, azt most nem fogom itt fejtegetni :)


Nos, ha megnézzük tehát, a boolean változó egy nagyon-nagyon pazarló megoldás. Hiszen 1 darab boolean változó 1 bájtot foglal, 4 darab boolean változó esetén ez már 4 bájt, ami megegyezik 1 integer változó méretével. Azonban, még a 4 boolean változóban 4 igaz/hamis érték kerülhet tárolásra, addig egy integerben 32 igaz/hamis értéket is eltárolhatunk.


Bizony, 32 igaz/hamis érték. Hiszen 1 integer változó 32 bitbõl áll, ha minden bitet hasznosítunk, akkor a bitmûveletek felhasználásával 32 igaz/hamis értéket is eltárolhatunk. Összehasonlítva:



32 darab boolean változó mérete 32 bájt.
1 integer változó mérete: 4 bájt.

 

Vagyis 32 boolean változó esetén nyolcad annyi memóriánkba kerül, ha egy darab integerben tároljuk el az értékeket. Persze 32 booleanra ritkán van szükség, de egy RP modban simán elõfordulhat. Gondoljunk csak bele...


Van 32 boolean-tömbös változónk, ez a maximum slotszámot(1000) figyelembe véve: 32*1000 byte azaz 32000 byte ami ~31 kilobyte.


Ha ezt egyetlen integer-tömbbel oldanánk meg: 4*1000 byte, azaz 4000 byte, ami  ~3,9 kilobyte. Azért így nézve már nem annyira \"elhanyagolandó\" az a különbség szerintem =)


Akár írhatnánk erre külön egy függvényt, mely az adott bit értékével tér vissza. Nem is bonyolult. Így már azok számára is használhatóak a bitmûveletek, akik nem értenek hozzá, és rengeteg memóriát takaríthatnak meg.


Íme egy függvény az adatok kiolvasására:



stock GetData(integer, bit)
{
    return integer >> bit & 1; //vagy az 1 helyett akár 0x01 alakban is megadhatjuk, nincs jelentõsége
}

 

És a párja, adat írásra:



stock SetData(&integer, bit, value)
{
    integer |= value << bit;
    return 1;
}

 

Persze ezt még lehetne csinosítani, hogy pl. ne 0-tól hanem 1-tõl számoljuk a biteket, vagy hogy 31(vagy 32 ha 1-tõl számolunk) felett 0 legyen a return értéke, esetleg a value-re is rakhatnánk ellenõrzést, hogy 0-1-e az értéke, vagy más, de ilyenekkel most nem törõdtem.


2.6.3 Több érték, egy integerbe

Na ez az a rész, ami véleményem szerint már csak a nagyon megrögzött memóriafelszabadítók szerint nem lesz felesleges :D Amennyiben nincs szükségünk túl nagy számokra(pl. csak 0-15, vagy akár csak 0-7, de akár még a 0-255 is megfelel), akkor akár egy integerbe is tehetjük õket. Hogyan? Egyszerû. Csoportosítjuk a biteket. Tegyük fel, hogy maradván egy RP szervernél, el akarjuk tárolni ûbergigantikusan memóriakímélõ megoldással a játékos házának számát(ez legyen mondjuk 0-100 közötti szám), a játékos frakcióját(ez legyen 0-15 között), a játékos rangját(0-7 között), hogy a telefonja be van-e kapcsolva(0-1), a játékos szolgálati jármûvének id-jét(legyen 0-255 között), és az alapmunkáját(0-15 között). Ez is megoldható, egyetlen integerben, és ismételten 1000 slottal számolva máris megspóroltunk 4*4*1000+1*1000 byte-t(5 integer, és 1 boolean helyett csupán 1 integert használunk), ami ~16,6 kilobyte. Azért nem mindegy az, hogy 20,5 kb-ot vagy 4 kb-ot használunk szerintem... :)


Ezt a következõ módszerrel valósíthatnánk meg:



#define DATA_HOUSE 0
#define DATA_FACTION 1
#define DATA_RANK 2
#define DATA_PHONESTATE 3
#define DATA_DUTYCAR 4
#define DATA_JOB 5
stock GetData(playerinfo, data)
{
    switch(data)
    {
        case DATA_HOUSE: return playerinfo & 127;//7 bit
        case DATA_FACTION: return playerinfo >> 7 & 15;//4 bit
        case DATA_RANK: return playerinfo >> 11 & 7;//3 bit
        case DATA_PHONESTATE: return playerinfo >> 14 & 1;//1 bit
        case DATA_DUTYCAR: return playerinfo >> 15 & 255;//8 bit
        case DATA_JOB: return playerinfo >> 23 & 15;//4 bit
}
return -1;
}
stock SetData(&playerinfo, data, value)
{
    switch(data)
    {
        case DATA_HOUSE: { playerinfo = playerinfo & ~127 | value; }//7 bit (0-127 közötti maximálisan)
        case DATA_FACTION: { playerinfo = playerinfo & ~(15 << 7) | value << 7; }//4 bit (0-15 között)
        case DATA_RANK: { playerinfo = playerinfo & ~(7 << 11) | value << 11; }//3 bit (0-7 között)
        case DATA_PHONESTATE: { playerinfo = playerinfo & ~(1 << 14) | value << 14; }//1 bit (0-1)
        case DATA_DUTYCAR: { playerinfo = playerinfo & ~(255 << 15) | value << 15; }//8 bit (0-255 között)
        case DATA_JOB: { playerinfo = playerinfo & ~(15 << 23) | value << 23; }//4 bit (0-15 között)
    }
    return -1;
}
stock SetDatas(&playerinfo, house, faction, rank, phonestate, dutycar, job)
{
playerinfo |= house | (faction << 7) | (rank << 11) | (phonestate << 14) | (dutycar << 15) | (job << 23);
}

 

Ez már azért elég morbid, ezt inkább csak érdekességképp mutattam, de éppenséggel ez is használható lenne, csak ehhez már kell egy kis õrültség :D




2.7 Második fejezet vége

Nos, láthattuk hogyan is mûködik mindazon sok \"marhaság\", amit az elsõ fejezetben elméletként átvettünk. Láthattuk hogyan mûködnek a jármûvek paneljének adataival babráló encode függvények, valamint megmutattam, hogyan írhatunk hozzájuk decode verziókat. Láthattunk még példát egyéb gyakorlati hasznosításra, kicsit megkoccoltuk a hexadecimális számok világát is, majd szóba került egy kis memóriatakarékosság. Végül mutattam egy összetettebb, elvetemült példát is, a bitmûveletek hasznosítására.





3. Összegzés, végszó
 

Úgy gondolom, hogy elég részletesen körbe jártuk a témát. Megnéztük a bitmûveletek elméleti, és gyakorlati oldalát is, láthattunk gyakorlati példákat. Nem kell elsõre megérteni ezt az egészet, sõt... Elegendõ ha egyszer elolvassuk, emésztjük kicsit, majd késõbb megint elõvesszük, akkor netán már kicsit többet is megértünk belõle. Nem egy kihagyhatatlan része a Pawno-nak, de azért van annak haszna, ha az ember jártas ebben a témában is, bár sokak szerint nem éri meg a sok fáradtságot, és idõt, mely a megértéséhez, begyakorlásához, használatának elsajátításához szükséges.


Próbáltam mindent részletesen kifejteni. A bonyolultabb dolgokhoz sokat magyarázni, az egyszerûbbek esetén csak visszautalni az alapokhoz. Sok dolgot talán már túl is magyaráztam. Ezt a leírást nem 1 nap alatt készítettem el, kb. 1 hónapja írtam meg az elméleti oldalát, most az elmúlt pár napban pedig a gyakorlatot. Esténként 1-2 órát szántam rá csupán, és mivel ilyenkor már nem vagyok épp a toppon, elképzelhetõ, hogy néhány helyen helyesírási, vagy elvi hibát vétettem. Amennyiben valaki ilyet találna, kérem szóljon, és korrigálni fogom. Nos, azt hiszem nincs is más hátra, mint hogy sok szerencsét kívánjak a bitmûveletek elsajátításához, és megosszam a forrásokat. Remélem néhányan hasznosnak találják, eme igen hosszúra sikerült leírást.





4. Források:
 

Internet:





Könyv, e-book:




  • Pohl László - A programozás alapjai(BME - Elektronikus Eszközök Tanszéke, Budapest, 2010)

  • Siroki László - C programozás - Bitmûveletek jegyzete





ˆ Anthony, 2012 - Minden jog fenntartva.

A leírás egészben, vagy részleteiben szabadon terjeszthetõ, ameddig egyértelmûen fel van tüntetve az eredeti készítõ, valamint hogy honnan is származik.

45
Bemutatkozás / Anthony - Frissítve!
« Dátum: 2012. Január 27. - 14:04:25 »
Üdv mindenkinek, gondoltam én is megírom (újra) a bemutatkozásom.
Néhány IRL infó: \'92-ben születtem, lassan 20 éves leszek, jelenleg a Szegedi Tudomány Egyetem (SZTE) Természettudományi és Informatikai Karán (TTIK) tanulok, Biológia BSc II. éves hallgatóként. Szentesen születtem, de a suli miatt kolis vagyok, így hétköznapjaimat (és barátnõm miatt mostanában gyakran hétvégéimet is) Szegeden töltöm, az oly rossz hírû, ám de nagyon jó hangulatú Károlyi Mihály kollégium 8. emeletén.
Érdeklõdési köröm: nehéz behatárolni. IT-vel kapcsolatosan sok minden, pl. jó pár éve rendszeres olvasó vagyok Ipon-on, szeretek programozni, weboldalt készíteni. Scriptelni már nem szoktam. Imádok vezetni, ámbár édesapám oktató, így néha-néha besegítek neki, no persze csak rutinpályára megyek tanulókkal, forgalomba nem. Ezen kívül ez-az, apróságok, filmek, sorozatok. Játszani egyre kevesebbet játszom, bár a felosztáson még lenne mit javítanom. Olykor ha leülök egy jó játék akár 4-5-6 órára képes magával ragadni (pl. L.A. Noire, Saint\'s Row The Third). De általánosan heti szinten ha leosztom, olyan napi 1-2 óra körül jön ki.
Autókterén: Jelenleg egy \"neptunzöld\"(ez van a forgalmin...), 2003-as, 1.6-os, benzines, 5 ajtós Ford Focusunk van (I. generáció ráncfelvarrott verziója, utolsó darabok közül), ezzel megyek erre-arra. Bár a jelenlegi benzinárak mellett egyre kevesebbet tudom használni... És mivel oktatóautó, igen, mindkét oldalon van pedál :P (anyósülésen ülve beállni a garázsba, felbecsülhetetlen :D). Ide még annyit, hogy odavagyok a Ford-okért, sosem vennék más autót, mióta emlékszem, nem is volt más márkájú autónk.. :)
Zeneileg stílusom egyre változó, hangulatfüggõ. Van hogy Three Days Grace, van hogy Linkin Park, de újabban bármi jöhet, kiváltképp egy kis alkohollal kísérve :) Itt megemlíteném még kedvenc Dj-met, DJ Lennardot, aki a Szegedi \"Tesis buli\"-k atyja is. Ezek 2 hetente vannak, és a legnépszerûbb bulik (Guinness rekord is volt belõle) :)
SAMP:
Magával a játékkal valamikor a 0.1b-s verziónál találkoztam elõször, egy ismerõsömnél. Akkor még nem igazán tetszett, felraktam otthon is, de gyors meg is untam. Késõbb, a 0.2-es verzió megjelenése után nem sokkal újra felraktam, ekkor kicsit tovább maradtam, de pár hónap után meguntam. A 0.2 R2-es verzió ideje alatt kezdtem el scriptelni, az R3-as verzió megjelenését örömmel fogadtam. Azóta nagyjából végig követtem az eseményeket, az elmúlt nem tom hány évben.
Script:
Mint írtam a 0.2 R2-es verzióval kezdtem, eleinte semmi hasznosat nem csináltam, összedobtam egy alap szervert, ami annyiból állt, hogy az LVDM-bõl SFDM-et csináltam. Nem volt sikeres szeró, gyors meg is szûnt. Volt még pár kisebb-mégkisebb projektem, de egyik sem volt túl népszerû.
Aztán egyszer rátaláltam Brad-re, õ meg Gergo1352-re, és megalapítottuk a WRP-t, amit az elmúlt 3-4 évben csinálgattam, legtöbbször vezettem is. Errõl nem is mondok többet, úgyse érdekel senkit :D
Fórum:
Már nem is tudom mikor találtam rá a fórumra. Az elõdjén, a forum-samp.extra.hu(talán ez volt a neve)-n eltöltöttem 1-2 hetet, majd szóltak, hogy új fórum indult samp-forum.extra.hu(javítsatok ki ha tévednék) néven. Még az elején regisztráltam(2008. Augusztus 20. 09:13:59), sok dolgot innen tanultam scriptelni. Dolgoztam egy idõben Kowalski-val, segítettem kicsit Eps-nek, mikor még tanult... :D Azóta messze lekörözött, elég rég volt már.
Mikor a web atw-re költözött, egy jó 1-1,5 évig nem írtam semmi HSZ-t, mert elfelejtettem a jelszavamat, és sehogy se kaptam meg a jelszó emlékeztetõt. Olvasgatni továbbra is olvastam a fórumot, de írni nem tudtam, új accot meg nem akartam regelni. Aztán azt hiszem épp valami balhé volt, amihez hozzá akartam szólni, így kértem még 1x jelszó emlékeztetõt, és végre megkaptam :D Nagyon örültem neki, azóta nagyjából állandó jelleggel nézegetem a fórumon. Nem lógok itt állandóan, de azért mindig elolvasgatom az aktuális dolgokat, na meg a számomra fontos részlegeket...(fõleg a Szerverek részleget, azon belül is fõként az RP-vel kapcsolatos dolgokat)
Fontos szerepem sokáig nem volt a fórumon, egyszer Eps írt engem, valami nem tom milyen ranghoz, de rajta kívül senki sem szavazott rám, szóval azt sem kaptam meg :D. Nemrég (újra...) elértem az 1000 HSZ-t, sajnálattal látom, hogy jó néhány régi HSZ-em és témám eltûnt(többek között a bemutatkozásom, néhány tutorialom, pár segítség kérésem, stb...) :( Késõbb aztán kaptam néhány rangot.. Néhány dátum:
2012. február 5. - Megkaptam a V.I.P. rangot.
2012. június 28. - Lemondtam a V.I.P. rangomról, mert vizsgaidõszakom volt, és úgy terveztem befejezem a SA:MP-ot, ezzel párhuzamosan...
2012. június 28. - Megkaptam a Legend rangot.
2012. augusztus 6. -  Lokális moderátor lettem a Szerverek fórumrészben.
2012. szeptember 23. - Globális moderátor lettem.
Azóta mint glob. mod tevékenykedem, próbálom minél jobban végezni a munkám, illetve Ystee(Csabesz) adott nekem egy \"Fórum fejlesztõ\" egyéni titulust még régebben, mert néha segítek neki ezt-azt a fórum fejlesztésében (az egyik projekten most egyedül én dolgozom, remélhetõleg hamarosan el is készül).
Egyéb
A Pawn mellett belekóstoltam más programozási nyelvekbe, egy idõben IV-MP szervert csinálgattam, volt egy fórumom is.
Kisebb-nagyobb tapasztalattal rendelkezem C, C++, C#, Perl, Python, VB nyelvekben, de kb. 1-2 éve már egyiket sem vettem elõ.
Jelen
Mostanában fõként \"webprogramozással\"(nevetséges, hogy programozásnak hívják, pedig egyáltalán nem az, összehasonlítva más programozási nyelvekkel...) foglalkozom, 4 éve PHP-zek, MySQL-bõl sem csak a \"SAMP-os\" alapokat ismerem, az ismeretségünk  3-3,5 évre nyúlik vissza. Kb. 1 éve már webdesign-al is foglalkozom, így ha komplett listát akarok, akkor a következõ dolgokat ismerem, web-hez kapcsolódóan:
 
  • PHP (4-esen kezdtem, de felzárkóztam az elmúlt idõben az 5-ös verzióhoz is)

  • HTML, XHTML

  • CSS (fõként a 2-es és 3-as verzió, valamint a böngészõspecifikus dolgok, illetve a kevésbé ismert újdonságok)

  • JavaScript

  • MySQL


Jelenleg fõleg a javascriptbe vagyok belebolondulva, no meg az apache Mod_rewrite-jába :D Odavagyok a jQuery-ért és az Ajax-ért, de a sima javascriptet is szeretem, mostanában fõleg ezekkel foglalkozom. Nemrég béreltem egy VPS-t, mostanában már ezen gyakorlom, és emellett elkezdtem a linux-ot is behatóbban tanulni, már be is vásároltam könyvekbõl, ha vége a vizsgaidõszaknak, akkor azok fognak következni.
Rövidebb idõt töltöttem néhány kevésbé ismert, és azóta megszûnt hostnál, konfigosként. Hosszabb ideig dolgoztam a Clans.hu-nál, még mostanában is jó viszonyban vagyok Raid-al, a tulajdonossal.
A jövõben webdesignnal és webtervezéssel szeretnék foglalkozni, munkaként, ám sajnos ehhez nincs meg jelenleg a \"cég\" a hátam mögött, aki munkát adna nekem, hisz egyetem mellett teljes munkaidõs állást nem vállalhatok. Hobbiból egy saját CMS rendszeren dolgoztam sokáig, azonban ezt a projektet néhány hónapja befejeztem. Az elmúlt 4 évben rengeteg dolgot tanultam az által, hogy ezt csinálgattam, hisz rengeteg problémába ütköztem, amelyet meg kellett oldanom. Ezen kívül írtam már 1-2 apró kiegészítést SMF-hez is, ezeket a WRP-n használtam is, de publikálva valószínûleg ezek sem lesznek soha. Tervezek valamilyen módon a VPS-el is pénzt keresni, no persze nem milliárdokat, csupán annyi a tervem, hogy azt a pár ezer forintot visszahozza amennyibe kerül havonta (jelenleg csak VPN és webszerverként használom, ezekre van szükségem mostanság).
Rövidebb ideje dolgozom a Telekomnál, a Szegedi Call Centerben, mint Mûszaki Call Centeres (MCC), köznapi nyelven hibabejelentõ, régebbi nevén Mûszaki HelpDesk (elõfordulhat, hogy a 1412-es számon már beszéltem is innen valakivel :D).
Steam:
Régebben gyûlöltem a steamet, de nemrég újra regeltem, és egy ideje aktívan elkezdtem használni is. Aki akar felvehet: anthony199206
Játékaim:
Company of Heroes
Company of Heroes: Opposing Fronts
Company of Heroes: Tales of Valor
Darksiders
L.A. Noire
Metro 2033
Portal
Portal 2
Red Faction: Armageddon ( + Path to War DLC)
Saints Row: The Third ( + Genkibowl VII, Gangstas Is Space, Nyte Blayde Pack, The Trouble With Clones DLC-k)
Team Fortress 2 (csak néhányszor játszottam még vele)
Titan Quest
Warhammer 40,000: Dawn of War - Game of the Year Edition
Igen, én is megvettem a THQ Humbly Bundle packot, de én a nagyobbat, no meg a Steam Holiday Sale 2012-n is bevásároltam :) Statisztikáim nem írom le, aki kíváncsi megnézheti a profilomon :) Amit viszont leírnék, hogy keresek Saint\'s Row The Third-hez Co-op partnert! Mivel javarészt már csak azok az Achievementek hiányoznak, és hát én nagy függõ vagyok ilyen téren... Achievementekkel meg lehet engem venni, addig nem törlöm le a játékot, ameddig mindet nem teljesítettem :)
Végére még néhány dolog:
PM-ben bárkivel szívesen beszélgetek, ha segíteni tudok (és nem scriptelésrõl van szó), akkor nyugodtan kereshettek, próbálok mihamarabb válaszolni. Steam-en megtaláltok, nyugodtan bejelölhettek, ha van kedvetek játszani valamit esetleg Co-op-ba, vagy \"csak úgy\". FB-n hiába jelöltök be, kevés ember van akinek visszajelölök, inkább csak a valódi ismerõsökkel tartom ott a kapcsolatot.
Még utoljára az \"unalmas\" kikkel vagyok igazán jóba a fórumról, ergó akiket birok, akikkel egyetértek, egy véleményen vagyok és/vagy szoktam velük beszélgetni:
Chucknorris, Csabesz, Epsilon, Gentleman, krisk, <[£u$ta]>, Pöpec, rayhassi, ScreaM, ɐʞzssǝlosz, stb... A sorrend ABC sorrend, szal nem számít :)
Kicsit hosszú lett, köszönöm annak aki elolvassa =)
 
Üdv: Anthony

Oldalak: 1 2 [3] 4
SimplePortal 2.3.7 © 2008-2024, SimplePortal