Skip to content

Instantly share code, notes, and snippets.

@PEMapModder
Created June 15, 2015 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PEMapModder/f9384f18e5d81de41443 to your computer and use it in GitHub Desktop.
Save PEMapModder/f9384f18e5d81de41443 to your computer and use it in GitHub Desktop.
Legion PE status generator, hosted at http://lgpe.co/status/
<?php
$begin = microtime(true);
const NORM = "/var/www/html/sgn/norm.ttf";
const BOLD = "/var/www/html/sgn/bold.ttf";
const X_INTERVAL = 6;
const LEFT_PADDING = 80;
const RIGHT_PADDING_24 = 325;
const RIGHT_PADDING_SLOTS = 350;
const TOP_PADDING = 100;
const BOTTOM_PADDING_24 = 80;
const BOTTOM_PADDING_SLOTS = 20;
const GRAPH_HEIGHT = 300;
const RADIUS = 200;
define("DIAMETER", RADIUS * 2);
require_once "/var/www/html/bnr/utils.php"; // fetch root
function writeTextCenter($img, $txt, $x0, $y0, $color, $size = 12.0, $bold = false, $angle = 0.0){
list($xleft, $ylow, $xright, , , $yhigh) = imagettfbbox($size, $angle, $bold ? BOLD : NORM, $txt);
imagettftext($img, $size, $angle, $x0 - ($xright - $xleft) / 2, $y0 - ($yhigh - $ylow) / 2, $color, $bold ? BOLD : NORM, $txt);
}
// prepare current-slots banner
$r = $db->query("SELECT unix_timestamp()-unix_timestamp(last_up) as diff, cnt, kitpvp, parkour, spleef, infected FROM active_servers WHERE sid=9");
$row = $r->fetch_assoc();
$r->close();
$img = imagecreate($width = LEFT_PADDING + RADIUS * 2 + RIGHT_PADDING_SLOTS, $height = TOP_PADDING + RADIUS * 2 + BOTTOM_PADDING_SLOTS);
$gray = imagecolorallocate($img, 128, 128, 128);
$white = imagecolorallocate($img, 0, 0, 0);
$black = imagecolorallocate($img, 255, 255, 255);
$red = imagecolorallocate($img, 255, 64, 0);
$green = imagecolorallocate($img, 64, 255, 0);
$blue = imagecolorallocate($img, 0, 64, 255);
imagefill($img, 0, 0, $gray);
imagearc($img, $centerx = LEFT_PADDING + RADIUS, $centery = TOP_PADDING + RADIUS, DIAMETER, DIAMETER, 0, 360, $black);
imagesetpixel($img, LEFT_PADDING + RADIUS, TOP_PADDING + RADIUS, $black);
UT3QueryServer("pe.legionpvp.eu", 19132, $result);
$max = $result["maxplayers"];
$unused = 360 - $row["cnt"] / $max * 360;
$kitpvp = $row["kitpvp"] / $max * 360;
$parkour = $row["parkour"] / $max * 360;
$spleef = $row["spleef"] / $max * 360;
$infected = $row["infected"] / $max * 360;
$degree = 0;
imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $maxArc = 360 - $unused, 360, $black, IMG_ARC_PIE);
imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $degree, $degree += $kitpvp, $red, IMG_ARC_PIE);
imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $degree, $degree += $parkour, $green, IMG_ARC_PIE);
imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $degree, $degree += $spleef, $blue, IMG_ARC_PIE);
//imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $degree, $degree += $infected, $blue, IMG_ARC_PIE);
imagefilledarc($img, $centerx, $centery, DIAMETER, DIAMETER, $degree, $maxArc, $white, IMG_ARC_PIE);
$slotsStr = "";
writeTextCenter($img, " Current distribution ", $width / 2, TOP_PADDING / 2 - 15, $black, 24, true);
writeTextCenter($img, "of server slots (total: $max)", $width / 2, TOP_PADDING / 2 + 15, $black, 24, true);
$x = LEFT_PADDING + DIAMETER + 10;
$y = TOP_PADDING + RADIUS - 50;
$cnt = $row["cnt"];
$kitpvp = $row["kitpvp"];
$parkour = $row["parkour"];
$spleef = $row["spleef"];
$unused = $max - $cnt;
$cnt -= $kitpvp + $parkour + $spleef;
imagettftext($img, 18.0, 0.0, $x, $y, $red, BOLD, "KitPvP ($kitpvp, " . round($kitpvp / $max * 100) . "%)");
$y += 25;
imagettftext($img, 18.0, 0.0, $x, $y, $green, BOLD, "Parkour ($parkour, " . round($parkour / $max * 100) . "%)");
$y += 25;
imagettftext($img, 18.0, 0.0, $x, $y, $blue, BOLD, "Spleef ($spleef, " . round($spleef / $max * 100) . "%)");
$y += 25;
imagettftext($img, 18.0, 0.0, $x, $y, $black, BOLD, "Unused slots ($unused, " . round($unused / $max * 100) . "%)");
$y += 25;
imagettftext($img, 18.0, 0.0, $x, $y, $white, BOLD, "Unauthenticated/\nHub ($cnt, " . round($cnt / $max * 100) . "%)");
ob_start(function($buffer){
global $slotsStr;
$slotsStr .= $buffer;
return "";
});
imagepng($img, null, 9);
ob_end_flush();
// prepare 24-hour banner
$r = $db->query("SELECT cnt, connects, joins, unix_timestamp() - unix_timestamp(at) AS diff FROM players_cnt WHERE unix_timestamp() - unix_timestamp(at) <= 86400 LIMIT 144"); # 864
$status = [];
while(is_array($row=$r->fetch_assoc())){
$status[] = $row;
}
$r->close();
while(count($status) < 144){
array_unshift($status, ["cnt" => 0, "connects" => 0, "joins" => 0, "diff" => INF]);
}
$maxCnt = 0;
$maxConns = 0;
$maxJoins = 0;
foreach($status as $row){
$maxCnt = max($maxCnt, $row["cnt"]);
$maxConns = max($maxConns, $row["connects"]);
$maxJoins = max($maxJoins, $row["joins"]);
}
$maxConns = $maxJoins = max($maxConns, $maxJoins);
$img = imagecreate($width = count($status) * X_INTERVAL + LEFT_PADDING + RIGHT_PADDING_24, $height = TOP_PADDING + GRAPH_HEIGHT + BOTTOM_PADDING_24);
$statusXdY = $width / $height;
$x0 = LEFT_PADDING;
$x1 = $width - RIGHT_PADDING_24;
$y0 = TOP_PADDING;
$y1 = TOP_PADDING + GRAPH_HEIGHT;
$black = imagecolorallocate($img, 255, 255, 255);
$white = imagecolorallocate($img, 0, 0, 0);
$red = imagecolorallocate($img, 255, 0, 0);
$blue = imagecolorallocate($img, 0, 255, 0);
$green = imagecolorallocate($img, 0, 0, 255);
$greenblue = imagecolorallocate($img, 0, 255, 255);
imagefill($img, 0, 0, $white);
writeTextCenter($img, "Online players in past 24 hours", $width / 2, $y0 / 2 - 10, $black, 42.0, true);
imageline($img, $x0, $y0, $x0, $y1, $black);
imageline($img, $x0, $y1, $x1, $y1, $black);
$x = $x0 - X_INTERVAL / 2;
$ya = $y1;
$yb = $y1;
$yc = $y1;
$i = 0;
foreach($status as $row){
$ox = $x;
$y = $y0;
imageline($img, $ox, $ya, $x += X_INTERVAL, $ya = $y + ($maxCnt - $row["cnt"]) / $maxCnt * ($y1 - $y), $red);
$y += 20;
imageline($img, $ox, $yb, $x, $yb = $y + ($maxConns - $row["connects"]) / $maxConns * ($y1 - $y), $green);
// $y += 40;
imageline($img, $ox, $yc, $x, $yc = $y + ($maxJoins - $row["joins"]) / $maxJoins * ($y1 - $y), $blue);
if(($i & 0x0F) === 0){
writeTextCenter($img, round($row["diff"] / 3600, 1), $x, $y1 + 10, $black, 12.0, false, 30.0);
}
$i++;
}
$x = $x0 - 60;
$y = $y0;
writeTextCenter($img, $maxCnt , $x, $y , $red, 12.0, true);
writeTextCenter($img, $maxCnt / 4, $x, $y + ($y1 - $y)*3/4, $red, 12.0, true);
writeTextCenter($img, $maxCnt / 2, $x, $y + ($y1 - $y) / 2, $red, 12.0, true);
writeTextCenter($img, $maxCnt *3/4, $x, $y + ($y1 - $y) / 4, $red, 12.0, true);
$x += 30;
$y += 20;
writeTextCenter($img, $maxConns , $x, $y , $greenblue, 12.0, true);
writeTextCenter($img, $maxConns / 4, $x, $y + ($y1 - $y)*3/4, $greenblue, 12.0, true);
writeTextCenter($img, $maxConns / 2, $x, $y + ($y1 - $y) / 2, $greenblue, 12.0, true);
writeTextCenter($img, $maxConns*3/4, $x, $y + ($y1 - $y) / 4, $greenblue, 12.0, true);
//$x += 30;
//$y += 20;
//writeTextCenter($img, $maxJoins , $x, $y , $blue, 12.0, true);
//writeTextCenter($img, $maxJoins / 4, $x, $y + ($y1 - $y)*3/4, $blue, 12.0, true);
//writeTextCenter($img, $maxJoins / 2, $x, $y + ($y1 - $y) / 2, $blue, 12.0, true);
//writeTextCenter($img, $maxJoins*3/4, $x, $y + ($y1 - $y) / 4, $blue, 12.0, true);
imagettftext($img, 18.0, 0.0, $x1, ($y1 - $y0) / 2 + $y0 - 25, $red, BOLD, "Number of players online");
imagettftext($img, 18.0, 0.0, $x1, ($y1 - $y0) / 2 + $y0, $green, BOLD, "Number of connect attempts");
imagettftext($img, 18.0, 0.0, $x1, ($y1 - $y0) / 2 + $y0 + 25, $blue, BOLD, "Number of new joins");
writeTextCenter($img, "hours ago", ($x1 - $x0) / 2 + $x0, $y1 + 35, $black, 18.0, true);
$h24Str = "";
ob_start(function($buffer){
global $h24Str;
$h24Str .= $buffer;
return "";
});
imagepng($img, null, 9);
ob_end_flush();
?>
<html>
<head>
<title>Status | Legion PE</title>
<style>
body{
font-family: Helvetica, sans-serif;
}
h1{
font-weight: bolder;
}
</style>
</head>
<body>
<h1>LegionPE Status</h1>
<hr>
<?php $height = 380; ?>
<img src="data:image/png;base64,<?= base64_encode($h24Str) ?>" width="<?= $height * $statusXdY ?>" height="<?= $height ?>">
<hr>
<?php $height = 500; ?>
<img src="data:image/png;base64,<?= base64_encode($slotsStr) ?>">
<hr>
<footer>Page generated in <?= microtime(true) - $begin ?> second(s).</footer>
</body>
</html>
@PEMapModder
Copy link
Author

Global variable $db and function UT3QueryServer are defined on line 15. The script is something like this:

$db = new mysqli(__DBHOST__, __DBUSER__, __DBHPASS__, __DBDATABASE__);
// Query code for PocketMine Banners from @99leonchang
const SERVER_OK = 0;
const SERVER_DOWN = 1;
const TIMEOUT = 1;
const SERVER_INVALID = 2;
const UNKNOWN_ERROR = 3;
function UT3QueryServer($host,$port,&$return){
    /** @noinspection PhpUsageOfSilenceOperatorInspection */
    $sock = @fsockopen("udp://" . $host, $port);
    if(!$sock){
        return SERVER_INVALID;
    }
    socket_set_timeout($sock, 0, 500000);
    /** @noinspection PhpUsageOfSilenceOperatorInspection */
    if(!@fwrite($sock, "\xFE\xFD\x09\x10\x20\x30\x40\xFF\xFF\xFF\x01")){
        return SERVER_DOWN;
    }
    $challenge = fread( $sock, 1400 );
    if(!$challenge){
        return UNKNOWN_ERROR;
    }
    $challenge = substr(preg_replace("/[^0-9\-]/si", "", $challenge), 1);
    $query = sprintf(
        "\xFE\xFD\x00\x10\x20\x30\x40%c%c%c%c\xFF\xFF\xFF\x01",
        ($challenge >> 24),
        ($challenge >> 16),
        ($challenge >> 8),
        ($challenge >> 0)
    );
    /** @noinspection PhpUsageOfSilenceOperatorInspection */
    if(!@fwrite($sock, $query)){
        return UNKNOWN_ERROR;
    }
    $response = [];
    for($x = 0; $x < 2; $x++){
        /** @noinspection PhpUsageOfSilenceOperatorInspection */
        $response[] = @fread($sock,2048);
    }
    $response = implode($response);
    $response = substr($response,16);
    $response = explode("\0",$response);
    array_pop($response);
    array_pop($response);
    array_pop($response);
    array_pop($response);
    $return = [];
    $type = false;
    $val = "";
    foreach($response as $key){
        if($type){
            $return[$val] = $key;
        }else{
            $val = $key;
        }
        $type = !$type;
    }
    return SERVER_OK;
}

@PEMapModder
Copy link
Author

For the server part, I won't share the counter plugin since it contains some credentials and I'm too lazy to remove them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment