Page 1 of 1

Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 4:37 am
by Tim
Hey guys,

Trying to get back into development on a new project. I am currently working on a combat system that uses the POST system to pass the creature from the form, and then execute the battle through a if(isset) on the same page. What I'm currently trying to do though is to reload the page every 5 seconds with the same creature selected and everything, so consecutive battles are taking place (and eventually take away stamina from the user per reload). This will keep the user from having to click the fight button a million times ...

I have already tried a few different ways with jQuery but the reload is only reloading the page, not with the post variable set.

Code: Select all

if (isset($_POST['creature'])
{
   //this is where the battle takes place, i want it to reload and this to execute (having the post variable set)
}
else
{
   //this is where it's loading ...
}
I have been looking into jQuery, reading a lot, and mostly watching a lot of Youtube videos, but this problem continues to challenge me. The perfect example (and where I stole the idea from) is with the game Lost Runes. Not sure if anyone plays it ..., but if you sign-up and attack some creatures with their "auto attack" setting, you will see exactly what I'm talking about.

So, I know it's possible ... I just can't figure out how to do it. Sorry if I'm not explaining myself correctly please let me know and I will try to explain it in a different way.

combat.php

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<?php
session_start();
include_once 'includes/connect.php';
include_once 'includes/session.php';
?>

<link rel="stylesheet" type="text/css" href="style.css" />

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<form method="post" action="combat.php">
<select name="creature">
<?php
$query = "SELECT * FROM creatures ORDER BY id";
$data = mysql_query($query) or die ("Error 007: Unable to query the creatures table.");

if (isset($_POST['creature']))
{
	$creature = $_POST['creature'];
} 
else 
{
	$creature = $data['name'];
}

while ($row = mysql_fetch_assoc ($data))
{
	?> 
	<option value="<?php echo $row['name'];?>"<?php if ($row['name'] == $creature){echo "selected=\"selected\"";} ?>><?php echo $row['name']; ?></option> 
	<?php
}
?>
</select>
<input type="submit" name="submit" value="Fight!" />
</form>

<?php
if (isset($_POST['submit'])) 
{
	$creature = $_POST['creature'];
	
	$query = mysql_query("SELECT * FROM creatures WHERE name = '$creature'") or die ("Error 008: Unable to query the creatures table.");
	$data = mysql_fetch_array ($query);
	
	$creature_health = $data['health'];
	$creature_attack_level = $data['attack_level'];
	$creature_defense_level = $data['defense_level'];
	$creature_gold_coins = $data['gold_coins'];
	$creature_loot_1 = $data['loot_1'];
	$creature_loot_2 = $data['loot_2'];
	$creature_loot_3 = $data['loot_3'];
	$creature_loot_4 = $data['loot_4'];
	$creature_loot_5 = $data['loot_5'];
	$creature_loot_6 = $data['loot_6'];
	
	$rounds = 0;
	
	$user_accuracy_bonus = 0;
	$user_armor_bonus = 0;
	$user_damage_bonus = 0;
	$user_defense_bonus = 0;
	
	$user_hits = 0;
	$user_critical_hits = 0;
	$user_dodges = 0;
	$user_misses = 0;
	
	$creature_hits = 0;
	$creature_critical_hits = 0;
	
	$total_damage_dealt = 0;
	$total_damage_received = 0;
	
	$attack_experience = 0;
	$defense_experience = 0;
	
	while ($rounds < 10)
	{
		$rounds++;
		
		if ($user_health > 0) // If the user is still alive, s/he will continue to fight.
		{
			$user_critical_attack_roll = rand(1, 10);
			$user_attack_roll = rand(1, 10) + $user_attack_level + $user_accuracy_bonus;
			$creature_defense_roll = rand(1, 10) + $creature_defense_level;
			
			if ($user_attack_roll > $creature_defense_roll)
			{
				$user_hits++;
				
				$damage = ($user_attack_roll + $user_damage_bonus) - $creature_defense_roll;
				$creature_health = $creature_health - $damage;
				
				$total_damage_dealt = $total_damage_dealt + $damage;
			}
			else
			{
				if ($user_critical_attack_roll == 1) // The user rolled a critical-to-hit.  The creature will NOT dodge this hit, no matter what.
				{
					$user_critical_hits++;
					
					$damage = $user_attack_roll;
					$creature_health = $creature_health - $damage;
					
					$total_damage_dealt = $total_damage_dealt + $damage;
				}
				else
				{
					$user_misses++;
				}
			}
		}
		else
		{
			// The creature was victorious.
			echo "You hit the " . $creature . " " . ($user_hits + $user_critical_hits)  . " times (" . $user_critical_hits . " critical hits) and missed " . $user_misses . " times.";
			echo "<br>";
			echo "You were hit " . ($creature_hits + $creature_critical_hits) . " times (" . $creature_critical_hits . " critical hits) and dodged " . $user_dodges . " times.";
			echo "<br><br>";
			echo "Total Damage Dealt: " . $total_damage_dealt . " (Average Hit: " . @round($total_damage_dealt / ($user_hits + $user_critical_hits)) . ")";
			echo "<br>";
			echo "Total Damage Received: " . $total_damage_received . " (Average Hit: " . @round($total_damage_received / ($creature_hits + $creature_critical_hits)) . ")";
			echo "<br><br>";
			echo "You were defeated by the " . $creature . " after " . $rounds . " round(s).";
			exit;
		}
		
		if ($creature_health > 0) // If the creature is still alive ... it will continue to fight.
		{
			$creature_critical_attack_roll = rand(1, 10);
			$creature_attack_roll = rand(1, 10) + $creature_attack_level;
			$user_defense_roll = rand(1, 10) + $user_defense_level + $user_defense_bonus;
			
			if ($creature_attack_roll > $user_defense_roll)
			{
				$creature_hits++;
				
				$damage = $creature_attack_roll - ($user_defense_roll + $user_armor_bonus);
				echo $creature . " hit " . $username . " for " . $damage . ". <br>";
				$user_health = $user_health - $damage;
				
				$total_damage_received = $total_damage_received + $damage;
			}
			else
			{
				if ($creature_critical_attack_roll == 1) // The creature rolled a critical-to-hit.  The user will NOT dodge this hit, no matter what.
				{
					$creature_critical_hits++;
					
					$damage = $creature_attack_roll - $user_armor_bonus;
					echo $creature . " critically hit " . $username . " for " . $damage . ". <br>";
					$user_health = $user_health - $damage;
					
					$total_damage_received = $total_damage_received + $damage;
				}
				else
				{
					$user_dodges++;
				}
			}
		}
		else
		{
			// The user was victorious.
			$attack_experience = ($creature_defense_level * ($user_hits + $user_critical_hits)) - $user_attack_level;
			$defense_experience = ($creature_attack_level * $user_dodges) - $user_defense_level;
			
			if ($attack_experience <= 0)
			{
				$attack_experience = 1;
			}
			
			if ($defense_experience <= 0)
			{
				$defense_experience = 1;
			}
			
			$overall_experience = $attack_experience + $defense_experience;
			
			$update = "UPDATE users SET overall_experience = overall_experience + '$overall_experience' WHERE username = '$username'";
			mysql_query($update) or die ("Error 010: Unable to update the users table.");
			
			$update = "UPDATE users SET attack_experience = attack_experience + '$attack_experience' WHERE username = '$username'";
			mysql_query($update) or die ("Error 011: Unable to update the users table.");
			
			$update = "UPDATE users SET defense_experience = defense_experience + '$defense_experience' WHERE username = '$username'";
			mysql_query($update) or die ("Error 012: Unable to update the users table.");
		
			echo "You hit the " . $creature . " " . ($user_hits + $user_critical_hits)  . " times (" . $user_critical_hits . " critical hits) and missed " . $user_misses . " times.";
			echo "<br>";
			echo "You were hit " . ($creature_hits + $creature_critical_hits) . " times (" . $creature_critical_hits . " critical hits) and dodged " . $user_dodges . " times.";
			echo "<br><br>";
			echo "Total Damage Dealt: " . $total_damage_dealt . " (Average Hit: " . @round($total_damage_dealt / ($user_hits + $user_critical_hits)) . ")";
			echo "<br>";
			echo "Total Damage Received: " . $total_damage_received . " (Average Hit: " . @round($total_damage_received / ($creature_hits + $creature_critical_hits)) . ")";
			echo "<br><br>";
			echo "You defeated the " . $creature . " after " . $rounds . " round(s)!";
			echo "<br>";
			echo "You gained " . $attack_experience . " attack experience and " . $defense_experience . " defense experience.";
			echo "<br><br>";
			include_once 'includes/level_up.php';
			exit;
		}
	}
	
	if ($rounds == 10)
	{
			echo "You hit the " . $creature . " " . ($user_hits + $user_critical_hits)  . " times (" . $user_critical_hits . " critical hits) and missed " . $user_misses . " times.";
			echo "<br>";
			echo "You were hit " . ($creature_hits + $creature_critical_hits) . " times (" . $creature_critical_hits . " critical hits) and dodged " . $user_dodges . " times.";
			echo "<br><br>";
			echo "Total Damage Dealt: " . $total_damage_dealt . " (Average Hit: " . @round($total_damage_dealt / ($user_hits + $user_critical_hits)) . ")";
			echo "<br>";
			echo "Total Damage Received: " . $total_damage_received . " (Average Hit: " . @round($total_damage_received / ($creature_hits + $creature_critical_hits)) . ")";
			echo "<br><br>";
			echo "The " . $creature ." fled from the battle!";
			exit;
	}
}
?>

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 5:25 am
by Jackolantern
Reloading a page and getting a $_POST value again goes against the way $_POST is supposed to function. In the traditional web development world, changes to a page that are not supposed to make changes to the state of the application are supposed to be done through $_GET query strings, and things that change the state or make some kind of change that cannot be undone (like placing an order) are done through $_POST, which tells the browser that it should guard against refreshes causing the same action again. That is why refreshes don't work with $_POST very well.

jQuery really isn't going to help either, because jQuery is Javascript, and the state of a Javascript application is reset each time the page is loaded. You are probably going to have to make a table in the database to store this info and query for it with each page reload or perhaps use AJAX calls to get the data.

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 6:01 am
by Tim
Thanks for the info Jacko, you're always a great resource to bounce ideas off of!

Do you think it would be unwise to convert my combat system to use GET instead of POST?

The only thing I can think of that would be bad is if the user opened a bunch of tabs of mygame.com/combat.php?creature=Goblin (example) and is getting the EXP off a bunch of battles running at the same time.

It would be super easy to do this in jQuery though with GET ... reload the current URL every 5 seconds for a total of ten times (turns).

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 9:08 am
by Winawer
POST won't really give you a security benefit vs GET. A cheater can send as many POST (or GET) requests as he wants with whatever variables set. You'll need to save something like the timestamp of the last attack so you can check the action made by the player is valid.

If you're using jQuery, I don't see much point in reloading the whole page. Use Ajax to get the new data and update the existing page.

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 10:32 am
by Callan S.
Why wouldn't you use session values and pass it along that way?

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 12:05 pm
by Chris
Winawer wrote:You'll need to save something like the timestamp of the last attack so you can check the action made by the player is valid.
I strongly dis-advise the use of timestamps as tokens. I've proven this method to be majorly flawed on a lot of systems as it is way too predictable. Use unique random generated tokens and store them in the clients JavaScript.

GET works a lot faster than POST, don't ask me how or why, but I found when sending GET requests to Apache that there is a noticeable speed difference.
(and eventually take away stamina from the user per reload)
Never ever trust a request from a client. Base the stamina reduction on a the time when the battle started, and store the time server-side, not client side.

Code: Select all

   $creature = $_POST['creature'];

   $query = mysql_query("SELECT * FROM creatures WHERE name = '$creature'") or die ("Error 008: Unable to query the creatures table."); 
Don't forget your mysql_real_escape_string when working with strings, otherwise I'll delete your database when I get the chance. Especially with that handy little error you're throwing there. As always, I'd strongly advise using the id rather than name as the reference. The id is an integer, therefore all you need to do is cast it rather than escape it.

Code: Select all

   $creature = (int)$_POST['creature'];

   $query = mysql_query("SELECT * FROM creatures WHERE id = '$creature'") or die ("Error 008: Unable to query the creatures table."); 

Code: Select all

<select name="creature">
<?php
$query = "SELECT * FROM creatures ORDER BY id";
while ($row = mysql_fetch_assoc ($query))
{
   ?> 
   <option value="<?php echo $row['id'];?>"<?php if ($row['name'] == $creature){echo "selected=\"selected\"";} ?>><?php echo $row['name']; ?></option> 
   <?php
}
?>
</select>

Re: Reload a page with a post variable ... how?

Posted: Mon Apr 23, 2012 5:41 pm
by Jackolantern
You could do it through sessions I guess, but since a reload hits the server again, you may as well just keep track of it all through the database. That would allow you to also setup a gatekeeper where you could ensure that each player is only in one battle at a time, and perform any other checks you need.