PDA

View Full Version : How to make live stats images for your scripts



xtrapsp
01-01-2013, 10:55 PM
Original thread:

http://villavu.com/forum/showthread.php?t=83538

Recently a few members of Villavu have been trying to re-create signature which update to their server. Some have been having issues.

Myself, Kyle and [J]ustin have done this to test it and found a few twists and turns in the tutorials which can throw people off, so this is hopefully a full fix for that tutorial.

What will you learn?
You will be learning a little PHP (Enough to progress you into further projects I think). Pascal and some logical thinking :)


What will I need?


A Webhost with MYSQL Databasing
An Image


Ok, so first things first we need to create a website, Putonajonny suggested:
http://www.000webhost.com/images/head.jpg (http://www.000webhost.com/order.php)

Steps from here:


Sign up using the registration, You don't want to pay so use a subdomain
Confirm your email
Go to the control panel of your selected sub domain, scroll or press CTRL + F to find Software / Services and click on the MYSQL icon (Should be a dolphin or something)
Create a new database and a user, SAVE THESE DETAILS. YOU WILL NEED THEM.
Now that you have a database and user, you need to manage it. So click on PHPMyAdmin and enter your database


So from this point we are inside the Database, this can get a little confusing so we will take baby steps!

The best way I can explain these databases is to imagine them like Excel spread sheets. The database is the document, the tables are the worksheets and all the parts inside is the data!

Firstly we will need to create a new database. If you are using 000webhost you will have a different PHPMyAdmin to most main hosts but have no fear! It's pretty much the same.

So following Putona's tutorial we will name the Table to be "Table1". (Case sensitive).
From here we need to create fields! So for now add 3-4 depending on how many variables you are using.
Here is an example of how the table details should look (I used Excel to explain it).

http://ollyisafag.minepress.co.uk/Ollyiswrong/tutorial/Tableexplain.png

Putona used this explanation which is fairly good describing all of the options:

http://ollyisafag.minepress.co.uk/Ollyiswrong/tutorial/PutonaExplains.png

Your fields should now look like this:

http://i.imgur.com/nTN0t.png

So far so good? I hope so!

With my technique it doesn't matter what you use My Scripts name as, it's only for personal use so you can read it easier.

Eventually with more scripts it will do this:

http://i.imgur.com/L3iAm.png

What ID auto increment means is that each time you submit a new script name it will automatically add a new ID :spot:

Connecting our database up.

Ok, so now we need to create a PHP file! :stirthepot:
To do this, create a new file (Preferably a text file) and name it

Commit.php (or anything you want.php) but make sure to save it as a PHP file and not a text file ;)

Inside here you want to put your Database information!


<?PHP

$user_name = "usename"; //Username for the account you created earlier
$pass_word = "password"; //Password for the account you created earlier
$database = "database"; //The name of the database you created earlier
$server = "MySQLServer"; //With 000webhost this can be found by going to your control panel then clicking MySQL


We also need to actually connect the database...

$db_handle = mysql_connect($server, $user_name, $pass_word); or die(mysql_error());
$db_found = mysql_select_db($database, $db_handle); or die(mysql_error());

What this does is check the database is connecting and if not it will tell you the error :)

Now we are going to check if the database is found and if it is then do the following!


