jblack Posted October 26, 2006 Share Posted October 26, 2006 Ok... so I'm making a huge arena type script to deal with levels and monsters and xp and such... The registration and logging in works fine... The members list works fine. But I can't get the core of it down. The fighting comes out with really wierd things...Ok so my strength in this program is 1, just use that as a variable and remember it. The problem I have with it though is that I hit really obscenely high numbers and the enemy monster can have like -58 hp and the fight still will not end. The fight only ends when your own fighter dies...Also, I hit the high numbers as 21...Anyway lets get on with the show here's the code, minus some things that deal with the login, registration, logout, etc...*One more thing, the mysql database looks like this:FIELD TYPE NULL DEFAULTid int(5) No username varchar(15) No password varchar(20) No email varchar(30) No hits int(3) No 10 strength int(100) No 0 accuracy int(100) No 0 defense int(100) No 0 race varchar(20) No faction varchar(20) No rank varchar(50) No gold int(11) No 0 xp int(5) No 0 <?phpinclude('mydatabaseinfo.php');if($page == 'fight1') {$usercookie = $_COOKIE['user'];$rmonster = '1';$q = "SELECT name,hits,strength,accuracy,defense FROM Arena_Monsters WHERE id = '$rmonster'";$fight = mysql_query($q);$row = mysql_fetch_row($fight);$monster = $row[0];$mhits = $row[1];$mstrength = $row[2];$maccuracy = $row[3];$mdefense = $row[4];$mxp = $row[5];?><table align="center" width="75%" style="border: #8D6D4D 1px solid;"> <tr> <td bgcolor="#d2b038" align="center"><b>FIGHT!</b></td> </tr> <tr> <td bgcolor="#e3cc80" align="center"><?php echo "Monster name: " . $monster . "<p />";echo "Hits: " . $mhits . "<p />";echo "Strength: " . $mstrength . "<p />";echo "Accuracy: " . $maccuracy . "<p />";echo "Defense: " . $mdefense . "<p />";echo "<hr>";$q2 = "SELECT username,hits,strength,accuracy,defense,xp FROM Arena WHERE username = '$usercookie'";$character = mysql_query($q2);$row2 = mysql_fetch_row($character);$fighter = $row2[0];$hits = $row2[1];$strength = $row2[2];$accuracy = $row2[3];$defense = $row2[4];$xp = $row2[5];echo "Username: " . $fighter . "<p />";echo "Hits: " . $hits . "<p />";echo "Strength: " . $strength . "<p />";echo "Accuracy: " . $accuracy . "<p />";echo "Defense: " . $defense . "<p />";echo "<hr>";while($mhits > '0' || $hits > '0') {if($strength < '5') {$rndhit = rand(1, 2);}if($strength > '4' && $strength < '10') {$rndhit = rand(1, 4);}if($strength > '9' && $strength < '20') {$rndhit = rand(1, 7);}if($strength > '19' && $strength < '40') {$rndhit = rand(1, 11);}if($strength > '39' && $strength < '80') {$rndhit = rand(1, 16);}else {$rndhit = rand(1, 22);}$mon1hit = rand(1, 3);echo $usercookie . " hits a " . $rndhit . " on " . $monster . ".<p>";$mhits = $mhits - $rndhit;echo $monster . " hits a " . $mon1hit . " on " . $usercookie . ".<p>";$hits = $hits - $mon1hit;echo "<b>" . $usercookie . "</b>: " . $hits . " <b>" . $monster . "</b>: " . $mhits;echo "<hr>";}?></td> </tr></table><?php } ?> Link to comment Share on other sites More sharing options...
justsomeguy Posted October 26, 2006 Share Posted October 26, 2006 This is an OR condition:while($mhits > '0' || $hits > '0') {So the fight will continue as long as either one is alive. You want it to continue as long as both of them are alive, so make it an AND condition instead.As far as rolling high numbers, remove the quotes around all of your numbers. A quoted number is a string, not a number. Since your data types in the database are int, comparing them with a string might be messing you up and falling into the else category. Link to comment Share on other sites More sharing options...
jblack Posted October 27, 2006 Author Share Posted October 27, 2006 Thanks...I'll try that, though I have no doubt that is what it is.EDIT -> Now the monster dies, but I still hit high numbers, even with the quotes gone. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 27, 2006 Share Posted October 27, 2006 The reason is because you only have 1 else statement. The interpreter sees this if/else statement:if($strength > '39' && $strength < '80') {$rndhit = rand(1, 16);}else {$rndhit = rand(1, 22);}And since the condition is not true, it executes the else and overwrites your random value. So, you need an else on every if statement after the first one. I also replaced rand with mt_rand, which is faster then rand and generates 'more random' numbers. I also took out the curly braces for the if statements, if you only have a single statement following the if statement, you don't need to wrap it in curly braces. if($strength < 5) $rndhit = mt_rand(1, 2);elseif($strength > 4 && $strength < 10) $rndhit = mt_rand(1, 4);elseif($strength > 9 && $strength < 20) $rndhit = mt_rand(1, 7);elseif($strength > 19 && $strength < 40) $rndhit = mt_rand(1, 11);elseif($strength > 39 && $strength < 80) $rndhit = mt_rand(1, 16);else $rndhit = mt_rand(1, 22);$mon1hit = mt_rand(1, 3); Link to comment Share on other sites More sharing options...
jblack Posted October 27, 2006 Author Share Posted October 27, 2006 Alright... so here's my full code, now the other stuff works, but what doesn't work is the updating ofthe database to give you xp. here's the code (look at near the bottom); <?phpinclude('database.php');$page = $_REQUEST['page'];if($page == "login") { $username = $_POST['username']; $password = $_POST['password']; if($username == '' || $password == '') {?><table align="center" width="75%" style="border: #8D6D4D 1px solid;"> <tr> <td bgcolor="#d2b038" align="center"><b>ERROR!</b></td> </tr> <tr> <td bgcolor="#e3cc80" align="center">You must enter a username and password!</td> </tr></table><?php die; } $q = "SELECT username FROM Arena WHERE username = '$username' AND password = '$password'"; $result = mysql_query($q); if(mysql_num_rows($result) == '1') { setcookie('user',$username,84000); header('location: index.php?file=mfront'); } else {?><table align="center" width="75%" style="border: #8D6D4D 1px solid;"> <tr> <td bgcolor="#d2b038" align="center"><b>ERROR!</b></td> </tr> <tr> <td bgcolor="#e3cc80" align="center">Your username/password is nonexistent or invalid!</td> </tr></table><?php }}if($page == 'logout') {setcookie('user',null,-1);header('location:index.php?file=front');}if($page == 'fight1') {$usercookie = $_COOKIE['user'];$rmonster = mt_rand(1,2);$q = "SELECT name,hits,strength,accuracy,defense,xp FROM Arena_Monsters WHERE id = '$rmonster'";$fight = mysql_query($q);$row = mysql_fetch_row($fight);$monster = $row[0];$mhits = $row[1];$mstrength = $row[2];$maccuracy = $row[3];$mdefense = $row[4];$mxp = $row[5];?><table align="center" width="75%" style="border: #8D6D4D 1px solid;"> <tr> <td bgcolor="#d2b038" align="center"><b>FIGHT!</b></td> </tr> <tr> <td bgcolor="#e3cc80" align="center"><?php echo "Monster name: " . $monster . "<p />";echo "Hits: " . $mhits . "<p />";echo "Strength: " . $mstrength . "<p />";echo "Accuracy: " . $maccuracy . "<p />";echo "Defense: " . $mdefense . "<p />";echo "XP: " . $mxp . "<p />";echo "<hr>";$q2 = "SELECT username,hits,strength,accuracy,defense,xp FROM Arena WHERE username = '$usercookie'";$character = mysql_query($q2);$row2 = mysql_fetch_row($character);$fighter = $row2[0];$hits = $row2[1];$strength = $row2[2];$accuracy = $row2[3];$defense = $row2[4];$xp = $row2[5];echo "Username: " . $fighter . "<p />";echo "Hits: " . $hits . "<p />";echo "Strength: " . $strength . "<p />";echo "Accuracy: " . $accuracy . "<p />";echo "Defense: " . $defense . "<p />";echo "<hr>";while($hits > 0 && $mhits > 0) {if($strength < 5) {$rndhit = mt_rand(1, 2);$rndhit = $rndhit + round(($accuracy / 2));}elseif($strength > 4 && $strength < 10) {$rndhit = mt_rand(1, 4);$rndhit = $rndhit + round(($accuracy / 2));}elseif($strength > 9 && $strength < 20) {$rndhit = mt_rand(1, 7);$rndhit = $rndhit + round(($accuracy / 2));}elseif($strength > 19 && $strength < 40) {$rndhit = mt_rand(1, 11);$rndhit = $rndhit + round(($accuracy / 2));}elseif($strength > 39 && $strength < 80) {$rndhit = mt_rand(1, 16);$rndhit = $rndhit + round(($accuracy / 2));}else {$rndhit = mt_rand(1, 22);$rndhit = $rndhit + round(($accuracy / 2));}$mon1hit = mt_rand(1, 3);echo $usercookie . " hits a " . $rndhit . " on " . $monster . ".<p>";$mhits = $mhits - $rndhit;echo $monster . " hits a " . $mon1hit . " on " . $usercookie . ".<p>";$hits = $hits - $mon1hit;echo "<b>" . $usercookie . "</b>: " . $hits . " <b>" . $monster . "</b>: " . $mhits;echo "<hr>";}if($hits < 1) {echo "The " . $monster . "has killed you!";echo "You have died. You will be automatically revived when you<p>";echo "go <a href='index.php?file=mfront'>here</a>";}if($mhits < 1) {echo "You have killed a " . $monster . ". You have gained " . $mxp . " experience.<p>";echo "You have also earned " . $rndgold = mt_rand(1,13) . " gold.";$q3 = "UPDATE Arena SET xp = 'xp + $mxp',gold = '$rndgold' WHERE 'username' = '$fighter'";$run = mysql_query($q3) or die("Could not run query.");}?></td> </tr></table><?php } ?> Link to comment Share on other sites More sharing options...
justsomeguy Posted October 27, 2006 Share Posted October 27, 2006 xp and gold are both ints, so you don't want to put quotes around them. Quotes makes a string. There should also not be quotes around the field name 'username'. So try this:$q3 = "UPDATE Arena SET xp = (xp + $mxp), gold = (gold + $rndgold) WHERE username = '$fighter'";Also, since you have posted both your database schema and source code, you really need to escape your database inputs. $q = "SELECT username FROM Arena WHERE username = '" . mysql_real_escape_string($username) . "' AND password = '" . mysql_real_escape_string($password) . "'"; Otherwise people can type in SQL statements into the username or password field and mess with your database. Whenever you use variables in a SQL statement that the user entered, like from $_GET or $_POST or $_COOKIE, you always need to escape them. There's one other SQL statement that needs to be escaped in the code. Link to comment Share on other sites More sharing options...
reportingsjr Posted October 27, 2006 Share Posted October 27, 2006 Actually justsomeguy, I have been pointed out that mysql_real_escape_string can really only help hackers. Since all it does is clean up mysql code it wont prevent hackers from doing something like putting in "DELETE `table`" so yeah.. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 27, 2006 Share Posted October 27, 2006 That's not true, give me an example where one can enter SQL code into a variable and have it get executed here:$sql = "SELECT * FROM table WHERE id='" . mysql_real_escape_string($id) . "'";The key is the quote. Any data they enter has to start with a single quote, and the function will escape it. Link to comment Share on other sites More sharing options...
reportingsjr Posted October 27, 2006 Share Posted October 27, 2006 Yes but that is it. I already gave you an example. The person could just type in DROP `table_name` and the whole table would be dropped. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 27, 2006 Share Posted October 27, 2006 No it wouldn't, that would produce this query:SELECT * FROM table WHERE id='DROP `table`'Run that query and see if the table gets dropped. Link to comment Share on other sites More sharing options...
reportingsjr Posted October 27, 2006 Share Posted October 27, 2006 http://programmingtalk.com/showthread.php?...age=2&pp=10Thats where I was told.. Link to comment Share on other sites More sharing options...
justsomeguy Posted October 27, 2006 Share Posted October 27, 2006 if you're passing SQL code in a GET var you're reallyasking for itObviously, you should never put anything un-escaped into a SQL query.Since you are deleting anyway (and everybody knows this, right?), I just need to make sure your Where clause hits everything.Like I hinted at above, escaping the string only works for strings, that is, things that are surrounded by quotes. If you are dealing with a number, you should always use either intval or floatval to transform the data instead of mysql_escape_string. I mentioned that here:http://w3schools.invisionzone.com/index.ph...6&hl=intvalhttp://w3schools.invisionzone.com/index.ph...7&hl=intvalhttp://w3schools.invisionzone.com/index.ph...1&hl=intval Link to comment Share on other sites More sharing options...
jblack Posted October 28, 2006 Author Share Posted October 28, 2006 nvm... Link to comment Share on other sites More sharing options...
shiftJIS Posted October 28, 2006 Share Posted October 28, 2006 I can't just stand by while someone has the totally wrong idea. justsomeguy is right, you NEED to escape input. I'll try to clear things up.Let's say you want to query information out of a table for a specific name: SELECT * FROM table WHERE name='$name' Suppose this $name came from $name = $_GET["name"]; If the hacker types in somename'; DROP TABLE table; then your mysql query effectively becomes: SELECT * FROM table WHERE name='somename'; DROP TABLE table;' Now I forget if that last quote makes a difference, but the hacker could close it or include it in an if statement that always tests as TRUE. Still, what you end up with is two queries in one, the first doing a search and the second screwing up your life.However, if you escape the string: $name = mysql_real_escape_string($_GET["name"]); then the query becomes: SELECT * FROM table WHERE name='somename\'; DROP TABLE table;' This is only one query, the quote has been ESCAPED (hence the function name) and shows up as a literal quote. This query is harmless and won't even return any results.That is, unless there is someone in your database named: somename'; DROP TABLE table; Link to comment Share on other sites More sharing options...
justsomeguy Posted October 28, 2006 Share Posted October 28, 2006 That is, unless there is someone in your database named: somename'; DROP TABLE table;You know, that's the name I normally use. But it was taken here. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now