50 Pound Sword (PBBG library) so far

Place to place any code snippets, completed games, or even uncompleted games for IR users to use.
Post Reply
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Ok, so I think for now I am going in another direction. However, I was somewhat proud of my registration classes, so I figure I would release them as they are, and maybe it could be the starting point for someone else, or it could be re-tooled to be the registration for your game. I don't have really any of the game-specific stuff done except a Player class, and it is far from complete. However, it does have the ability to reset the player's status in each new script (to basically "rehydrate" the player for each page). Anyway, I am releasing these scripts under the MIT license, as usual for me, so that grants broad rights to use it basically anyway you want.
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Hmm..I seem to have a problem with the script maybe being too long. I am going to have to do it in multiple parts, I guess. Just copy'n'paste them together.

Register.php (first part)

Code: Select all

<?php
    require_once "Inireader.php";
    require_once "Clean.php";

   class FiftyPound_Register {
        private $dbConn;
        private $uname;
        private $password1;
        private $password2;
        private $email;
        private $race;
        private $playerClass;
        private $securityQuestion;
        private $securityAnswer;
        private $registerResult = array();
        
        //=======================================================================
        //Constants to be used for registration data minimums and maximums.
        const EMAILMAX = 34;
        const USERNAMEMIN = 4;
        const USERNAMEMAX = 13;
        const SECURITYANSMIN = 4;
        const SECURITYANSMAX = 14;
        const PASSWORDMIN = 6;
        const PASSWORDMAX = 17;
        //=======================================================================
        
        
        /**
         *The constructor to the pbbgLib Register class, which is used to submit the data for the registration. After this info is inserted,
         *the doRegister() method is then used to actually complete the registration.
         *@param string $username The username to try to register.
         *@param string $password1 The password to try to register.
         *@param string $password2 A confirmation of the password to register.
         *@param string $email The email to try to register.
         *@param string $race The race the player wants to choose.
         *@param string $playerClass The class the players wants to be.
         *@param string $securityQuestion The security question the player chose to answer.
         *@param string $securityAnswer The answer the player gave to the security question.
         *@param array $statHolder An associative array containing the stats that the game will use.
         */
        public function __construct($username, $password1, $password2, $email, $race, $playerClass, $securityQuestion, $securityAnswer) {
            $this->uname = $username;
            $this->password1 = $password1;
            $this->password2 = $password2;
            $this->email = $email;
            $this->race = $race;
            $this->playerClass = $playerClass;
            $this->securityQuestion = $securityQuestion;
            $this->securityAnswer = $securityAnswer;
        }
        
        /**
         *The method used to perform the actual registration. It will return an associative array that contains information about the
         *resitration attempt.
         *@param resource $db The resource for the MySQLi database connection. It must be of the MySQLi type, not the old MySQL type.
         *@return array $registerResult The associative array returned from the resistration attempt.
         */
        public function doRegister($db){
            //First see if the email is empty
            if ($this->email == "") {
                $this->registerResult['code'] = 1;
                $this->registerResult['doc'] = "No email address supplied.";
                $this->registerResult['msg'] = "Please enter an email address.";
                return $this->registerResult;
            }
            
            //Check to see if the email is valid
            if (!(preg_match('^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$^', $this->email))) {
                $this->registerResult['code'] = 2;
                $this->registerResult['doc'] = "Email supplied was not correct format.";
                $this->registerResult['msg'] = "Please enter a correct email address.";
                return $this->registerResult;
            }
            
            //Check to see if either password is missing
            if ($this->password1 == "" || $this->password2 == "") {
                $this->registerResult['code'] = 5;
                $this->registerResult['doc'] = "One or both passwords missing.";
                $this->registerResult['msg'] = "Be sure to fill out both password fields.";
                return $this->registerResult;
            }
            
            //check that the email is within the right length
            if (strlen($this->email) > self::EMAILMAX) {
                $this->registerResult['code'] = 3;
                $this->registerResult['doc'] = "Email was too long for the database.";
                $this->registerResult['msg'] = "The supplied email address needs to be short than ".self::EMAILMAX." characters long.";
                return $this->registerResult;
            }
            
            //Check that both emails were entered the same.
            if (!($this->password1 == $this->password2)) {
                $this->registerResult['code'] = 4;
                $this->registerResult['doc'] = "Passwords entered did not match each other.";
                $this->registerResult['msg'] = "Both passwords must be the same.";
                return $this->registerResult;
            } 
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Register.php (second part)

Code: Select all

 //Check that the username is not too short.
            if (strlen($this->uname) < self::USERNAMEMIN) {
                $this->registerResult['code'] = 6;
                $this->registerResult['doc'] = "Username too short.";
                $this->registerResult['msg'] = "The email address must be between ".self::USERNAMEMIN." and ".self::USERNAMEMAX." characters.";
                return $this->registerResult;
            }
            
            //Check that the username is not too long.
            if (strlen($this->uname) > self::USERNAMEMAX) {
                $this->registerResult['code'] = 7;
                $this->registerResult['doc'] = "Username too long.";
                $this->registerResult['msg'] = "The email address must be between ".self::USERNAMEMIN." and ".self::USERNAMEMAX." characters.";
                return $this->registerResult;
            }
            
            //Check that the password is not too short
            if (strlen($this->password1) < self::PASSWORDMIN) {
                $this->registerResult['code'] = 8;
                $this->registerResult['doc'] = "Password is too short.";
                $this->registerResult['msg'] = "The password must be between ".self::PASSWORDMIN." and ".self::PASSWORDMAX." characters.";
                return $this->registerResult;
            }
            
            //Check that the password is not too long
            if (strlen($this->password1) > self::PASSWORDMAX) {
                $this->registerResult['code'] = 9;
                $this->registerResult['doc'] = "Password is too long.";
                $this->registerResult['msg'] = "The password must be between ".self::PASSWORDMIN." and ".self::PASSWORDMAX." characters.";
                return $this->registerResult;
            }
            
            //Check that the security question answer is not too short
            if (strlen($this->securityAnswer) < self::SECURITYANSMIN) {
                $this->registerResult['code'] = 10;
                $this->registerResult['doc'] = "Security answer is too short.";
                $this->registerResult['msg'] = "The security question answer must be between ".self::SECURITYANSMIN." and ".self::SECURITYANSMAX." characters.";
                return $this->registerResult;
            }
        
            //Check if the character name already exists, which would mean the player already exists
            $sqlquery = "SELECT username FROM users WHERE username='".$this->uname."'";
            
            $sqlresult = $db->query($sqlquery);
            $results = $sqlresult->fetch_assoc();
            if ($results['username'] == $this->uname) {
                $this->registerResult['code'] = 11;
                $this->registerResult['doc'] = "This player already exists.";
                $this->registerResult['msg'] = "There is already a player with that name.";
                return $this->registerResult;
            }
                 
            //Begin the process of entering the new player, since all of the error conditions have passed by
            //=========================================================
            
            //clean the data
            $cleaner1 = new FiftyPound_Clean($this->uname);
            $cleaner2 = new FiftyPound_Clean($this->password1);
            
            $this->uname = $cleaner1->doSqlClean($db);
            $this->password1 = $cleaner2->doSqlClean($db);
            
            //encrypt the password
            $epassword = sha1($this->password1);
            
            //First, get a list of the stat names in the game
            $iniRead = new FiftyPound_Inireader();
            $statArray = $iniRead->getStatList();
            $raceStats = $iniRead->getRaceStats($this->race);
            $classStats = $iniRead->getClassStats($this->playerClass);
             
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Register (third part: paste them all together into Register.php):

Code: Select all

//Get the final stat values
            $finalStats = array();
            for ($y = 0; $y < count($raceStats); $y++) {
                $finalStats[$y] = $raceStats[$y] + $classStats[$y];
            }
            
            //Now start forming SQL statement
            $sqlstring = "INSERT into users(username, email, password, playerclass, race, security, secanswer";
            
            //Iterate through the list of stat names and add each one into the sql statement
            for ($i = 0; $i < count($statArray); $i++) {
              $sqlstring .= ", ".$statArray[$i];
             }
            
             //enter the next part of the SQL statement
             $sqlstring .= ") VALUES ('$this->uname', '$this->email','$epassword', '$this->playerClass', '$this->race', '$this->securityQuestion','$this->securityAnswer'";
            
            //Iterate through the list of actual stats and add each to the sql statement
             for ($x = 0; $x < count($finalStats); $x++) {
                $sqlstring .= ", ".$finalStats[$x];
            }
            
            //finish the sql statement and close it
            $sqlstring .= ")";
            
            //run the query to enter the player with the assembled sql insert statement
            if ($db->query($sqlstring)) {
                $this->registerResult['code'] = 0;
                $this->registerResult['doc'] = "User entered successfully.";
                $this->registerResult['msg'] = "Registration successful!";
                return $this->registerResult;
            } else {
                $this->registerResult['code'] = 12;
                $this->registerResult['doc'] = "Problem inserting the user.";
                $this->registerResult['msg'] = "A problem occured while creating your account.";
                return $this->registerResult;
            }
            
        }
   }

 
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Login.php:

