Twilight MU Online Forum

Twilight MU Online Forum (http://forum.twilightmu.com/index.php)
-   Programming Section (http://forum.twilightmu.com/forumdisplay.php?f=128)
-   -   [Tutorial]Making a dynamic signature for twilight (http://forum.twilightmu.com/showthread.php?t=18279)

Quest 01-04-2008 04:19 PM

[Tutorial]Making a dynamic signature for twilight
 
Hello everybody,

Update info
Updated again with a link to XAMPP, a web server that can be installed locally and easier than installing Apache and PHP separately. You can now try your dynamic signatures on your own computer before uploading somewhere or giving them to someone who can host.

I updated the tutorial to work with and to output PNG images, which is better quality than JPG, partly because PHP handles JPG badly, not outputting them at maximum quality (comparison included at the end of tutorial). Other minor updates includes the introduction of a 0rr if() case, another textcolor variable, to paint in red some status messages and renaming the prepared signature to "signature" instead of "signature0". Thread appearance slightly updated to be more readable on linux; smileys introduced.
-- § --

I will try to explain how to do a dynamic signature for Twilight MU using php.
WARNING: I AM A N00B. THE THINGS I WILL EXPLAIN WERE LEARNT FROM OTHERS' WORK AND BY COPY / PASTING AND MODIFYING. SO DON'T EXPECT ANY FLAWLESSNESS OR BRILLIANCE FROM ME.

[0. Things you will need]
  • an already-made .PNG signature. For this tutorial I used this image (using zukih as test subject without her permission http://signature.elementfx.com/image...eys/tongue.png hope I don't get banned http://signature.elementfx.com/image...eys/messed.png). Do notice that the signature needs to be specially made with space left for numbers & letters to be written. You must have everything put in the signature except status numbers, guild name and online status. Of course, it will work with any kind of signature too, but imagine how ugly it will look to have numbers written on it.
  • server with PHP AND php functions include() and fsockopen() enabled. Big warning here, as most free hosting companies do NOT have include() and fsockopen() enabled, usually offering them only if you upgrade your account to a paid one.
  • (OPTIONAL) http://www.wedwick.com/wftopf.exe - It's a tool working under windows that converts fonts to a format usable by php. I didn't like the default font used by php so I used this.
  • (OPTIONAL) HaxrCorp.fon - It's the font I used in this tutorial. You can use any other font you like.
  • patience? http://signature.elementfx.com/image...t-wits-end.png

[1. Creating the folders]
First of all let's make the directory structure on the server.
Note:
! the "[ ]" brackets are NOT part of the folder name.
! the folder "public_html" is the root folder of your site, you do NOT need to create it (it's already there in fact).
! the tutorial is updated to use png but you still see "/sig.jpg/" in the structure and you may be confused. Don't be! sig.jpg is just a folder and it's irrelevant to the outcome of the filetype; I did not change the folder structure for convenience. If still in doubt use sig.png as foldername and get on with it.

http://signature.elementfx.com/image...rstructure.png

[2. Uploading the prepared signature]
Verify that all is in order with the prepared signature...

http://signature.elementfx.com/images/signature.png

... name it "signature.png" and upload it to the "./sig_example/sig.jpg/images/" folder.

[3. Converting & Uploading the desired font] OPTIONAL
I will use the "HaxrCorp 4088" font. Download it on your PC and copy it to the "C:\Windows\Fonts\" folder.
Run "wftopf.exe" and select the settings as show in picture.
Note:
! You do NOT need to have PHP installed on your PC in order to run and use this application.
! It is useful to delete what is written in the "Preview" box and put there numbers, the guild name, "YES" and "NO" to see if they look how you planned. For example, I tested the font in Photoshop to see how it would look if I use it on the signature, and then I used this program and modified the "Heigh" & "Width" settings until they looked like what I had in photoshop.
! It might be quite difficult to find the propper "Heigh" & "Width" settings. If the size of the planned font was declared as "14" in photoshop, it does NOT mean that if you put 14 at "Height" it will be the same.

http://signature.elementfx.com/images/wftopf.png

After you obtained the desired look, save the font as "font.gdf" and upload it to "./sig_example/sig.jpg/gd_fonts/" on the server.

to be continued...

Quest 01-04-2008 04:21 PM

[4. Writing the main script]
This is the principal and longest part of the tutorial. http://signature.elementfx.com/image...e-fighter1.png
Create a file on your PC 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.
Code:

<?php
$im = imagecreatefrompng("images/signature.png");
imageantialias($im, true);

imageSaveAlpha($im, true);

imagealphablending($im , false);

# creating a variable that stores the image from the prepared signature we uploaded to the server.
# imageantialias, imageSaveAlpha and imagealphablending are png related settings that I am unsure what they do http://signature.elementfx.com/images/smileys/silly.png ; they are necesary for they make the signature to have alpha transparency (for example my signatures have cut corners that are transparent, whereas were they jpg that corner would have been filled with a color).

Code:

$site = file_get_contents("http://www.twilightmuonline.com/search.php?chara=zukih28s");
# using the search function from the twilight website we search for the character whom status we want to show on the signature. replace "zukih28s" 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:

preg_match_all("/<strong>(.*)<\/strong>/", $site, $results0);
# 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".
# $results0 array will look like this after the above code is executed:

http://signature.elementfx.com/images/results0.png

# 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 check the HTML code of the web page http://www.twilightmuonline.com/sear...chara=zukih28s 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 (also while working on this script I discovered some mistakes in the twilight's website HTML code http://signature.elementfx.com/image...ys/disdain.png but I didn't check any further anyway; if it works ... ).
# 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);
# 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:

http://signature.elementfx.com/images/results1.png

# level, reset and elite reset are contained in [1][0],[2][0] respectively [3][0].

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);
# 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:

http://signature.elementfx.com/images/results2.png

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 signature we uploaded.

Code:

$textcolor = imagecolorallocate($im, 48, 255, 0);
$textcolorRED = imagecolorallocate($im, 255, 0, 0);

# set the colour of the font.
# the 3 numbers after $im are the RGB values for the colors I chose (a shade of green complementary to pink, and red for second). They have the same value that any other program will show (e.g. here, Photoshop):

http://signature.elementfx.com/images/RGB.png

Code:

$font = imageloadfont("gd_fonts/font.gdf");
# loading the font that we will use.

Code:

imagestring($im , $font , 38 ,  5, $results1[1][0] , $textcolor );
# beginning the actual writing on the signature. Here, we wrote the level.
# syntax: (<image we write on (here, $im)>, <font we will use; if you don't use another font, here you will write the size of the font (1 to 5)> , X coordinate , Y coordinate , <what to write; here, we just dump the variable's value> , <colour of font>)
# the X and Y coordinates will say where to start writing from. They are equal to pixels. PHP calculates X & Y starting from top left corner of the image.

http://signature.elementfx.com/images/graph.png

You should change them until they get in the desired position.

Code:

if ( $results1[2][0] == NULL ) {

        imagestring ( $im , $font , 106 , 6 , "0" , $textcolorRED );

        }

        else {

                imagestring( $im , $font , 106 , 6 , $results1[2][0] , $textcolor );

        }

# writing the reset; we use an if() because if the character has no resets the $results1[2][0] doesn't get displayed (it should but it doesn't; a bug I haven't tracked down yet)
# if the character is 0rr we display 0 in red color

Code:

imagestring ( $im , $font , 41 , 25, $results2[1][0] , $textcolor );
imagestring ( $im , $font , 41 , 41, $results2[1][1] , $textcolor );
imagestring ( $im , $font , 41 , 56, $results2[1][2] , $textcolor );
imagestring ( $im , $font , 41 , 71, $results2[1][3] , $textcolor );

# writing the strength, agility, vitality and energy.
# you notice that we don't write elite reset and command, but they can be written if needed. For Command you just need to insert one more similar line of code and ajust it where to be written. For elite reset you can add it too but it's just a switch (0 or 1) so you would rather do a signature that writes already you are elite and just display the usual resets. In this case elite rr and command aren't needed on the signature.

Code:

if ($results2[1][5]==NULL){
                imagestring($im , $font , 57 , 93, "NO GUILD" , $textcolorRED );
        }
        else{
                imagestring($im , $font , 57 , 93, $results2[1][5] , $textcolor );
        }

#we use an "if" statement because, if the character is in no guild we want the signature to say so, in red. If the character is in a guild, then we write the guild's name, in normal color.

Code:

if ($results0[1][0]=="Online"){
                imagestring($im, $font, 183, 93, "YES", $textcolor);
        }
        else{
                imagestring($im, $font, 183, 93, "NO", $textcolor);
        }

# similar for the online status. If character is online we write "YES" using the normal text color, otherwise "NO" using red text color.

Code:

header("Content-type: image/png");

imagepng($im, NULL, 0, NULL);

?>

# End of File http://signature.elementfx.com/image...hypnotized.png
# because the output will be in a browser we set the header type and then output the image.
# syntax: (<image to be output> , <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, 0 ;maximum 9; remember png compression is lossless, it's just that I haven't tried the setting yet that I left it 0>, <filters>)

After you finished writing, save and upload "generate.php" to "./sig_example/sig.jpg/includes/".

Almost finished now, hang in there http://signature.elementfx.com/image...ys/soldier.png.

Quest 01-04-2008 04:21 PM

[5. Writing the auxiliary script]
Don't be scared this one is very short. http://signature.elementfx.com/image...s/struggle.png
Create a file named "index.php" on your PC and open it for editing. Copy / paste the following code in it.
Code:

<?php
include('./includes/generate.php');
?>

Save it and upload it to "./sig_example/sig.jpg/".
I'll explain why we need this file (the "secret" of dynamic signatures):
Our signature is dynamic and to actually see it we need to run the "generate.php" script. But if we want to use the signature on a forum, we can't use "http://server_address.com/sig_example/sig.jpg/includes/generate.php" because the forum will only allow (and understand) something ending in an image extension. So we use a trick, we use our "sig.jpg" folder as a file. The forum will think of it as a image file, but when it accesses it from our server, the server knows it's a folder and (by default) the server runs any file .html or .php with the name "index". But index.php that we have will call the image-generating script throught the include() function. The script will generate an image and send response to index.php as a png. And behold, our signature is on forum (or wherever for that matter).

[6. Restricting access]
Test your signature to see if it works by going to http://<the address of your server>/sig_example/sig.jpg/ .
If everything is in order, then we might consider "locking" the folders that are in "sig.jpg/" so that anyone trying to access anything else except "index.php" (a.k.a our signature), to receive an HTTP Error 403 - Forbidden.
Create a file named ".htaccess" on your PC and open it for editing. Add the folowing code.
Code:

<Limit GET POST HEAD PUT DELETE>
    order deny,allow
    deny from all
</Limit>

Save and upload it to:
  • ./sig_example/sig.jpg/gd_fonts/
  • ./sig_example/sig.jpg/images/
  • ./sig_example/sig.jpg/includes/
Now this is what you should have on your server
http://signature.elementfx.com/image...rstructure.png

My result:
http://signature.elementfx.com/sig_example/sig.jpg/

Here is a result using the old script that output jpg:
http://signature.elementfx.com/sig_example_jpg/sig.jpg/

---- § ----

Finished *phew* http://signature.elementfx.com/images/smileys/party.png

Please email/pm me any questions you have, any discrepancies you find, any suggestions you have. I will modify posts if problems are found.

Oh yah, and press here if you like all this nonsense ^_^.

Phoenix 01-04-2008 04:48 PM

Nice guide ^^

Quest 01-04-2008 04:52 PM

Phoenix approves !!!111 yey

prozac 02-04-2008 01:22 AM

Good.... u forgot to make dynamic part for Elite reset :)

HalfDead 02-04-2008 06:00 AM

Sry for spamming, Quest pls check ur mail in game, i got a Q for u about this script..

Quest 02-04-2008 06:06 AM

Quote:

Originally Posted by prozac (Post 91909)
Good.... u forgot to make dynamic part for Elite reset :)

Quote:

Originally Posted by Quest (Post 91893)
# you notice that we don't write elite reset and command, but they can be written if needed. For Command you just need to insert 1 more similar line of code and ajust it where to be written. For elite reset you just need to modify the reset line to show elite resets instead. In this case elite rr and command aren't needed on the signature.

OMG They don't even read and says I am a nab T_T

Quote:

Originally Posted by HalfDead (Post 91915)
Sry for spamming, Quest pls check ur mail in game, i got a Q for u about this script..

Yah I saw that I have mail last night but forgot to check sorry ^^ Checking asap.



Also thanks goes to Lizi for pointing out a mistake with one of the pictures. ("Thanks Lizi!").

HalfDead 02-04-2008 08:42 AM

w00t thanks Quest! All worked perfect.
Il reward you soon^^. Tnx for all the help bro.
Sry to spam btw XD

Iril 02-04-2008 08:47 AM

wow
i want 1 me too


All times are GMT -5. The time now is 01:59 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright ©2006 - 2019 Twilight MU. All Rights Reserved