[6. Writing the main script]
This is the principal and longest part of the tutorial.
Create a file in
C:\xampp\htdocs\signature_example\sig.png\include\ named "
generate.php". Open it (e.g. with notepad) and prepare for editing.
I will explain the code as we write in the file. Just copy / paste the code sections into the file. I'll also use comments in the code itself, maybe it helps learning faster.
Code:
<?php
//reading the site
$site = file_get_contents("http://www.twilightmuonline.com/search.php?chara=scyonnoou");
# using the search function from the twilight website we search for the character whom status we want to show on the signature. replace
scyonnoou with the character name you chose the signature to be for.
# the character name we send to the search function does
NOT require to be cAsE SeNsItIvE (unlike in-game) so don't worry about it.
# it's good practice to test the link between
" " and make sure it works before continuing.
# file_get_contents() gives us the HTML page (with the results of the search on it) which gets stored in the
$site variable.
Code:
//making matches
preg_match_all("/<strong>(.*)<\/strong>/", $site, $results0); //online status
# preg_match_all() is a php function that takes two arguments (here,
<strong>(.*)<\/strong> and
$site), compares them, and puts what it finds in an array (here,
$results0).
# sytax:
(.*) = any "something"(a wildcard).
# $results0 array content will look like this after the above code is executed:
# as you see, what this code line did was to search in the HTML code (of the
$site) for anything matching "
<strong>ANYTHING </strong>". Here, the findings (two matches were found) were put in a matrix (or two-dimensional array), in the [0] it was put with the searched criteria included, and in [1] it was put without the search criteria.
# note that
[1][0] has the value of the on-line status.
# if you get "Offline" at [1][0] don't be scared, it just means the character is offline, while at the moment I took that screenshot, it was online.
# if you check the HTML code of the web page
http://www.twilightmuonline.com/sear...hara=scyonnoou you will see that it contains.
Code:
<td bgcolor=black width=30>
<font face=Arial size=2>
<font color='#00FF00'>
<strong>Online</strong>
</font>
</font>
</td>
The code is very messy in original, I indented it here for easy reading.
# if you are wondering why we put "
/<strong>(.*)<\/strong>/" instead of "
<strong>(.*)</strong>" it's because, besides that the arguments must be contained between
"/ /", some characters need to be escaped. "
\" is used for escaping characters. If those characters aren't escaped the php compiler misinterprets what we are trying to do and will give errors.
Code:
preg_match_all("/<td bgcolor=black width=30><font face=Arial size=2 font color=white>(.*)\((.*)\)\[(.*)\]<\/b><\/font><\/td>/", $site, $results1); //level, reset, elite switch
# here we have 3 readings: level, reset and elite reset. It's all HTML code but with a lot of escaping because the LVL RR ERR format is <number>(<number>)[<number>], and the brackets must be escaped.
# I am
NOT sure if it's necessary to have such a long match, it might be possible to get the same readings with a smaller search criteria. I just wanted to be sure of what I get.
# what the matrix
$results1 contains after the code is executed:
# level, reset and the elite switch are contained in
[1][0],
[2][0] respectively
[3][0].
# again don't get scared if values differ, the character might have gained additional levels/resets.
Code:
preg_match_all("/<td bgcolor=black width=30><font face=Arial size=2 font color=white>([A-Za-z0-9]{1}|[A-Za-z0-9]{2}|[A-Za-z0-9]{3}|[A-Za-z0-9]{4}|[A-Za-z0-9]{5}|[A-Za-z0-9]{6}|[A-Za-z0-9]{7}|[A-Za-z0-9]{8})<\/b><\/font><\/td>/", $site, $results2); //strength, agility, vitality, energy, guild
# this will catch the status and the guild name. The syntax is slightly different: we search for only one string (we have only 1 pair of
( ) ) and it must be numbers, letters or numbers+letters. if we don't use all that criteria, we will end up with the result from LVL, RR, ERR (brackets included) in here too and we don't need that. so what is between
( ) brackets says: search for any "something" that is made of 1, 2, 3, 4, 5, 6, 7 or 8 numbers / letters / numbers&letters.
# syntax:
[A-Za-z0-9] = any letter from A to Z that is upper-case + any letter from a to z that is lower-case + any number from 0-9;
{4} = that occurs 4 times (e.g. this will detect a string like "n00b");
| = or;
( ) = marks the search criteria.
# content of
$results2 after execution of the line:
Now we finished with reading the site, we collected all the required data. Let's list the variables that hold the relevant values:
- $results0[1][0] = On-line status
- $results1[1][0] = Level
- $results1[2][0] = Reset
- $results1[3][0] = Elite reset
- $results2[1][0] = Strength
- $results2[1][1] = Agility
- $results2[1][2] = Vitality
- $results2[1][3] = Energy
- $results2[1][4] = Command
- $results2[1][5] = Guild name
This values will be written later on the signatures we uploaded.
Code:
//Online status
//if for loading different images/colors
if ($results0[1][0]=="Online"){
//creating the image
$im = imagecreatefrompng("images/signature.png");
imagesavealpha($im, true);
imagealphablending($im, true);
//defining text colors
$textcolor = imagecolorallocate($im, 255, 255, 255); //white
}
else{
//creating the image
$im = imagecreatefrompng("images/signature_offline.png");
imagesavealpha($im, true);
imagealphablending($im, true);
//defining text colors
$textcolor = imagecolorallocate($im, 58, 58, 58); //gray
}
# using an
if() for loading different images and using different text colors depending on the online status of the character.
# imagesavealpha(),
imagealphablending() are all PNG related functions, one saving the image's alpha channels, the other setting the blending mode.
# creating a variable
$imthat holds the image of the signature.
# setting the color of the text we will use, using
imagecolorallocate(); the 3 numbers after
$im are the RGB values of the color; they have the same value that any other program will show (e.g. here, MSPaint):
# for the old clients: you notice I don't use imageantialias() anymore; it's because I discovered it's useful only when using php to draw lines, arcs, circles or w/e; also didn't notice any difference in quality between using and not using it.
# for the old clients: you notice imagealphablending() gets the value "true" now; that's because "false" doesn't work with the fonts, makes them appear as blocks.
Code:
//defining font
$font = 'font/smudgerletplain-1.0.ttf';
# loading the font we will use.
Let's write the "easy" values first, leaving the if() ones for the end.
Code:
//level
imagettftext( $im , 14 , 0 , 210 , 73 , $textcolor , $font , $results1[1][0] );
//strength
imagettftext( $im , 14 , 0 , 210 , 97 , $textcolor , $font , $results2[1][0] );
//agility
imagettftext( $im , 14 , 0 , 296 , 97 , $textcolor , $font , $results2[1][1] );
//stamina
imagettftext( $im , 14 , 0 , 205 , 120 , $textcolor , $font , $results2[1][2] );
//energy
imagettftext( $im , 14 , 0 , 300 , 120 , $textcolor , $font , $results2[1][3] );
# beginning the actual writing on the signature; we don't write command as he's not a DL.
# syntax:
(<image we write on>
, <font size; it isn't always the same with the value from Photoshop, but neither too far from it>
, <angle; we can write at angles with this new function; 0 = 90degrees, normal standing text>
, <X coordinate>
, <Y coordinate>
, <color for the text>
, <font face>
, <writing; here, we just dump the variable's value>
)
# the
X and
Y coordinates will tell where to start writing from. They are equal to pixels. PHP calculates X & Y starting from top left corner of the image.
You should change them until they get in the desired position.
Code:
//guild
//detecting no guild
if ($results2[1][5]==NULL){
imagettftext( $im , 14 , 0 , 170 , 139 , $textcolor , $font , "NO GUILD" );
}
else{
imagettftext( $im , 14 , 0 , 170 , 139 , $textcolor , $font , $results2[1][5] );
}
# using an if() to see if the character is in any guild; if he is, we write the name of the guild; if not, we write "NO GUILD".
Code:
//reset
//if elite
if ($results1[3][0]==1){
imagettftext( $im , 14 , 0 , 296 , 73 , $textcolor , $font , $results1[2][0]." Elite" );
}
else{
imagettftext( $im , 14 , 0 , 296 , 73 , $textcolor , $font , $results1[2][0] );
}
# we use an if() to detect if the character is elite; if he is we write: "<the_current_resets> Elite"; otherwise we just write "<the_current_resets>".
# syntax:
. (the dot) is used for concatenation of the two strings (resets and " Elite").
# for the old customers: you notice I don't use the 0rr if() case anymore; that's because I found out it works like this and the bug I thought I had wasn't real ... me n00b ^_^.
Code:
//outputting image
header("Content-type: image/png");
imagepng($im, NULL, 9, NULL);
imagedestroy($im);
?>
# End of File
# because the output will be in a browser we set the header type and then output the image.
# syntax:
(<image to be output> [COLOR="Lucida Console"]
,[/COLOR] <file to output to; here, we put
NULL because we don't want to save the file, we just want to show it directly>
, <png compression; here,
9 aximum 9, minimum 0; remember, png compression is lossless>
, <filters>
)
# I discovered imagedestroy() should always be used so the memory used by php for the image to be freed; I don't know if it's any use here as the script ends when the work with the image is done, but it's at least good practice.
After you finished writing, save. Always save.
Almost finished now, hang in there.