Code: Select all

<?php
    
    session_start();
    require_once "Clean.php";
    
    class FiftyPound_Login {
        
        private $uname;
        private $password;
        
        /**
         * The constructor for the login object. It takes the username and password you are trying to login.
         * @param string $username The username of the player attempting to login
         * @param string $password The password for the player. Can be SHA-1 encrypted or not.
        */
        public function __construct($username, $password) {
            $this->uname = $username;
            $this->password = $password;
        }    
        
        /**
         * The method to perform the login operation. The username and password are already loaded in from the constructor.
         * The function will load the playername into sessions to save the login.
         * @param resource $db A resource handle to the database connection. Must be MySQLi, not standard MySQL.
         * @return array loginResult An associative array containing the result of the login attempt.
        */
        public function doLogin($db) {
            //first check if the password has been encrypted or not
            if (strlen($this->password) == 40) {
                //the password has already been SHA1'd, so proceed
                //  ...empty condition...
            } else {
                //the password is in raw format, so must be SHA1'd
                $sha1d = sha1($this->password);
                $this->password = $sha1d;
            }
            
            //clean the username and password
            $cleaner1 = new FiftyPound_Clean($this->uname);
            $cleaner2 = new FiftyPound_Clean($this->password);
            
            $this->uname = $cleaner1->doSqlClean($db);
            $this->password1 = $cleaner2->doSqlClean($db);
            
            //see if the player exists in the database with the submitted password
            $sqllogin = "SELECT username FROM users WHERE username='".$this->uname."' AND password='".$this->password."'";
            
            //TESTING***********************
            echo "<br />".$sqllogin."<br />";
            
            //run the query and check the results to see if the credentials pulled up a player
            if ($resname = $db->query($sqllogin)) {
                $resulter = $resname->fetch_assoc();
                if ($resulter['username'] == $this->uname) {
                    $this->registerResult['code'] = 0;
                    $this->registerResult['doc'] = "User logged-in successfully successfully.";
                    $this->registerResult['msg'] = "Log-in successful!";
                    
                    //set the session
                    $_SESSION['username'] = $this->uname;
                    
                    //return the results of the successful login
                    return $this->registerResult;
                } else {
                    //a strange event has occured. Throw exception
                    //throw new Exception("User returned from login, but incorrect name.");
                    $this->registerResult['code'] = '1L';
                    $this->registerResult['doc'] = "User was not found in the system.";
                    $this->registerResult['msg'] = "No player found with that information.";
                    return $this->registerResult;
                }
            } else {
                $this->registerResult['code'] = '1L';
                $this->registerResult['doc'] = "User was not found in the system.";
                $this->registerResult['msg'] = "No player found with that information.";
                return $this->registerResult;
            }
              
        }
    }
    
