Page 1 of 1

Tournament script

Posted: Fri Aug 01, 2008 4:01 am
by dagothar
I'm just starting with PHP. I had a idea given to create a script as for the mmo game for players to enter into a tournament and be automatically assigned into divisions.
I just want to learn something.

Now, as you imagine it's done as much straightforward as possible and untidy at best. There are sure some 'conventions' for coding many issues I'm struggling with. Could you possibly point out as many mistakes, quirks, errors or whatever I'm making here?
What else does the code need to be legitimately used?

As much as I can tell, script works for me.
Here's how it looks: http://dagothar.freehostia.com

Certain functions are yet to be filled in and return some dummy values for testing purposes.

Code: Select all

   <HTML>
 
    <HEAD>
    <META name="Content-Type" content="text/html">
    </HEAD>
 
    <BODY>
    <?php
       $config_file = false;
       $entry_file = false;
 
       $deadline = 0;
       $allow_multiple_entries = false; //whether it's possible for players to enter multiple characters
                   //from one account
 
    /*----------------------------------------------------*/
 
       //Check whether form data are true and valid
       function check($acc, $char, $pass)
       {
          return true;
       }
 
       //Load configuration file for the tournament
       function load_config()
       {
          global $deadline, $allow_multiple_entries;
 
          $config_file = fopen("data/config.txt", "r");
          if($config_file == false) {
             die("Could not load configuration file.");
          }
 
          $config = array();
          while(true) {
             $line = fgets($config_file);
             if($line == null) break;
 
             $line = trim($line);
             if($line[0] == '#') continue;
             $line = explode('=', $line);
 
             $config[$line[0]] = $line[1];
          }
 
          if($config["allow_multiple_entries"] === "yes") $allow_multiple_entries = true;
             else $allow_multiple_entries = false;
 
          $deadline = strtotime($config["entry_deadline"]);
 
          fclose($config_file);
       }
 
       //Show form for players to enter their character into competition
       function show_form()
       {
          print '<FORM action="'.$_SERVER['PHP_SELF'].'" method="post">';
          print '<TABLE>';
          print '<TR><TD>Account</TD><TD><INPUT type="text" name="account"></TD></TR>';
          print '<TR><TD>Character</TD><TD><INPUT type="text" name="character"></TD></TR>';
          print '<TR><TD>Password</TD><TD><INPUT type="text" name="pass"></TD></TR>';
          print '<TR><TD><INPUT type="submit" value="Enter!"></TD></TR>';
          print '<INPUT type="hidden" name="_check" value="1">';
          print '</FORM>';
       }
 
       //Checks if character from that account has already been entered
       function already_in($acc, $char)
       {
          global $entry_file;
          global $allow_multiple_entries;
 
          rewind($entry_file);
 
          $is_it = false;
          while(true) {
             $line = fgets($entry_file);
             if($line == null) break;
             $line = trim($line);
             if($line[0] == '#') continue;
             $acc_data = explode(' ', $line);
 
             if($allow_multiple_entries && $char === $acc_data[1]) {
                $is_it = true;
                print 'Sorry, a character '.$acc_data[1].' has already been entered into tournament!<BR>';
                break;
             } elseif(!$allow_multiple_entries && $acc === $acc_data[0]) {
                $is_it = true;
                print 'Sorry, a character from this account has already been entered into tournament!<BR>';
                break;
             }
          }
 
          return $is_it;
       }
 
       //Gets character level of experience to see which division to put it in
       function get_character_level($char_name)
       {
          return rand(1, 150);
       }
 
       function get_character_gold($char_name)
       {
          return rand(0, 1000000);
       }
 
       function get_players_fee($char_name, $fee)
       {
          return;
       }
 
       //Get info about division that player is going to be assigned to
       function div_assign($char_name)
       {
          $level = get_character_level($char_name);
 
          $div_file = fopen("data/divs.txt", "r");
          if($div_file == false) {
             die("Couldn't open file div.txt.");
          }
 
          $division = null;
          while(true) {
             $line = fgets($div_file);
             if($line == null) break;
             $line = trim($line);
             if($line[0] == '#') continue;
             $div_data = explode(' ', $line);
 
             if($level >= $div_data[1] && $level <= $div_data[2]) {
                $division = $div_data;
                break;
             }
          }
 
          if($division == null) {
             die("Could not determine which division assign the player to!");
          }
 
          return $division;
       }
 
       //Write player's entry into file
       function entry($acc, $char, $div)
       {
          global $entry_file;
 
          fseek($entry_file, 0, SEEK_END);
          fputs($entry_file, $acc." ".$char." ".$div."\n");
       }
 
    /*-----------------------------------------------------*/
       if(array_key_exists("_check", $_POST)) {
          $acc = $_POST["account"];
          $char = $_POST["character"];
          $pass = $_POST["pass"];
 
          //Load configuration
          load_config();
 
          //First check if it's before entry deadline
          if(strtotime("now") > $deadline) {
             print "Sorry, it's already too late to enter into upcoming tournament.<BR>";
             return;
          }
 
          //Check if acc name, char and pass correct
          if(check($acc, $char, $pass) == false) return;
 
          $entry_file = fopen("data/entry.txt", "r+");
          if($entry_file == false) {
             die("Could not open entry file.");
          }
 
          //See if that acc name has been posted already
          if(already_in($acc, $char)) return;
 
          //Check which division to assign the character to
          $division = div_assign($char);
 
          //Check if that character has enough gold in the bank
          if(get_character_gold($char) < $division[3]) {
             print "Sorry, but you don't have enough money in your bank.<BR>";
             print "Entry fee for ".$division[0]." division is ".(int)$division[3]." gold pieces.<BR>";
             return;
          }
 
          //Player's rich enough, tax him!
          get_players_fee($char, $division[3]);
 
          //Make entry into file
          entry($acc, $char, $division[0]);
 
          fclose($entry_file);
 
          print $char." has entered into tournament in ".$division[0]." division.<BR>";
          print "<STRONG>Good luck!</STRONG>";
 
       } else {
          show_form();
       }
    ?>
    </BODY>
 
    </HTML>

Re: Tournament script

Posted: Sat Aug 02, 2008 7:18 pm
by califdon
I'm afraid I don't have much time today, but as nobody else has yet responded to you, I'll just mention that the use of Global variables in PHP is now deprecated and it is recommended that you use Session variables instead. You should probably validate all your $_POST variables to see that they don't contain any kind of code that hackers or robots might insert. It might not be a factor in this example script, but it's a good habit to form, from the start. For an actual application, I would recommend using a database for the user and character data, but text files are fine when you're just testing the waters.

Re: Tournament script

Posted: Sun Aug 03, 2008 7:05 am
by dagothar
Thanks for reply.
I do use a database now. Would checking the values using preg_match() against any not alphanumeric character be enough to avoid danger? I assume I also have to check if strings don't exceed some specified length.
What's the most elegant and versatile way to do this actually?

Re: Tournament script

Posted: Sun Aug 03, 2008 11:39 am
by califdon
dagothar wrote:Thanks for reply.
I do use a database now. Would checking the values using preg_match() against any not alphanumeric character be enough to avoid danger? I assume I also have to check if strings don't exceed some specified length.
What's the most elegant and versatile way to do this actually?
There's no one best method, it depends on what your data is like. This could be a good place to use a function with parameters for the value being checked and what to check for, such as length and acceptable characters. There are numerous posts here and elsewhere that deal with security risks, written by others with much greater knowledge of this than I have.