diff --git a/Admin/admin.php b/Admin/admin.php index a117db4c..b5138153 100644 --- a/Admin/admin.php +++ b/Admin/admin.php @@ -561,7 +561,7 @@ if (!empty($_GET['p'])) { { include('Templates/search.tpl'); } - if($_POST['p'] and $_POST['s']) + if(isset($_POST['p']) && isset($_POST['s']) && $_POST['p'] and $_POST['s']) { $filename = 'Templates/results_'.$_POST['p'].'.tpl'; if(file_exists($filename)) diff --git a/GameEngine/Account.php b/GameEngine/Account.php index 07c1a8f6..6ebadbfb 100755 --- a/GameEngine/Account.php +++ b/GameEngine/Account.php @@ -1,5 +1,8 @@ ]+/", $_POST['name'])) { $form->addError("name",USRNM_CHAR); } - else if($database->checkExist($_POST['name'],0)) { - $form->addError("name",USRNM_TAKEN); - } - else if($database->checkExist_activate($_POST['name'],0)) { + else if(User::exists($database,$_POST['name'])) { $form->addError("name",USRNM_TAKEN); } @@ -89,10 +89,7 @@ class Account { if(!$this->validEmail($_POST['email'])) { $form->addError("email",EMAIL_INVALID); } - else if($database->checkExist($_POST['email'],1)) { - $form->addError("email",EMAIL_TAKEN); - } - else if($database->checkExist_activate($_POST['email'],1)) { + else if(User::exists($database,$_POST['email'])) { $form->addError("email",EMAIL_TAKEN); } } @@ -190,7 +187,7 @@ class Account { if(!isset($_POST['user']) || $_POST['user'] == "") { $form->addError("user",$user); } - else if(!$database->checkExist($_POST['user'],0)) { + else if(!User::exists($database,$_POST['user'])) { $form->addError("user",USR_NT_FOUND); } if(!isset($_POST['pw']) || $_POST['pw'] == "") { diff --git a/GameEngine/Admin/Mods/addUsers.php b/GameEngine/Admin/Mods/addUsers.php index 4c6dfbb6..d0398229 100755 --- a/GameEngine/Admin/Mods/addUsers.php +++ b/GameEngine/Admin/Mods/addUsers.php @@ -8,6 +8,9 @@ ## Copyright: TravianZ (c) 2014. All rights reserved. ## ######################################################### +include_once("../../../src/Entity/User.php"); +use App\Entity\User; + include_once("../../config.php"); include_once("../../Session.php"); include_once("../../Automation.php"); @@ -78,7 +81,7 @@ else $act = ""; // Check username not already registered - if($database->checkExist($userName,0)) + if(User::exists($database, $userName)) { // Name already used, do nothing except update $skipped $skipped ++; diff --git a/GameEngine/Admin/database.php b/GameEngine/Admin/database.php index acec1327..edfd87a3 100755 --- a/GameEngine/Admin/database.php +++ b/GameEngine/Admin/database.php @@ -38,7 +38,7 @@ class adm_DB { var $connection; function __construct(){ global $database; - $database = new MYSQLi_DB; + $database = new MYSQLi_DB(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); $this->connection = $database->return_link(); } @@ -763,8 +763,8 @@ class adm_DB { for($i=0;$i<=count($cropholder)-1;$i++) { $basecrop+= $bid4[$fdata[$cropholder[$i]]]['prod']; } $crop = $basecrop + $basecrop * 0.25 * $ocounter[3]; $jcrop=0; - if($grainmill >= 1) $jcrop=$bid8[$grainmill]['attri']; - if($bakery >= 1) $jcrop+=$bid9[$bakery]['attri']; + if($grainmill >= 1) $jcrop=(isset($bid8[$grainmill]['attri']) ? $bid8[$grainmill]['attri'] : 0); + if($bakery >= 1) $jcrop+=(isset($bid9[$bakery]['attri']) ? $bid9[$bakery]['attri'] : 0); $crop += $basecrop /100 * $jcrop; if($b4 > time()) { $crop *= 1.25; diff --git a/GameEngine/Admin/function.php b/GameEngine/Admin/function.php index 56151bd5..0a3a5ced 100755 --- a/GameEngine/Admin/function.php +++ b/GameEngine/Admin/function.php @@ -20,7 +20,7 @@ class funct { function CheckLogin(){ - if($_SESSION['access'] >= MULTIHUNTER and $_SESSION['id']){ + if(isset($_SESSION['access']) && $_SESSION['access'] >= MULTIHUNTER and $_SESSION['id']){ return true; }else{ return false; @@ -212,14 +212,14 @@ class funct { $funct = new funct; if($funct->CheckLogin()){ - if($_GET['action']){ + if(isset($_GET['action']) && $_GET['action']){ $funct->Act($_GET); } - if($_POST['action']){ + if(isset($_POST['action']) && $_POST['action']){ $funct->Act2($_POST); } } -if($_POST['action']=='login'){ +if(isset($_POST['action']) && $_POST['action']=='login'){ $funct->LogIN($_POST['name'],$_POST['pw']); } ?> diff --git a/GameEngine/Alliance.php b/GameEngine/Alliance.php index 88857f7e..95ec8bf1 100755 --- a/GameEngine/Alliance.php +++ b/GameEngine/Alliance.php @@ -16,7 +16,10 @@ ## ## ################################################################################# - class Alliance { +include_once("src/Entity/User.php"); +use App\Entity\User; + +class Alliance { public $gotInvite = false; public $inviteArray = array(); @@ -114,7 +117,7 @@ $form->addError("perm", NO_PERMISSION); }elseif(!isset($post['a_name']) || $post['a_name'] == "") { $form->addError("name1", NAME_EMPTY); - }elseif(!$database->checkExist(stripslashes($post['a_name']), 0)) { + }elseif(!User::exists($database, $post['a_name'])) { $form->addError("name2", NAME_NO_EXIST."".stripslashes(stripslashes($post['a_name']))); }elseif($UserData['id'] == $session->uid) { $form->addError("name3", SAME_NAME); diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index d9139e2f..f11d5cb8 100755 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -3891,10 +3891,10 @@ $wallimg = "bountyresarray[$cropholder[$i]]]['prod']; } if($grainmill >= 1) { - $crop += $crop /100 * $bid8[$grainmill]['attri']; + $crop += $crop /100 * (isset($bid8[$grainmill]['attri']) ? $bid8[$grainmill]['attri'] : 0); } if($bakery >= 1) { - $crop += $crop /100 * $bid9[$bakery]['attri']; + $crop += $crop /100 * (isset($bid9[$bakery]['attri']) ? $bid9[$bakery]['attri'] : 0); } if($this->bountyocounter[3] != 0) { $crop += $crop*0.25*$this->bountyocounter[3]; diff --git a/GameEngine/Building.php b/GameEngine/Building.php index 6fdaf992..77ab14b6 100755 --- a/GameEngine/Building.php +++ b/GameEngine/Building.php @@ -110,7 +110,7 @@ class Building { public function canBuild($id,$tid) { global $village,$session,$database; $demolition = $database->getDemolition($village->wid); - if($demolition[0]['buildnumber']==$id) { return 11; } + if((isset($demolition[0])) && $demolition[0]['buildnumber']==$id) { return 11; } if($this->isMax($tid,$id)) { return 1; } else if($this->isMax($tid,$id,1) && ($this->isLoop($id) || $this->isCurrent($id))) { diff --git a/GameEngine/Database.php b/GameEngine/Database.php index 3c9c012a..bdeda69e 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -1,6 +1,4 @@ - dblink = mysqli_connect(SQL_SERVER, SQL_USER, SQL_PASS) or die(mysqli_error($this->dblink)); - mysqli_select_db($this->dblink, SQL_DB); - mysqli_query($this->dblink,"SET NAMES 'UTF8'"); +class MYSQLi_DB implements IDbConnection { + + private + /** + * @var string MySQL server hostname to connect to. + */ + $hostname = 'localhost', + + /** + * @var int MySQL server port to connect to. + */ + $port = 3306, + + /** + * @var string Username to authenticate with to the MySQL connection. + */ + $username = 'root', + + /** + * @var string Password to authenticate with to the MySQL connection. + */ + $password = '', + + /** + * @var string Database to use with TravianZ. + */ + $dbname = 'travian', + + /** + * @var int Counter of all SELECT queries performed. + */ + $selectQueryCount = 0, + + /** + * @var int Counter of all INSERT queries performed. + */ + $insertQueryCount = 0, + + /** + * @var int Counter of all UPDATE queries performed. + */ + $updateQueryCount = 0, + + /** + * @var int Counter of all DELETE queries performed. + */ + $deleteQueryCount = 0, + + /** + * @var int Counter of all REPLACE queries performed. + */ + $replaceQueryCount = 0; + + public $dblink; + + /** + * + * Constructor. + * Will initialize the connection to MySQL + * and die on any error it would encounter. + * + * @example $db = new MYSQLi_DB(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); + * + * @param string $hostname Hostname of the MySQL server. + * @param string $username Username to be used to to connect. + * @param string $password Password to be used to to connect. + * @param string $dbname Name of the database to use. + * @param int $port [Optional] server port to connect to. Default: 3306 + * @return void This method doesn't have a return value. + */ + public function __construct(string $hostname, string $username, string $password, string $dbname, int $port = 3306) { + $this->hostname = $hostname; + $this->port = $port; + $this->username = $username; + $this->password = $password; + $this->dbname = $dbname; + + // connect to the DB + if (!$this->connect()) { + die(mysqli_errno($this->dblink)); + } + + // we will operate in UTF8 + mysqli_query($this->dblink,"SET NAMES 'UTF8'"); + } + + /** + * {@inheritDoc} + * @see \App\Database\IDbConnection::connect() + */ + public function connect(): bool { + // try to connect + $this->dblink = mysqli_connect($this->hostname, $this->username, $this->password); + + // return on error + if (mysqli_error($this->dblink)) { + return false; + } + + // select the DB to use + mysqli_select_db($this->dblink, $this->dbname); + + // return on error + if (mysqli_error($this->dblink)) { + return false; + } else { + // connected and DB exists, we're good to go + return true; + } + } + + /** + * {@inheritDoc} + * @see \App\Database\IDbConnection::disconnect() + */ + public function disconnect(): bool { + if ($this->dblink) { + if (!$this->dblink->close()) { + return false; + } + + $this->dblink = null; + } + + return true; + } + + /** + * {@inheritDoc} + * @see \App\Database\IDbConnection::reconnect() + */ + public function reconnect(): bool { + $this->disconnect(); + return $this->connect(); + } + + /** + * {@inheritDoc} + * @see \App\Database\IDbConnection::query() + */ + public function query_new(string $statement, ...$params) { + // check for SELECT + preg_match('/[^AZ-az]*(\()?[^AZ-az]*SELECT/i', $statement, $matches); + + // SELECT statement it is... + if (count($matches)) { + if ($prep = mysqli_prepare($this->dblink, $statement)) { + // prepare all parameter types + $types = []; + + foreach ($params as $param) { + // default to string, change if neccessary + $paramType = 's'; + + if (Math::isInt($param)) { + $paramType = 'i'; + } else if (Math::isFloat($param)) { + $paramType = 'd'; + } + + $types[] = $paramType; + } + + // dynamically bind parameters + $bind_names = [implode('', $types)]; + for ($i=0; $iselectQueryCount++; + return mysqli_stmt_get_result($prep); + } else { + throw new Exception('Failed to execute an SQL statement!'); + } + } else { + throw new Exception('Failed to prepare an SQL statement!'); + } + } + + return false; + } + + /** + * {@inheritDoc} + * @see \App\Database\IDbConnection::is_connected() + */ + public function is_connected(): bool { + return ($this->dblink ? true : false); } function escape($value) { @@ -111,38 +310,6 @@ class MYSQLi_DB { return mysqli_query($this->dblink,$q); } - function checkExist($ref, $mode) { - list($ref, $mode) = $this->escape_input($ref, $mode); - - if(!$mode) { - $q = "SELECT username FROM " . TB_PREFIX . "users where username = '$ref' LIMIT 1"; - } else { - $q = "SELECT email FROM " . TB_PREFIX . "users where email = '$ref' LIMIT 1"; - } - $result = mysqli_query($this->dblink,$q); - if(mysqli_num_rows($result)) { - return true; - } else { - return false; - } - } - - function checkExist_activate($ref, $mode) { - list($ref, $mode) = $this->escape_input($ref, $mode); - - if(!$mode) { - $q = "SELECT username FROM " . TB_PREFIX . "activate where username = '$ref' LIMIT 1"; - } else { - $q = "SELECT email FROM " . TB_PREFIX . "activate where email = '$ref' LIMIT 1"; - } - $result = mysqli_query($this->dblink,$q); - if(mysqli_num_rows($result)) { - return true; - } else { - return false; - } - } - public function hasBeginnerProtection($vid) { list($vid) = $this->escape_input($vid); @@ -4205,7 +4372,7 @@ class MYSQLi_DB { for($i=0;$i<=count($cropholder)-1;$i++) { $basecrop+= $bid4[$buildarray[$cropholder[$i]]]['prod']; } $crop = $basecrop + $basecrop * 0.25 * $cropo; if($grainmill >= 1 || $bakery >= 1) { - $crop += $basecrop /100 * ($bid8[$grainmill]['attri'] + $bid9[$bakery]['attri']); + $crop += $basecrop /100 * ((isset($bid8[$grainmill]['attri']) ? $bid8[$grainmill]['attri'] : 0) + (isset($bid9[$bakery]['attri']) ? $bid9[$bakery]['attri'] : 0)); } if($bonus > time()) { $crop *= 1.25; @@ -4635,7 +4802,7 @@ References: // database is not needed if we're displaying static pages $req_file = basename($_SERVER['PHP_SELF']); if (!in_array($req_file, ['tutorial.php', 'anleitung.php'])) { - $database = new MYSQLi_DB; + $database = new MYSQLi_DB(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); $link = $database->return_link(); $GLOBALS['db'] = $database; $GLOBALS['link'] = $database->return_link(); diff --git a/GameEngine/Session.php b/GameEngine/Session.php index 040a71ed..eee5a124 100755 --- a/GameEngine/Session.php +++ b/GameEngine/Session.php @@ -1,4 +1,6 @@ diff --git a/GameEngine/Village.php b/GameEngine/Village.php index ff7905ab..c87f1906 100755 --- a/GameEngine/Village.php +++ b/GameEngine/Village.php @@ -229,7 +229,7 @@ class Village { for($i=0;$i<=count($cropholder)-1;$i++) { $basecrop+= $bid4[$this->resarray[$cropholder[$i]]]['prod']; } $crop = $basecrop + $basecrop * 0.25 * $this->ocounter[3]; if($grainmill >= 1 || $bakery >= 1) { - $crop += $basecrop /100 * ($bid8[$grainmill]['attri'] + $bid9[$bakery]['attri']); + $crop += $basecrop /100 * (isset($bid8[$grainmill]['attri']) ? $bid8[$grainmill]['attri'] : 0) + (isset($bid9[$bakery]['attri']) ? $bid9[$bakery]['attri'] : 0); } if($session->bonus4 == 1) { $crop *= 1.25; diff --git a/Templates/Alliance/invite.tpl b/Templates/Alliance/invite.tpl index 5acafa09..d32b1ee4 100644 --- a/Templates/Alliance/invite.tpl +++ b/Templates/Alliance/invite.tpl @@ -43,7 +43,7 @@ if (count($allianceInvitations) == 0) { echo ""; } else { foreach($allianceInvitations as $invit) { - $invited = $database->getUserField($invit['uid'],username,0); + $invited = $database->getUserField($invit['uid'],'username',0); echo ""; echo "\"Del\""; echo "".$invited.""; diff --git a/Templates/Ranking/overview.tpl b/Templates/Ranking/overview.tpl index 0b377983..55258dc7 100644 --- a/Templates/Ranking/overview.tpl +++ b/Templates/Ranking/overview.tpl @@ -42,7 +42,7 @@ $search = $_SESSION['search']; echo ""; } echo $i."."; - if($ranking[$i]['access'] > 2){ + if(isset($ranking[$i]['access']) && $ranking[$i]['access'] > 2){ echo"".$ranking[$i]['username'].""; } else { echo"".$ranking[$i]['username'].""; diff --git a/Templates/dorf3/3.tpl b/Templates/dorf3/3.tpl index e51856d2..60bce13c 100644 --- a/Templates/dorf3/3.tpl +++ b/Templates/dorf3/3.tpl @@ -69,7 +69,7 @@ foreach($varray as $vil){ $prod_iron += $prod_iron /100 * $bid7[$foundry]['attri']; } if ($grainmill >= 1 || $bakery >= 1) { - $prod_crop += $prod_crop /100 * ($bid8[$grainmill]['attri'] + $bid9[$bakery]['attri']); + $prod_crop += $prod_crop /100 * ((isset($bid8[$grainmill]['attri']) ? $bid8[$grainmill]['attri'] : 0) + (isset($bid9[$bakery]['attri']) ? $bid9[$bakery]['attri'] : 0)); } $oasisowned = $database->getOasis($vid); //more oasis logic required diff --git a/Templates/multivillage.tpl b/Templates/multivillage.tpl index 8848d53e..c855b823 100644 --- a/Templates/multivillage.tpl +++ b/Templates/multivillage.tpl @@ -9,7 +9,12 @@ ## ## ################################################################################# -if(count($session->villages) > 1){?> +if (!isset($id)) { + $id = ''; +} + +if(count($session->villages) > 1){ +?> villages);++$i){echo' - + '; }}?> diff --git a/build.php b/build.php index 6eecbcb1..776772d3 100644 --- a/build.php +++ b/build.php @@ -40,7 +40,7 @@ if(isset($_GET['id'])) { $_GET['id'] = "1"; } $checkBuildings = array(0,16,17,25,26,27); - if($_GET['id'] < 19 || !in_array($_GET['gid'], $checkBuildings)){ + if($_GET['id'] < 19 || (isset($_GET['gid']) && !in_array($_GET['gid'], $checkBuildings))){ $_GET['t'] = ""; $_GET['s'] = ""; } @@ -250,7 +250,7 @@ header("Location: banned.php"); exit; } } -if($_GET['mode']=='troops' && $_GET['cancel']==1){ +if(isset($_GET['mode']) && $_GET['mode']=='troops' && isset($_GET['cancel']) && $_GET['cancel']==1){ if($session->access != BANNED){ $oldmovement=$database->getMovementById($_GET['moveid']); $now=time(); @@ -367,7 +367,7 @@ if(isset($_GET['id']) or isset($_GET['gid']) or $route == 1 or isset($_GET['rout else { include("Templates/Build/".$village->resarray['f'.$_GET['id'].'t'].".tpl"); } - if($_GET['buildingFinish'] == 1) { + if((isset($_GET['buildingFinish'])) && $_GET['buildingFinish'] == 1) { if($session->gold >= 2) { $building->finishAll("build.php?gid=".$_GET['id']."&ty=".$_GET['ty']); exit; diff --git a/create_account.php b/create_account.php index 7d38a559..57b53084 100644 --- a/create_account.php +++ b/create_account.php @@ -18,7 +18,10 @@ ################################################################################# - include_once ("GameEngine/Session.php"); +include_once("src/Entity/User.php"); +use App\Entity\User; + +include_once ("GameEngine/Session.php"); include_once ("GameEngine/config.php"); @@ -493,7 +496,7 @@ if($_POST['password'] != ""){ } echo "Done"; -}elseif($database->checkExist('Natars', 0)) { +}elseif(User::exists($database,'Natars')) { ?>

Error: Natar account already exist diff --git a/src/Database/IDbConnection.php b/src/Database/IDbConnection.php new file mode 100644 index 00000000..8e1c6682 --- /dev/null +++ b/src/Database/IDbConnection.php @@ -0,0 +1,74 @@ + SELECT statements will return a mysqli_result + * -> INSERT, UPDATE, DELETE, REPLACE statements will return an integer + * (last insert ID for INSERTs, number of affected rows for everything else) + * + * @example $dbConnection->query("SELECT id FROM ".TB_PREFIX."users WHERE email = ? AND activated = ?", "my@mail.com", 1); + * @example $dbConnection->query("UPDATE ".TB_PREFIX."users SET name = ? WHERE id = ?", "John Doe", 1); + * @example $dbConnection->query("INSERT INTO ".TB_PREFIX."users (name, email) VALUES (?, ?)", "John Doe", "john@doe.com"); + * @example $dbConnection->query("REPLACE INTO ".TB_PREFIX."users (name, email) VALUES (?, ?)", "John Doe", "john@doe.com"); + * @example $dbConnection->query("DELETE FROM ".TB_PREFIX."users WHERE id IN(?, ?, ?)", 1, 2 3); + * + * @param string $statement The query to prepare and execute. + * @param mixed ...$params Parameters for the query. These usually come from user via POST or GET requests. + * @return mixed Returns either a mysqli_result or a number. If number is returned, it will be last insert ID + * for INSERTs or number of affected rows for anything else. + */ + public function query_new(string $statement, ...$params); +} + diff --git a/src/Entity/User.php b/src/Entity/User.php new file mode 100644 index 00000000..70b96b7b --- /dev/null +++ b/src/Entity/User.php @@ -0,0 +1,116 @@ +id = $identifier; + } else { + $this->username = $identifier; + } + + $this->db = $database; + } + + /** + * Checks whether username or e-mail already exists in the database. + * + * @param IDbConnection $db The current database connection. + * @param string $value Value to check names and emails for. + * @return boolean Returns true if the value exists in database, + * false otherwise. + */ + public static function exists(IDbConnection $db, string $value) { + $sql = '( + SELECT + Count(*) AS in_users + FROM + '.TB_PREFIX.'users + WHERE + username = ? OR email = ? + ) + UNION ALL + ( + SELECT + Count(*) AS in_act + FROM + '.TB_PREFIX.'activate + WHERE + username = ? OR email = ? + )'; + + $res = $db->query_new($sql, $value, $value, $value, $value); + + // convert result into an array + $res = mysqli_fetch_array($res, MYSQLI_NUM); + + return ($res[0] > 0 || $res[1] > 0); + } +} \ No newline at end of file diff --git a/src/Utils/Math.php b/src/Utils/Math.php new file mode 100644 index 00000000..8807b52b --- /dev/null +++ b/src/Utils/Math.php @@ -0,0 +1,34 @@ +

:
('.$returnVillageArray[$i-1]['x'].'
|
'.$returnVillageArray[$i-1]['y'].')