if ($db_found) {
$SQL = "SELECT * FROM `Table1` WHERE `ID` = 1";
$result = mysql_query($SQL);
if($result){
while ($db_field = mysql_fetch_assoc($result)){

$time = $db_field['Time'];
$tokens = $db_field['XP'];
}

Now there are two parts in this, the table and ID + the Variables.

$SQL = "SELECT * FROM `Table1` WHERE `ID` =1"; basically checks in Table1 and finds all of the information inside the row of ID1.


$time = $db_field['Time'];
$tokens = $db_field['XP'];

Another image which will hopefully explain it!
http://ollyisafag.minepress.co.uk/Ollyiswrong/tutorial/tableinfo.png



header("Content-type: image/png");
putenv("GDFONTPATH=".realpath("."));

$img = imagecreatefrompng("signature.png");

$color["yellow"] = imagecolorallocate( $img, 255, 255, 0 );
$color["white"] = imagecolorallocate( $img, 255, 255, 255 );
$color["green"] = imagecolorallocate( $img, 0, 255, 0 );
$color["orange"] = imagecolorallocate( $img, 254, 179, 0 );
$color["purple"] = imagecolorallocate( $img, 128, 0, 128 );
$color["dblue"] = imagecolorallocate( $img, 37, 84, 199 );



if you want to make it something other than a PNG, read this:
http://php.net/manual/en/function.header.php

$img = is the location of the background on your root.
putenv("GDFONTPATH=".realpath("."));
basically means the font should be in the root of the site :)


This section is a little more creative!

Now to change the text on the signature!


//size x y
imagettftextshadow($img, 20, 0, 25, 30, $color["dblue"], "font.ttf", "Script name");
imagettftextshadow($img, 12, 0, 10, 56, $color["orange"], "font.ttf", "XP Gained: ");
imagettftextshadow($img, 12, 0, 90, 56, $color["purple"], "font.ttf", number_format($XP));
imagettftextshadow($img, 12, 0, 10, 76, $color["orange"], "font.ttf", "Total Time: ");
imagettftextshadow($img, 12, 0, 120, 76, $color["purple"], "font.ttf", formatMilliseconds($time * 1000));

imagepng($img);
imagedestroy($img);
}

This is pretty much it, you have defined your color, the text and what its printing..

E.g the $ stuff ;)

SIMBA part:

Add this in the mainloop:

AddOnTerminate('SendData');//To make it send the data

Function SendData : Boolean;
Var
i : integer;
begin

i := InitializeHTTPClientWrap(False); //this creates a client

AddPostVariable(i, 'time', IntToStr(GetTimeRunning / 1000));//This adds our info to the client
AddPostVariable(i, 'runs', IntToStr(XPGained));

Result := Pos('true', Lowercase(PostHTTPPageEx(i, 'http://mywebsite.net/MyPage.php'))) <> 0;//Then this posts it

FreeHTTPClient(i);//Remember to free it

end;


Full PHP bit:




<?PHP //Milliseconds Function

function formatMilliseconds($milliseconds) {
$seconds = floor($milliseconds / 1000);
$minutes = floor($seconds / 60);
$hours = floor($minutes / 60);
$days = floor($hours / 24);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
$hours = $hours % 24;

if($days == 0){
$format = '%uhours, %02uminutes and %02u seconds';
$time = sprintf($format, $hours, $minutes, $seconds);
return rtrim($time, '0');
}else{
$format = 'Úys, %uhours, %02uminutes';
$time = sprintf($format, $days, $hours, $minutes, $seconds);
return rtrim($time, '0');
}

}

//imagettftext function
function imagettftextshadow($image, $size, $angle, $x, $y, $color, $fontfile, $text) {
imagettftext($image, $size, $angle, $x + 1, $y + 1, imagecolorallocate($image, 0, 0, 0), $fontfile, $text);
imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text);
}
//Database

$user_name = "DBUsername"; //Username for the account you created earlier
$pass_word = "Password"; //Password for the account you created earlier
$database = "DBname"; //The name of the database you created earlier
$server = "localhost"; //With 000webhost this can be found by going to your control panel then clicking MySQL

$db_handle = mysql_connect($server, $user_name, $pass_word) or die(mysql_error());
$db_found = mysql_select_db($database, $db_handle) or die(mysql_error());

//Script
if ($db_found) {

$SQL = "SELECT * FROM `table1` WHERE `ID` = 1";
$result = mysql_query($SQL);
if($result){
while ($db_field = mysql_fetch_assoc($result)){

$time = $db_field['Time'];
$xp = $db_field['XP'];
}

header("Content-type: image/png");
putenv("GDFONTPATH=".realpath("."));

$img = imagecreatefrompng("sig.png");

$color["yellow"] = imagecolorallocate( $img, 255, 255, 0 );
$color["white"] = imagecolorallocate( $img, 255, 255, 255 );
$color["green"] = imagecolorallocate( $img, 0, 255, 0 );
$color["orange"] = imagecolorallocate( $img, 254, 179, 0 );
$color["purple"] = imagecolorallocate( $img, 128, 0, 128 );
$color["dblue"] = imagecolorallocate( $img, 37, 84, 199 );

imagettftextshadow($img, 12, 0, 10, 50, $color["orange"], "sans.ttf", "XP Gained: ");
imagettftextshadow($img, 12, 0, 90, 50, $color["purple"], "sans.ttf", number_format($xp));
imagettftextshadow($img, 12, 0, 10, 70, $color["white"], "sans.ttf", "Time Run: ");
imagettftextshadow($img, 12, 0, 90, 70, $color["purple"], "sans.ttf", formatMilliseconds($time * 1000));

imagepng($img);
imagedestroy($img);
}else
print "Not working";

}
else
print "DB not Found, please report this";


?>

SQL Injection:


[J]ustin reminded me of this ^^

SQL Injection can be a pain in the arse, they can find your details, put stuff onto your website etc. So you need protection!
This is the function:


mysql_real_escape_string();


This is it in use:


mysql_real_escape_string($SQL);


Tutorial:

http://www.tizag.com/mysqlTutorial/mysql-php-sql-injection.php

Gucci
01-02-2013, 12:44 AM
nice tut man

Ian
01-02-2013, 09:56 AM
I may want to try this, could it work for avatars too?

Justin
01-02-2013, 09:58 AM
Wont work for avatars.

You might want to add some sql injection protection there Brad

xtrapsp
01-02-2013, 09:58 AM
I may want to try this, could it work for avatars too?

I don't believe so. It's worth a try :D

eska
01-02-2013, 10:07 AM
Disregard this post.

I didn't think before posting -.-

Justin
01-02-2013, 10:08 AM
I don't believe so. It's worth a try :D

Don't forget to add that you will need to edit the script to calculate the 'XPGained' variable :)

litoris
01-02-2013, 10:57 AM
Nice tut, too bad stats has been down since March :(

Justin
01-02-2013, 11:07 AM
Nice tut, too bad stats has been down since March :(

This doesn't use SRL Stats.

xtrapsp
01-02-2013, 11:07 AM
Nice tut, too bad stats has been down since March :(

It doesn't use SRL stats, it uses your own ^^

Justin
01-02-2013, 11:11 AM
It doesn't use SRL stats, it uses your own ^^

Feel the power of being ninja'd :D

Shatterhand
01-03-2013, 05:01 PM
There is a mistype at the part "Full PHP bit:".

$format = 'Úys, %uhours, %02uminutes';

J J
01-03-2013, 05:08 PM
Might want to add error reporting

error_reporting(-1);

Got everything working now thanks to Shatterhands tutorial and help on Skype. Hope this will work for anyone without help.

xtrapsp
01-05-2013, 02:32 AM
There is a mistype at the part "Full PHP bit:".

$format = 'Úys, %uhours, %02uminutes';

I think thats a format issue with the forum, it keeps changing it. I think the PHP tag isn't utf-8 or something ^^

J J
01-06-2013, 01:48 PM
Can you add information about adding caching to your images? Because my database is offline now because I put the image in my signature :stirthepot:

I think something like this (http://dtbaker.com.au/random-bits/how-to-cache-images-generated-by-php.html) will work? I'm not sure about PHP-related stuff and I don't want to overflow the site again. Thanks in advance :)

Shatterhand
01-15-2013, 07:28 PM
Can you add information about adding caching to your images? Because my database is offline now because I put the image in my signature :stirthepot:

I think something like this (http://dtbaker.com.au/random-bits/how-to-cache-images-generated-by-php.html) will work? I'm not sure about PHP-related stuff and I don't want to overflow the site again. Thanks in advance :)
Didnt know about caching, thanks for the tip!
EDIT: Its not working nvm.
EDIT2: Googled a lot, here is what I found:
source -> (http://webcodingeasy.com/Site-optimization/Cache-images-from-PHP-output)

function getRequestHeaders()
{
if (function_exists("apache_request_headers"))
{
if($headers = apache_request_headers())
{
return $headers;
}
}
$headers = array();
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
$headers['If-Modified-Since'] = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
}
return $headers;
}

// Return the requested graphic file to the browser
// or a 304 code to use the cached browser copy
function displayGraphicFile ($graphicFileName, $fileType='jpeg')
{
$fileModTime = filemtime($graphicFileName);
// Getting headers sent by the client.
$headers = getRequestHeaders();
// Checking if the client is validating his cache and if it is current.
if (isset($headers['If-Modified-Since']) &&
(strtotime($headers['If-Modified-Since']) == $fileModTime))
{
// Client's cache IS current, so we just respond '304 Not Modified'.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fileModTime).
' GMT', true, 304);
}
else
{
// Image not cached or cache outdated, we respond '200 OK' and output the image.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fileModTime).
' GMT', true, 200);
header('Content-type: image/'.$fileType);
header('Content-transfer-encoding: binary');
//header('Content-length: '.filesize($graphicFileName));
//readfile($graphicFileName);
}
}
displayGraphicFile("image.png");
These functions will change the caching setting of the header.
Remove the line "header("Content-type: image/png"); " and put the code before it.
It works. :D
EDIT3: Just realized that texts dont get updated on the cached picture. :(

Olly
01-16-2013, 04:43 AM
Kyles your man for this ^ :p

xtrapsp
01-16-2013, 10:05 AM
Didnt know about caching, thanks for the tip!
EDIT: Its not working nvm.
EDIT2: Googled a lot, here is what I found:
source -> (http://webcodingeasy.com/Site-optimization/Cache-images-from-PHP-output)

function getRequestHeaders()
{
if (function_exists("apache_request_headers"))
{
if($headers = apache_request_headers())
{
return $headers;
}
}
$headers = array();
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
$headers['If-Modified-Since'] = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
}
return $headers;
}

// Return the requested graphic file to the browser
// or a 304 code to use the cached browser copy
function displayGraphicFile ($graphicFileName, $fileType='jpeg')
{
$fileModTime = filemtime($graphicFileName);
// Getting headers sent by the client.
$headers = getRequestHeaders();
// Checking if the client is validating his cache and if it is current.
if (isset($headers['If-Modified-Since']) &&
(strtotime($headers['If-Modified-Since']) == $fileModTime))
{
// Client's cache IS current, so we just respond '304 Not Modified'.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fileModTime).
' GMT', true, 304);
}
else
{
// Image not cached or cache outdated, we respond '200 OK' and output the image.
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $fileModTime).
' GMT', true, 200);
header('Content-type: image/'.$fileType);
header('Content-transfer-encoding: binary');
//header('Content-length: '.filesize($graphicFileName));
//readfile($graphicFileName);
}
}
displayGraphicFile("image.png");
These functions will change the caching setting of the header.
Remove the line "header("Content-type: image/png"); " and put the code before it.
It works. :D
EDIT3: Just realized that texts dont get updated on the cached picture. :(

Try refreshing with CTRL + F5?

Shatterhand
01-16-2013, 10:09 AM
Try refreshing with CTRL + F5?
Ye it works, but a normal user would not do CTRL + F5. This is not the best solution. :D

xtrapsp
01-16-2013, 10:29 AM
Ye it works, but a normal user would not do CTRL + F5. This is not the best solution. :D

It simply means your not having your cache cleared regularly, I'l look into it when I have time ^^

Shatterhand
01-16-2013, 10:40 AM
It simply means your not having your cache cleared regularly, I'l look into it when I have time ^^
Im not sure what you mean.
JJ and me wants our images (lot of Kb) not to load every time we load the page.
Normal images get cached by browser automatically, but .php images dont.
So we want our .php images to have cached, but ONLY the image, the text on should be up-to-date.

Here is an example:
not cached image, up-to-date text: -> (http://shatterhand.comuv.com/ShatterFighter/image.php)
cahced image, not up-to-date text: -> (http://shatterhand.comuv.com/ShatterFighter/imagetest.php)

xtrapsp
01-16-2013, 10:59 AM
Im not sure what you mean.
JJ and me wants our images (lot of Kb) not to load every time we load the page.
Normal images get cached by browser automatically, but .php images dont.
So we want our .php images to have cached, but ONLY the image, the text on should be up-to-date.

Here is an example:
not cached image, up-to-date text: -> (http://shatterhand.comuv.com/ShatterFighter/image.php)
cahced image, not up-to-date text: -> (http://shatterhand.comuv.com/ShatterFighter/imagetest.php)

Hmm, the only thing that I question with that is that it's saving the text on the image isn't it? so surely it's a matter of detecting if the time is different from when u last cached it, deleting and reuploading?

Kyle

Shatterhand
01-16-2013, 11:44 AM
Hmm, the only thing that I question with that is that it's saving the text on the image isn't it? so surely it's a matter of detecting if the time is different from when u last cached it, deleting and reuploading?
Kyle
What if the text changes every minute or so? It would force to load the image every time you load the page. We should separate the image and text somehow, but not sure how. This caching applies to the whole header.

xtrapsp
01-16-2013, 12:42 PM
What if the text changes every minute or so? It would force to load the image every time you load the page. We should separate the image and text somehow, but not sure how. This caching applies to the whole header.

If we seperated the image to the text it wouldn't be an image format then surely?

Kyle Undefined
01-16-2013, 03:11 PM
You cannot "split" the text from the image. That's why you're printing out the text on top of the image, to make it a PHP image. It's either you cache everything, or you don't cache at all. Because even if the text changes, you'll have to create a whole new image, which defeats the purpose of caching.

I'd do an hour cache, that's the normal for these type of things.

xtrapsp
01-16-2013, 03:34 PM
You cannot "split" the text from the image. That's why you're printing out the text on top of the image, to make it a PHP image. It's either you cache everything, or you don't cache at all. Because even if the text changes, you'll have to create a whole new image, which defeats the purpose of caching.

I'd do an hour cache, that's the normal for these type of things.

Thanks for confirming Kyle.

StickToTheScript
03-30-2013, 09:02 PM
Very useful in the future my friend! Good job.

The Killer
05-20-2016, 07:01 PM
Right so I've been trying to follow this guide, but wanting to make something slightly different.

Firstly the simba code:
program new;


function AddAccount(login, password: String; TutIsland:Boolean; MageLevel:Integer):Boolean;
var
i : Integer;
a: String;
begin

i := InitializeHTTPClient(False); //this creates a client
//login, pw, TutIsland, MageLevel
AddPostVariable(i, 'login', login);//This adds our info to the client
AddPostVariable(i, 'pw', password);
AddPostVariable(i, 'TutIsland', ToStr(TutIsland));//This adds our info to the client
AddPostVariable(i, 'MageLevel', IntToStr(MageLevel));
a := Lowercase(PostHTTPPageEx(i, 'http://tkfarm.esy.es/AddAccount.php'));
Result := Pos('true', a) <> 0;//Then this posts it
Writeln(a);
FreeHTTPClient(i);//Remember to free it


end;

begin
Writeln(AddAccount('srl@gmail.com', 'gg', false, 1));
end.

The output from this is
<!doctype html public "-//ietf//dtd html 2.0//en">
<html><head>
<title>302 found</title>
</head><body>
<h1>found</h1>
<p>the document has moved <a href="http://error.hostinger.eu/403.php?">here</a>.</p>
</body></html>

False


So its clearly not working correctly, though I have no idea why...

here's the php code:

<?PHP

$user_name = "u791978145_tk"; //Username for the account you created earlier
$pass_word = "removed"; //Password for the account you created earlier
$database = "u791978145_tk"; //The name of the database you created earlier
$server = "mysql.hostinger.co.uk"; //With 000webhost this can be found by going to your control panel then clicking MySQL

$login = $_POST['login'];//The things in the [] can be anything you want, but remember these for later
$pw = $_POST['pw'];
$tutisland = $_POST['TutIsland'];
$magelevel= $_POST['MageLevel'];



// Create connection
$conn = new mysqli($server, $user_name, $pass_word);

// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO Accounts (Login, Pw, TutIsland, MageLevel) VALUES ('". $login . "' ,'" . $pw . "', '" . $tutisland . "', '" . $magelevel . "');";//Or whatever you called your table and script
$result = $conn->query($sql);
print $login . $pw . $tutisland . $magelevel;
print $sql;
print $result;
if($result)
print "True";
else
print "False";

?>

Olly
05-20-2016, 10:50 PM
Set a user agent:

SetHTTPUserAgent(i, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36');

You probs also want to close the connection > mysqli_close($conn);

The Killer
05-20-2016, 11:29 PM
You probs also want to close the connection > mysqli_close($conn);

I guess thats an accidental double quote, but thanks a lot Olly, I'll try and make a list of the changes that are needed to this thread and get an admin to update it

edit: I was making some other scrub mistakes, but I figure that stuff out, not setting the user agent was my main problem