?>
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Inireader.php (first part):

Code: Select all

<?php

    class FiftyPound_Inireader {
        private $fp;
        
        /**
         *This is the constructor for the Inireader class. It opens the
         *fiftypound.ini file for reading the values the user has entered.
         */
        public function __construct() {
            try {
                $this->fp = fopen("configuration/fiftypound.ini", "r");
            } catch (Exception $e) {
                echo "Error: ".$e->getMessage();
            }
        }
        
        /**
         *This is the method to retrieve the list of races.
         *@return array $raceList A standard array filled with the races from the ini file.
         */
        public function getRaceList() {
            //move the file pointer back to the start of the file in case it isn't there
            rewind($this->fp);
            //begin iterating through the lines in the ini file
            while (!feof($this->fp)) {
                $line = fgets($this->fp, 999);
                $first = substr($line, 0, 1);
                
                //if a line begins with ';', it is a comment and can be skipped
                if ($first == ';' || $first == ' ') {
                    continue;
                }
                
                //get the "subject" of that ini line
                $subject = substr($line, 0, 5);
                
                //if the subject is races, proceed to getting the list
                if ($subject == 'races') {
                    //split the subject name and actual list
                    $second = explode(':', $line);
                    $racesLi = $second[1];
                    
                    //turn the list of races into an array
                    $raceArray = explode(',', $racesLi);
                    
                    //trim all of the values
                    for ($d = 0; $d < count($raceArray); $d++) {
                        $raceArray[$d] = trim($raceArray[$d]);
                    }
                    
                    //return the array of races
                    return $raceArray;
                } 
            }
        }
        
        public function getClassList() {
            //move the file pointer back to the start of the file in case it isn't there
            rewind($this->fp);
            //begin iterating through the lines in the ini file
            while (!feof($this->fp)) {
                $line = fgets($this->fp, 999);
                $first = substr($line, 0, 1);
                
                //if a line begins with ';', it is a comment and can be skipped
                if ($first == ';' || $first == ' ') {
                    continue;
                }
                
                //get the "subject" of that ini line
                $subject = substr($line, 0, 7);
                
                //if the subject is classes, proceed to getting the list
                if ($subject == 'classes') {
                    //split the subject name and actual list
                    $second = explode(':', $line);
                    $classLi = $second[1];
                    
                    //turn the list of classes into an array
                    $classArray = explode(',', $classLi);
                    
                    //trim all of the values
                    for ($d = 0; $d < count($classArray); $d++) {
                        $classArray[$d] = trim($classArray[$d]);
                    }
                    
                    //return the array of classes
                    return $classArray;
                } 
            }
        }
        
        public function getStatList() {
            //move the file pointer back to the start of the file in case it isn't there
            rewind($this->fp);
            //begin iterating through the lines in the ini file
            while (!feof($this->fp)) {
                $line = fgets($this->fp, 999);
                $first = substr($line, 0, 1); 
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Inireader.php (second part: paste together into Inireader.php):

Code: Select all

//if a line begins with ';', it is a comment and can be skipped
                if ($first == ';' || $first == ' ') {
                    continue;
                }
                
                //get the "subject" of that ini line
                $subject = substr($line, 0, 5);
                
                //if the subject is stats, proceed to getting the list
                if ($subject == 'stats') {
                    //split the subject name and actual list
                    $second = explode(':', $line);
                    $statsLi = $second[1];
                    
                    //turn the list of stats into an array
                    $statsArray = explode(',', $statsLi);
                    
                    //trim all of the values
                    for ($d = 0; $d < count($statsArray); $d++) {
                        $statsArray[$d] = trim($statsArray[$d]);
                    }
                    
                    //return the array of stats
                    return $statsArray;
                } 
            }
        }
        
        public function getRaceStats($race) {
            //move the file pointer back to the start of the file in case it isn't there
            rewind($this->fp);
             //begin iterating through the lines in the ini file
            while (!feof($this->fp)) {
                $line = fgets($this->fp, 999);
                $first = substr($line, 0, 1);
                
                //if a line begins with ';', it is a comment and can be skipped
                if ($first == ';' || $first == ' ') {
                    continue;
                }
                
                //get the length of the race name to search for
                $searchLen = strlen($race);
                
                //get the "subject" of that ini line
                $subject = substr($line, 0, $searchLen);
                
                //if the subject matches the race name, proceed to getting the stats
                if ($subject == $race) {
                    //split the subject name and actual stat list
                    $second = explode(':', $line);
                    $statsLi = $second[1];
                    
                    //turn the list of stats into an array
                    $statsArray = explode(',', $statsLi);
                    
                    //trim all of the values
                    for ($d = 0; $d < count($statsArray); $d++) {
                        $statsArray[$d] = trim($statsArray[$d]);
                    }
                    
                    //return the array of stats
                    return $statsArray;
                } 
            }
        }
        
        public function getClassStats($class) {
            //move the file pointer back to the start of the file in case it isn't there
            rewind($this->fp);
             //begin iterating through the lines in the ini file
            while (!feof($this->fp)) {
                $line = fgets($this->fp, 999);
                $first = substr($line, 0, 1);
                
                //if a line begins with ';', it is a comment and can be skipped
                if ($first == ';' || $first == ' ') {
                    continue;
                }
                
                //get the length of the class name to search for
                $searchLen = strlen($class);
                
                //get the "subject" of that ini line
                $subject = substr($line, 0, $searchLen);
                
                //if the subject matches the class name, proceed to getting the stats
                if ($subject == $class) {
                    //split the subject name and actual stat list
                    $second = explode(':', $line);
                    $statsLi = $second[1];
                    
                    //turn the list of stats into an array
                    $statsArray = explode(',', $statsLi);
                    
                    //trim all of the values
                    for ($d = 0; $d < count($statsArray); $d++) {
                        $statsArray[$d] = trim($statsArray[$d]);
                    }
                    
                    //return the array of stats
                    return $statsArray;
                } 
            }
        }
        
    }

 
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Cleaner.php (incomplete: still needs more security routines added, and tighter security implemented):

Code: Select all

<?php
    class FiftyPound_Clean {
        
        private $incoming;
        
        /**
         * The constructor for the Clean class. This class will secure data incoming to the system with various different methods.
         *@param mixed $incoming The data the client needs to sanitize. 
        */
        public function __construct($incoming) {
            $this->incoming = $incoming;
        }
        
        /**
         *  This is the method for cleaning data for the database.
         * @param resource $db The link to the database. Must be MySQLi.
         * @return mixed $cleaned The returned value post-sanitizing.
        */
        public function doSqlClean($db) {
            $cleaned = $db->real_escape_string($this->incoming);
            return $cleaned;
        }
    }
    
?>
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

fiftypound.ini (needs to be in its own folder called "configuration" inside the main 5PS folder. As is, it is filled with default values):

Code: Select all

; 50 Pound Sword config file

; Enter races below. Write as a comma-separated list of races.
races: elf, orc, human, dwarf

; Enter classes below. Write as a comma-separated list of classes.
classes: mage, fighter, thief, monk

; Enter the stat names below. Write as a comma-separated list. Put in the same order as they appear in the database.
; They must also be written the same as in the database.
stats: strength, dexterity, agility, intelligence, wisdom

; These are the racial base stats. List numbers in the same order as the stats are declared above.
; race names must be entered exactly as they appear above. ex:  elf: 6, 9, 8, 10, 8
elf: 6, 9, 8, 10, 8
orc: 10, 9, 7, 6, 6
human: 8, 7, 6, 7, 6
dwarf: 9, 10, 8, 6, 6

