Tom Posted September 28, 2015 Share Posted September 28, 2015 (edited) Gonna give this tutorial thing a crack ya know Introduction What is a Dynamic Signature?A Dynamic Signature is an automatically updating image that will display a group of statistics for individual, or a certain amount of users. It uses PHP scripts to write over the top of an already existing image with data from a specified database, and then outputs it as a new image. Example of a grouped user dynamic signature: Example of an individual user dynamic signature: What are the benefits of creating a dynamic signature? Dynamic signatures are a great way to display data, and it also gives users of your script something to show off. For example, you want to find out how long an individual user has run a certain script for, but all you can see is the time ran in milliseconds, which isn't very readable. Requirements - A web server / website - A MySQL Database - A brain basic understanding of programming concepts - The ability to understand what I am trying to demonstrate, I am by no means a teacher. The Beef So lets get started. With my current setup, I am using 2 separate PHP files, one is for updating the database with the new data for each user, and the other is for generating Creation of the Database The database is the most important thing when it comes to creating the dynamic signature, as you might of guessed, it stores all of your data. I'm going to assume most of you are going to access your database through your webhost, and I will use my webhost as an example in the tutorial, but if you do not use a web host, and need help setting up the database with appropriate tables, feel free to ask. Step 1. Access your web hosting cPanel. Step 2. Create a database user with all privileges: First thing you need to do here, is navigate to the MySQL section of cPanel, which usually you have to scroll down a tiny bit to find. And select MySQL Databases. Now, you may need to scroll down again, but you should see the Add MySQL User option on the screen (Ignore the timestop_ part, this is the name my hosting provider decided to give me) Fill in the details, and click create. You now have a MySQL user, and if i entered 'Tom' into the first text field, my username would be timestop_tom, and yours could be peter_smith, or even just smith. Step 3. Creating a database For this you can stay on the same page as before, but it is generally located towards the top of the page. Once again, ignore the timestop part, as that is unique to me, you will have your own prefix. Click create, and you are done for this step. Step 4. Assigning the user you created to the database you created. This step is very important, as you want the requires privileges. Go down towards the bottom of the same page as before, and you should see: Select the user you just created, then the database you have just created, and click add. You will then be navigated to a page containing something like this, but it may be different You want to give yourself every single privilege, this can be done easily just by checking the ALL PRIVILEGE checkbox if there is one. Finish by clicking Make Changes. Step 5. Creating a table in your database This is a little more tricky, but it can be done using the built in phpMyAdmin that generally comes with cPanel, or just simple software like Navicat Lite. You can access phpMyAdmin from the front page of your cPanel once again Click to navigate. You should then see a list of databases on the left of the page, click through them until you found the one you just created, (timestop_awesomescript in my case) Afterwards, on the right side of the page, it should automatically pop up with the option to create a table, you DON'T want to do it like this, instead up the top of the page, you should see the tab option "SQL". Press that, and you should see this tab pop up In that middle text field, enter the following: CREATE TABLE Data (Username varchar(25) NOT NULL, timeran bigint(200), expgained bigint(200), premium varchar(3), PRIMARY KEY(Username)); And click GO in the bottom right corner. Congratulations, your database and table have been setup correctly if you followed this properly. Update.php This script is used to pass new data into your Tables, it will also ADD onto old data <?php // Connection details $servername = "YOUR_SERVER_NAME E.G. WWW.BRAZZERS.COM"; $user = "YOUR_DATABASE_USERNAME"; $password = "YOUR_DATABASE_PASSWORD"; $dbname = "THE_NAME_OF_THE_DATABASE"; // Your data variables, you can have as many as you want. $timetemp = $_GET ['time']; // The total time ran $exptemp = $_GET ['exp']; // The total EXP gained $nametemp = $_GET ['name']; // The username of the botter. $premium = $_GET ['premium']; // "YES" if the user is premium, "NO" if they are using the free script // Variable conn is used to determine the new mysql connection for above data // If you are running this script off the same webserver that the database is stored on, the servername can be NULL. $conn = mysqli_connect ($servername, $user, $password, $dbname ); // Checking if the connection is valid, if not, killing the process and throwing a error message if ($conn->connect_error) { die ( "Connection failed: " . $conn->connect_error ); } if (mysqli_connect_errno ()) { echo "Failed to connect to the mySQL server "; die (); } $setResult = mysqli_query ( $conn, "SELECT * FROM Data WHERE Username='$nametemp'" ); // Selects all fields from the Data table, based on the username supplied if ($setResult) { /* If the Table already contains some data for this user, it will instead ADD the new data onto the old data, then insert it back into the table. */ $resultArray = mysqli_fetch_row($setResult); $time = $resultArray[1]; $exp = $resultArray[2]; $exp2 = $exp + $exptemp; $time2 = $time + $timetemp; // Query for inserting the wanted data into the mysql - Where Data is the table name $sql = "REPLACE INTO Data (Username, timeran, expgained, premium) VALUES ('$nametemp', '$time2',' $exp2', '$premium')"; if (mysqli_query ( $conn, $sql )) { echo "Recorded Data"; } else { echo "Error: " . $sql . "<br>" . mysqli_error ( $conn ); } } else{ // If there is currently no user data, it will insert a fresh sample. $sql = "INSERT INTO Data (Username, timeran, expgained, premium) VALUES ('$nametemp', '$timetemp',' $exptemp', '$premium')"; if (mysqli_query ( $conn, $sql )) { echo "Recorded new Data"; } else { echo "Error: " . $sql . "<br>" . mysqli_error ( $conn ); } } $conn->close (); ?> Signature.php This script is used to generate the signature that the users can put in there signatures, or just look at to keep track of their stats. <? function formatTime($time){ $time_seconds = $time / 1000; $time_minutes = $time_seconds / 60; $time_hours = $time_minutes / 60; $time_days = floor($time_hours / 24); $seconds = $time_seconds % 60; $minutes = $time_minutes % 60; $hours = $time_hours % 24; $days = floor($time_days % 365); $years = floor($time_days / 365); return $years . "y " . $days . "d " .$hours . "h " . $minutes . "m "; } $username=""; //Your MySQL Username. $password=""; // Your MySQL Pass. $database=""; // Your MySQL database. $host=""; // Your MySQL host. This is "localhost" or the IP specified by your hosting company. $player_name=$_GET['player_name']; // This gets the player his name from the previous page. mysql_connect($host,$username,$password); // Connection to the database. @mysql_select_db($database) or die( "Unable to select database. Be sure the databasename exists and online is."); //Selection of the database. If it can't read the database, it'll give an error. /* To protect MySQL injection. */ $player_name = stripslashes($player_name); $player_name = mysql_real_escape_string($player_name); /* */ if($player_name == "ALL"){ // If you want to sum all of your users data, like I have in my signature, you need this. $query="SELECT SUM(timeran) as timesum FROM Data"; $result=mysql_query($query); $Timeran1= mysql_fetch_assoc($result); $Timeran = $Timeran1[timesum]; $query="SELECT SUM(expgained) as expsum FROM Data"; $result=mysql_query($query); $ExpGained1= mysql_fetch_assoc($result); $ExpGained = $ExpGained1[expsum]; // Now for the creation of the image. header('Content-Type: image/png;'); // Your image must be in the same directory as your PHP Scripts for it to work, otherwise you will need to include a path $im = @imagecreatefrompng('YOUR_IMAGE.png') or die("Cannot find image, check naming and file location"); $text_color = imagecolorallocate($im, 255,255,100); // RED, GREEN, BLUE , you can goto http://colorpicker.com to pick a nice colour if you wish. $text_username = "ALL"; // This gets the information about player name to be showed in the picture. $text_timeran = formatTime($Timeran); // Same as above ^^ $text_expgained = number_format($ExpGained); $font = 'Calibri.ttf'; //Upload your custum font to the directory where this file is placed if you wish to customise it. // 18 is the font size, 0 is the angel of the text, 165 is the x coordinate on your image, and 132 is the Y coordinate on your image. imagettftext($im, 18, 0, 165, 132, $text_color, $font, 'ALL'); imagettftext($im, 12, 0, 300, 93, $text_color, $font, $text_timeran); imagettftext($im, 14, 0, 130, 93, $text_color, $font, $text_expgained); imagepng($im); imagedestroy($im); return; } // Below is the code for regular players, it will not SUM $query="SELECT * FROM Data WHERE Username='$player_name'"; // Gets all the information about the player. $result=mysql_query($query); $i=mysql_num_rows($result); // Here we are counting how many rows this result gives us. if ($i == 1) // If the user has been correct, then it'll give us 1 row. If its 1 row, then it'll proceed with the code. { $Username=mysql_result($result,0,"Username"); $Timeran=mysql_result($result,0,"timeran"); $ExpGained=mysql_result($result,0,"expgained"); // Creating of the .png image. header('Content-Type: image/png;'); header('Content-Type: image/png;'); // Your image must be in the same directory as your PHP Scripts for it to work, otherwise you will need to include a path $im = @imagecreatefrompng('YOUR_IMAGE.png') or die("Cannot find image, check naming and file location"); $text_color = imagecolorallocate($im, 255,255,100); // RED, GREEN, BLUE , you can goto http://colorpicker.com to pick a nice colour if you wish. $text_username = "$Username"; // This gets the information about player name to be showed in the picture. // This gets the information about player name to be showed in the picture. $text_timeran = formatTime($Timeran); // Same as above ^^ $text_expgained = number_format($ExpGained); $font = 'Calibri.ttf'; //Upload your custum font to the directory where this file is placed. Then change the name here. // 18 is the font size, 0 is the angel of the text, 165 is the x coordinate on your image, and 132 is the Y coordinate on your image. imagettftext($im, 12, 0, 138, 130, $text_color, $font, $text_username); imagettftext($im, 12, 0, 300, 93, $text_color, $font, $text_timeran); imagettftext($im, 14, 0, 138, 93, $text_color, $font, $text_expgained); imagepng($im); imagedestroy($im); } else echo('Username is not in our database. Please try again.'); // If the username doesn't exist (so the row is 0) then it'll give en error. mysql_close(); ?> Finishing Off There is only a couple more steps left, and they are generally a lot easier for most people. Step 1. Submitting data when your script is stopped Basically, in your onExit(), you want to have this, you will need to replace the URL with your web host URL. if (getExperienceTracker().getElapsed(Skill.YOURSKILL) > 0) { try { URL submit = new URL("http://THE_WEB_DIRECTORY + "/update.php?name=" + getClient().getUsername().replace(" ", "_") + "&time=" + instance.getExperienceTracker().getElapsed(Skill.YOURSKILL) + "&exp=" + instance.getExperienceTracker().getGainedXP(Skill.YOURSKILL) + "&premium=" + "YES"); URLConnection con = submit.openConnection(); instance.log("Submitting statistics..."); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); final BufferedReader rd = new BufferedReader( new InputStreamReader(con.getInputStream())); rd.close(); } catch (Exception e) { instance.log("Failed to submit print details"); } } Don't forget to start the experience tracker either, this can be done in the onStart getExperienceTracker().start(Skill.YOURSKILL); Step 2. Creating a web page for generation This 2nd last step, and it is important to ensure that the html file you create is in the same folder as your PHP scripts, otherwise you will have to do all that pathing nonsense, which isn't that big of a deal. Here is my current HTML Code for a simple user interface: <html> <head> <title>Dynamic Signature Creation</title> </head> <h1>Your Dynamic Signature</h1> <p> To generate your Dynamic Signature, enter your OSBot username below!</p> <form action="signature.png" method="get"> OSBot Username: <input type="text" name="player_name"><br> <!-- This is a little text box which will ask for you playername. --> <input type="Submit"> <!-- A "send" button. --> </form> </body> </html> Which would look something like Step 3. Modifying your .htaccess to rewrite .php urls to .png so that you can display your signature on the forum. On your webserver, there should be a file called ".htaccess" Modify this, and place the following inside RewriteEngine On RewriteBase / RewriteRule signature.png signature.php You should now be able to generate Dynamic signatures like so: If you find any problems, please don't hesitate to point them out, or to ask for help. Edited October 12, 2015 by Tom 6 Quote Link to comment Share on other sites More sharing options...
DubzieBug Posted September 28, 2015 Share Posted September 28, 2015 omg 0.o i have been wondering how to do this! My savior once again tom Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 28, 2015 Share Posted September 28, 2015 Oh boy, I love me some delicious motherfucking SQLi! It's a good learning point, but don't ever use this in a production environment. Yes, there's only user data, but data and you don't even sanitise it! Quote Link to comment Share on other sites More sharing options...
Tom Posted September 28, 2015 Author Share Posted September 28, 2015 Oh boy, I love me some delicious motherfucking SQLi! It's a good learning point, but don't ever use this in a production environment. Yes, there's only user data, but data and you don't even sanitise it! sanitisation is for the weak Quote Link to comment Share on other sites More sharing options...
Tom Posted September 28, 2015 Author Share Posted September 28, 2015 For the record, there is SQL injection protection Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 28, 2015 Share Posted September 28, 2015 For the record, there is SQL injection protection $setResult = mysqli_query ( $conn, "SELECT * FROM Data WHERE Username='$nametemp'" ); // Selects all fields from the Data table, based on the username supplied What happens when $nametemp is ' OR '1'='1'? Look into parametised queries or sanitise your input properly :/ Quote Link to comment Share on other sites More sharing options...
Tom Posted September 28, 2015 Author Share Posted September 28, 2015 $setResult = mysqli_query ( $conn, "SELECT * FROM Data WHERE Username='$nametemp'" ); // Selects all fields from the Data table, based on the username supplied What happens when $nametemp is ' OR '1'='1'? Look into parametised queries or sanitise your input properly :/ The username is directly entered by your script using their osbot username, so unless someone has the URL and knows the php parameters, they aren't going to have the ability to do anything Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted September 28, 2015 Share Posted September 28, 2015 The username is directly entered by your script using their osbot username, so unless someone has the URL and knows the php parameters, they aren't going to have the ability to do anything Why don't you understand that if someone wants to get all of your data, they will. All I need to do is just turn on wireshark, look at my connections, and grab the data. You don't sanitise any data in the update page, you use deprecated MySQL in signature.php, you rely solely on mysql_real_escape_string (which will not escape certain characters like \ and \x00). At least you mask errors, that's a start. 2 Quote Link to comment Share on other sites More sharing options...
Tom Posted September 28, 2015 Author Share Posted September 28, 2015 Why don't you understand that if someone wants to get all of your data, they will. All I need to do is just turn on wireshark, look at my connections, and grab the data. You don't sanitise any data in the update page, you use deprecated MySQL in signature.php, you rely solely on mysql_real_escape_string (which will not escape certain characters like \ and \x00). At least you mask errors, that's a start. oh no they get my fish sum 1 Quote Link to comment Share on other sites More sharing options...
Lemons Posted September 28, 2015 Share Posted September 28, 2015 (edited) Lol, PHP OT: Looks good besides the obvious SQL Injection, use PDO if your lazy lol Edited September 28, 2015 by Lemons Quote Link to comment Share on other sites More sharing options...
Apaec Posted September 29, 2015 Share Posted September 29, 2015 Lol, PHP OT: Looks good besides the obvious SQL Injection, use PDO if your lazy lol you're* 1 Quote Link to comment Share on other sites More sharing options...
Flamezzz Posted October 5, 2015 Share Posted October 5, 2015 (edited) Edit: fixed it by generating sigs every 10 min..."Unable to retrieve signature image dimensions, please try another image."Dafuq is this? I get this when I try to put the image in my signature...Halp anyone plz?(/care about the text atm)http://www.flamezzz.nl/signature.png?user=flamezzz&script=fcluehuntereasyDimensions = 500x150, even windows can read this so I assume the file is not corrupt in any way.signature.php <? Header('Content-type: image/png'); ..... ..... $image = @imagecreatefrompng('./cluehuntereasy.png') or die("Picture not found."); $black = imagecolorallocate($image, 0, 0, 0); $white = imagecolorallocate($image, 255, 255, 255); imagecolortransparent($image, $black); imagealphablending($image, false); imagesavealpha($image, true); ..... ..... imagettftext($image, 15, 0, 370, 58, $white, $font, $row['solved']); imagettftext($image, 15, 0, 370, 107, $white, $font, $runtime); imagettftext($image, 15, 0, 370, 153, $white, $font, $profit); imagettftext($image, 20, 0, 50, 153, $white, $font, $row['name']); imagepng($image); imagedestroy($image); mysql_close(); ?> Edited October 6, 2015 by Flamezzz Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted October 5, 2015 Share Posted October 5, 2015 "Unable to retrieve signature image dimensions, please try another image." Dafuq is this? I get this when I try to put the image in my signature... Halp anyone plz? (/care about the text atm) http://www.flamezzz.nl/signature.png?user=flamezzz&script=fcluehuntereasy Dimensions = 500x150, even windows can read this so I assume the file is not corrupt in any way. signature.php <? Header('Content-type: image/png'); ..... ..... $image = @imagecreatefrompng('./cluehuntereasy.png') or die("Picture not found."); $black = imagecolorallocate($image, 0, 0, 0); $white = imagecolorallocate($image, 255, 255, 255); imagecolortransparent($image, $black); imagealphablending($image, false); imagesavealpha($image, true); ..... ..... imagettftext($image, 15, 0, 370, 58, $white, $font, $row['solved']); imagettftext($image, 15, 0, 370, 107, $white, $font, $runtime); imagettftext($image, 15, 0, 370, 153, $white, $font, $profit); imagettftext($image, 20, 0, 50, 153, $white, $font, $row['name']); imagepng($image); imagedestroy($image); mysql_close(); ?> I think I circumvented this for myself by removing imagealphablending($image, false);. Good luck Quote Link to comment Share on other sites More sharing options...
Tom Posted October 7, 2015 Author Share Posted October 7, 2015 Edit: fixed it by generating sigs every 10 min... Sorry, i wasn't following the thread so I didn't see your initial post. What was the problem and why do you need to generate a sig every 10 minutes? Quote Link to comment Share on other sites More sharing options...
Explv Posted October 7, 2015 Share Posted October 7, 2015 (edited) dat SQL Edited October 7, 2015 by Explv Quote Link to comment Share on other sites More sharing options...