Szerző Téma: Szerver monitorozó - "dOnitor"  (Megtekintve 1794 alkalommal)

Nem elérhető Dfoglalo

  • 4069
  • Globális Moderátor
    • Profil megtekintése
Szerver monitorozó - "dOnitor"
« Dátum: 2014. November 20. - 23:09:24 »
+3 Show voters

Szerver monitorozó

\"dOnitor\" by Dfoglalo
 

Kedves Fórumozók,
Nem sok munkát publikálok, mert nem is nagyon szoktam publikálásra szánt anyagokat írni: Ez alkalommal kedvet kaptam ahhoz, hogy írjak egy kis alap, példa kódot egy igen hasznos dologgal kapcsolatban: ez pedig a SAMP szever monitorozása. Ennek alapjául a SAMP Wiki egy oldala szolgált, amelynek tartalma a gyakorlatlan szemnek elsőre egy bonyolult dolognak tűnhet, pedig valójában roppant egyszerű. Éppen ezért is írtam meg ezt a kis 100 soros kódot; hogy aki ki szeretné ezt a lehetőséget használni, de nem nagyon sikerül megérteni, az talán egy példán és némi magyarázaton keresztül megérti majd. Ezeken kívül természetesen található a neten rengeteg forráskód még ezzel kapcsolatban, amelyek sokszor komoly rendszerek, amely biztosítanak függvényeket a lekérdezések és műveletek egyszerű elvégzéséhez. Illetve találni kész, nagy terjedelmű, dizájnolt kódokat is. Azonban úgy gondolom, hogy hasznosabb az, ha az ember érti is a forráskódot és nem csak letölt egyet, illetve ha teljesen sajátot ír, a saját kódolási szokásaival, a saját szándékának megfelelően. Ez a példa pedig talán remek alapjául szolgálhat a dolog megértésének és egy egyedi kódba kezdésnek.
De talán szokásomhoz híven kicsit sokat szövegeltem, így ideje egy képen bemutatni az eredményt:
 

[hs width=222]
http://kephost.com/images/2014/11/20/example.png[/hs]
1. ábra - A képen egy, a SAMP kliens szerverlistázójából véletlenszerűn kiválasztott szerver adatai láthatók
 

Semmi túlzott dizájn, csak egy kevéske HTML az olvashatóság értekében. Ti majd magatoknak a saját kódotokat úgy dizájnoljátok, ahogyan csak akarjátok. De most jön a lényeg, a kód:
 