; These are the class stat bonuses. These are added onto the racial base stats the player chooses.
; As in the racial base stats, the class names must be typed exactly as they are when declared above.
mage: 0, 0, 0, 3, 2
fighter: 2, 3, 1, 0, 0
thief: 0, 3, 2, 0, 0
monk: 2, 2, 2, 0, 0
The indelible lord of tl;dr
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: 50 Pound Sword (PBBG library) so far

Post by Jackolantern »

Player.php (incomplete. Obviously this would be a very big class to run a full-featured game since most things will deal with the player's character. Currently its only methods are "reset", which fills the player with its stat values from the db for every page it is needed on, and "getStat", which retrieves the value of a selected stat):

Code: Select all

<?php
    session_start();
    require_once "/Inireader.php";
    
    class FiftyPound_Player {
        private $statHolder;
        private $statNames;
        private $uname;
        
        /**
         * This method gets the state of the player loaded and ready for use. Pulled fresh from the db each use in case state is updated outside of the player.
         * @param resource $db The link to the database. Must be MySQLi, not standard MySQL.
         * @return bool $ready Whether or not the player was loaded. If the session is lost, the user will need to reset it.
        */
        public function reset($db) {
            //see if the player name is saved in session
            if (isset($_SESSION['username'])) {
                $this->uname = $_SESSION['username'];
            } else {
                //send false back to the client to show session data was lost and the user name must be entered, or player must relog-in
                return false;
            }
            
            //get the list of stats
            $iniobj = new FiftyPound_Inireader();
            $this->statNames = $iniobj->getStatList();
            
            //now query to get the player stat values
            $sqlplayer = "SELECT * FROM users WHERE username='".$this->uname."'";
            $result = $db->query($sqlplayer);
            $playerdata = $result->fetch_assoc();
            
            if ($playerdata['username'] == $this->uname) {
                //initialize the $statHolder array
                $this->statHolder = array();
                //begin creating $statHolder to hold an associative array of the player's stats
                for ($x = 0; $x < count($this->statNames); $x++) {
                    //$statHolder is going to hold an associative array, with each stat name being a key and
                    //  each stat value being the value.
                    $this->statHolder[$this->statNames[$x]] = $playerdata[$this->statNames[$x]];
                }
                
                return true;
         
            } else {
                return false;
            }
           
        }
        
        /**
         * Get the value of a stat. 
         * @param string $stat The name of the stat to retrieve.
         * @return int $statvalue The value of the stat found from the method. Returns -1 if $stat does not match a player stat name.
        */
        public function getStat($stat) {
            if (isset($this->statHolder[$stat])) {
                return $this->statHolder[$stat];
            } else {
                return -1;
            }
        }
    }
?>
The indelible lord of tl;dr
Post Reply

Return to “Code Sharing”