<?php
/*
Készítette: Dfoglalo
Felhasználási feltételek: ne állítsa be úgy a kódot, mintha önmaga készítette volna.
Kelt: 2014.11.20.
*/
$ip = \"127.0.0.1\"; // A szerver IP címe
$port = \"7777\"; // A szerver portja
$socket = fsockopen(\'udp://\'. $ip, $port, $errorn, $errori); // Socket készítése
if($socket) // Ha a megnyitás sikeres
{
$packet = \'SAMP\'; // A SAMP packet kiválasztása
// Az IP címet és a portot hozzáadogatjuk a változóhoz
$packet .= chr($ip[0]);
$packet .= chr($ip[1]);
$packet .= chr($ip[2]);
$packet .= chr($ip[3]);
$packet .= chr($port & 0xFF);
$packet .= chr($port >> 8 & 0xFF);
fwrite($socket, $packet.\'i\'); // Elküldjük a packetet, benne a SAMP azonosítóval, az IP-vel és a porttal, valamint az i opcodeddal
fread($socket, 11); // A 11. bájttól kezdjük a beolvasást, mert ott találjuk az első kiírandó adatot
/* A 11. bittől kezdve kérdezhetjük le, hogy jelszóval van e védve a szerver.
Ennek a hossza 1 bit, tehát ekkora a hosszan is kérjük le az adatokat.
A visszakapott értéket ellenőrizzük és ha igaz, a szerver jelszóval van védve.
Ellenkező esetben természetesen a szerver nincs jelszóval védve. */
$password = ord(fread($socket, 1));
if($password) echo \'<b>A szerver <font color=\"red\">jelszóval van védve.</font></b><br>\';
else echo \'<b>A szerver <font color=\"green\">nincs jelszóval védve.</font></b><br><br>\';
/* A követkőzkben kiírjuk, hogy a szerveren hány játékos tartózkodik jelenleg hány slotból.
Mivel előtte lekérdeztünk egy bitet, így automatikusan továbbléptünk a következőhöz.
Ezáltal le tudjuk kérdezni akár a következő 2 bitet is, amely a játékosok számát adja vissza.
Ha ezzel is készen vagyunk, lekérdezhetjük a következő kettőt, amely a szerver slotok számát adja vissza. */
echo \'<b>Játékosok száma:</b> \' . ord(fread($socket, 2)) . \'/\' . ord(fread($socket, 2)) . \'<br>\';
/* A következő 4 biten lekérdezhetjük, hogy milyen hosszú a hostname.
Ezen lekérdezést eredményét deklaráljuk egy $strlen nevű változóba.
Utána jön maga a hostname. Hogy ezt le tudjuk kérdezni, meg kell tudnunk, hogy hány
bitnyi adatok kell most lekérdeznünk. Ezt mi már megtudtuk az előző lépés segítségével.
Így tehát egy kézzel beírt szám helyett a deklarált $strlen változót adjuk meg. */
$strlen = ord(fread($socket, 4));
echo \'<b>Hostname:</b> \' . fread($socket, $strlen) . \'<br>\';
/* Ugyanezen módszerrel lekérdezhetjük a gamemode nevét és a
mapnamet is, ugyanis ők következnek a sorban, a visszakapott bitek sorában. */
$strlen = ord(fread($socket, 4));
echo \'<b>Gamemode:</b> \' . fread($socket, $strlen) . \'<br>\';
$strlen = ord(fread($socket, 4));
echo \'<b>Mapname:</b> \' . fread($socket, $strlen) . \'<br><br>\';
/* Idáig tartottak az alap adatok, amelyeket az ember általában ki szokott íratni.
Azonban felhozok még 1-2 példát, ha nem porlbéma. Például azt, hogy hogyan kell
lekérdezi az egyes játékosok elérhető adatait. Íme.*/
fwrite($socket, $packet.\'c\'); // Már az c opcodeddal küldjük el a packetet
fread($socket, 11); // Szintén a 11. bájttól kezdjük a beolvasást
$players = ord(fread($socket, 2)); // Deklaráljuk a players változót, amely értéke egyenlő lesz az online játékosok számával
/* 0 játékos esetén ez a rész nem fog lefutni. Ha csak a ciklus létezne, nem
lenne rá feltétlenül szükség, mert a ciklusmag egyszer sem futna le, 0 játékos
esetén sem. Bár a ciklus megpróbálna lefutni, feleslegesen, amelyet jobb megakadályozni.
De jelen esetben főleg azért van rá szükség, hogy ne hozzunk létre feleslegesen egy
táblázatot, ha 0 játékos tartózkodik fent a kiválasztott szerveren. */
if($players > 0)
{
/* Táblázat megkezdése 5 pixeles margóval, a játékos lista megformázása érdekében */
echo \'<table celspacing=\"5\">
   <tr>
      <td><b>Név</b></td>
      <td><b>Pont</b></td>
   </tr>\';
for($i = 0; $i < $players; ++$i)
{
   /* A kényelmesebb kommentezés érdekében deklaráltam néhány plusz helyi
   változót, például a $score változóra nincs jelenleg szükség, ugyanis
   kiírhattam volna rögtön a képernyőre az fread függvény által visszaadott adatokat. */
   $strlen = ord(fread($socket, 1)); // Lekérdezzük a soron következő játékos nevének a hosszát
   $player = fread($socket, $strlen); // Lekérdezzük a soron következő játékos nevét annak előzőleg lekérdezett hossza alapján
   $score = ord(fread($socket, 4)); // Lekérdezzük a soron következő játékos pontjainak számát, a következő 4 bitről
   /* Kiíratjuk a játékos nevét és a pontját. */
   echo \'<tr><td>\' . $player .\'</td><td>\' . $score .\'</td></tr>\';
   /* Ha még van(nak) hátra játékos(ok), akkor a ciklis nem kép ki és a ciklusmag újra lefut.
   Azonban ekkor már túlléptünk néhány bitet, nevezetesen a soron következett játékos
   nevének a hosszát, a nevét és a pontját tartalmazó biteket. Így legközelebb már az ezen
   bitok után következő bitek fognak következni, amely már egy új játékos adati lesznek. */
}
echo \'</table>\'; // A táblázat lezárása
}
}
else echo \"A szerver nem elérhető.\";
fclose($socket); // Lezárjuk a kapcsolatot
?>

 
Nem a legprofibb kód, de megteszi. Egyébként egyedül azért nevezem ezt egy PHP szkriptnek, nem pedig egy tutorialnak, mert a szkript önmagában is felhasználható - és így is szeretném kiadni, mint felhasználható szkript, ha már megírtam - például arra, hogy valaki a szervere weboldalán kilistázza az éppen online játékosokat. Na meg a tutorial kicsit máshogy is nézne ki; alapból a fórum témában írnám meg, nem pedig kommentezve a kódban.
 

Letöltés - Pastebin
 
 
Remélem, hogy azért valakinek majd a hasznára válik.
Utóirat: lehet, hogy ezt a dOnitor megnevezést nem kéne erőltetnem, de már mindegy. :D
 

Üdvözlettel,

Dfoglalo

Szerver monitorozó - "dOnitor"
« Válasz #1 Dátum: 2014. November 20. - 23:19:50 »
0 Show voters
Valahol mintha láttam volna már az alsó részét.

Nem elérhető Dfoglalo

  • 4069
  • Globális Moderátor
    • Profil megtekintése
Szerver monitorozó - "dOnitor"
« Válasz #2 Dátum: 2014. November 20. - 23:24:31 »
0 Show voters
Ez az egyik legegyszerűbb megoldás. Nem fogom átírni máshogy (már ha egyáltalán át lehet - nem hiszem, mert freaddel lehet beolvasni, meg kell adni a megnyitott socketet és a biteket és pont) csak azért, mert más már megoldotta esetleg így. Bár lehetne például így is:
 
echo \'<tr><td>\' . fread($socket, $strlen) .\'</td><td>\' . ord(fread($socket, 4)) . \'</td></tr>\';

 
Csak kommentezni szerettem volna.

Szerver monitorozó - "dOnitor"
« Válasz #3 Dátum: 2014. November 20. - 23:38:20 »
0 Show voters
Szép! :D

Szerver monitorozó - "dOnitor"
« Válasz #4 Dátum: 2014. November 21. - 00:53:35 »
0 Show voters
Elég szép munka

Nem elérhető tonyo

  • 1335
  • Moderális Generátor
    • Profil megtekintése
Szerver monitorozó - "dOnitor"
« Válasz #5 Dátum: 2014. December 26. - 23:49:42 »
0 Show voters
Szerintem az elején kimaradt egy explode:
 
$ip = \"127.0.0.1\"; // A szerver IP címe

 
Majd kicsivel utána:
 
$packet .= chr($ip[0]);
$packet .= chr($ip[1]);
$packet .= chr($ip[2]);
$packet .= chr($ip[3]);

 
Kettő közt kellene:
 
explode(\'.\', $ip);

Szerver monitorozó - "dOnitor"
« Válasz #6 Dátum: 2014. December 27. - 00:17:31 »
0 Show voters
Most néztem csak át rendesen a kódot, szépen megfogalmaztad, hogy hol mit csinálsz épp.
..
Most hülyeséget akartam kérdezni, de írás közben rájöttem :D
Az opcodeokról viszont írhattál volna többet is, hogy egyáltalán mi az, vagy hogy melyik mit csinál

Nem elérhető tonyo

  • 1335
  • Moderális Generátor
    • Profil megtekintése
Szerver monitorozó - "dOnitor"
« Válasz #7 Dátum: 2014. December 27. - 01:26:53 »
0 Show voters
Idézetet írta: blackdog476 date=1419635851\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"51436\" data-ipsquote-contentclass=\"forums_Topic
Az opcodeokról viszont írhattál volna többet is, hogy egyáltalán mi az, vagy hogy melyik mit csinál
Van hozzá dokumentáció.

Szerver monitorozó - "dOnitor"
« Válasz #8 Dátum: 2014. December 27. - 14:41:35 »
+1 Show voters

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal