diff --git a/GameEngine/Account.php b/GameEngine/Account.php index 79099dd0..3e66f78b 100755 --- a/GameEngine/Account.php +++ b/GameEngine/Account.php @@ -17,384 +17,264 @@ use App\Entity\User; ## ## ################################################################################# -/* -========================================================= -= AUTOLOADER DISCOVERY -========================================================= -*/ - global $autoprefix; +// go max 5 levels up - we don't have folders that go deeper than that $autoprefix = ''; - for ($i = 0; $i < 5; $i++) { - $autoprefix = str_repeat('../', $i); - - if (file_exists($autoprefix . 'autoloader.php')) { + if (file_exists($autoprefix.'autoloader.php')) { + // we have our path, let's leave break; } } -include_once($autoprefix . "GameEngine/Session.php"); +include_once($autoprefix."GameEngine/Session.php"); +class Account { -/* -========================================================= -= ACCOUNT CLASS -========================================================= -*/ + function __construct() { + global $session; + if(isset($_POST['ft'])) { + switch($_POST['ft']) { + case "a1": + $this->Signup(); + break; + case "a2": + $this->Activate(); + break; + case "a3": + $this->Unreg(); + break; + case "a4": + $this->Login(); + break; + } + } if(isset($_GET['code'])) { + $_POST['id'] = $_GET['code']; $this->Activate(); + } + else { + if($session->logged_in && in_array("logout.php",explode("/",$_SERVER['PHP_SELF']))) { + $this->Logout(); + } + } + } -class Account -{ - /* - ===================================================== - = CONSTRUCTOR / REQUEST ROUTER - ===================================================== - */ - - public function __construct() - { - global $session; - - if (isset($_POST['ft'])) { - - switch ($_POST['ft']) { - - case "a1": - $this->Signup(); - break; - - case "a2": - $this->Activate(); - break; - - case "a3": - $this->Unreg(); - break; - - case "a4": - $this->Login(); - break; + private function Signup() { + global $database,$form,$mailer,$generator,$session; + if(!isset($_POST['name']) || trim($_POST['name']) == "") { + $form->addError("name",USRNM_EMPTY); + } + else { + if(strlen($_POST['name']) < USRNM_MIN_LENGTH) { + $form->addError("name",USRNM_SHORT); + } + else if(!USRNM_SPECIAL && preg_match('/[^0-9A-Za-z]/',$_POST['name'])) { + $form->addError("name",USRNM_CHAR); + } + else if(USRNM_SPECIAL && preg_match("/[:,\\. \\n\\r\\t\\s\\<\\>]+/", $_POST['name'])) { + $form->addError("name",USRNM_CHAR); + } + else if(strtolower($_POST['name']) == 'natars') { + $form->addError("name",USRNM_TAKEN); } - } + else if(User::exists($database,$_POST['name'])) { + $form->addError("name",USRNM_TAKEN); + } - elseif (isset($_GET['code'])) { - - $_POST['id'] = $_GET['code']; - $this->Activate(); - } - - elseif ( - $session->logged_in && - in_array("logout.php", explode("/", $_SERVER['PHP_SELF'])) - ) { - $this->Logout(); - } - } - - - /* - ===================================================== - = SIGNUP - ===================================================== - */ - - private function Signup() - { - global $database, $form, $mailer, $generator; - - /* - ------------------------------------------------- - USERNAME VALIDATION - ------------------------------------------------- - */ - - if (empty($_POST['name'])) { - - $form->addError("name", USRNM_EMPTY); - - } else { - - if (strlen($_POST['name']) < USRNM_MIN_LENGTH) - $form->addError("name", USRNM_SHORT); - - elseif (!USRNM_SPECIAL && preg_match('/[^0-9A-Za-z]/', $_POST['name'])) - $form->addError("name", USRNM_CHAR); - - elseif (USRNM_SPECIAL && - preg_match("/[:,\\. \\n\\r\\t\\s\\<\\>]+/", $_POST['name'])) - $form->addError("name", USRNM_CHAR); - - elseif (strtolower($_POST['name']) == 'natars') - $form->addError("name", USRNM_TAKEN); - - elseif (User::exists($database, $_POST['name'])) - $form->addError("name", USRNM_TAKEN); - } - - - /* - ------------------------------------------------- - PASSWORD VALIDATION - ------------------------------------------------- - */ - - if (empty($_POST['pw'])) { - - $form->addError("pw", PW_EMPTY); - - } else { - - if (strlen($_POST['pw']) < PW_MIN_LENGTH) - $form->addError("pw", PW_SHORT); - - elseif ($_POST['pw'] == $_POST['name']) - $form->addError("pw", PW_INSECURE); - } - - - /* - ------------------------------------------------- - EMAIL VALIDATION - ------------------------------------------------- - */ - - if (!isset($_POST['email'])) { - - $form->addError("email", EMAIL_EMPTY); - - } else { - - if (!$this->validEmail($_POST['email'])) - $form->addError("email", EMAIL_INVALID); - - elseif (User::exists($database, $_POST['email'])) - $form->addError("email", EMAIL_TAKEN); - } - - - /* - ------------------------------------------------- - TRIBE & AGREEMENT VALIDATION - ------------------------------------------------- - */ - - if (!isset($_POST['vid']) || !in_array($_POST['vid'], [1,2,3])) - $form->addError("tribe", TRIBE_EMPTY); - - if (!isset($_POST['agb'])) - $form->addError("agree", AGREE_ERROR); - - - /* - ------------------------------------------------- - ERROR HANDLING - ------------------------------------------------- - */ - - if ($form->returnErrors() > 0) { + } + if(!isset($_POST['pw']) || trim($_POST['pw']) == "") { + $form->addError("pw",PW_EMPTY); + } + else { + if(strlen($_POST['pw']) < PW_MIN_LENGTH) { + $form->addError("pw",PW_SHORT); + } + else if($_POST['pw'] == $_POST['name']) { + $form->addError("pw",PW_INSECURE); + } + } + if(!isset($_POST['email'])) { + $form->addError("email",EMAIL_EMPTY); + } + else { + if(!$this->validEmail($_POST['email'])) { + $form->addError("email",EMAIL_INVALID); + } + else if(User::exists($database,$_POST['email'])) { + $form->addError("email",EMAIL_TAKEN); + } + } + if(!isset($_POST['vid']) || !in_array($_POST['vid'], [1, 2, 3])) { + $form->addError("tribe",TRIBE_EMPTY); + } + if(!isset($_POST['agb'])) { + $form->addError("agree",AGREE_ERROR); + } + if($form->returnErrors() > 0) { + $form->addError("invt",$_POST['invited']); $_SESSION['errorarray'] = $form->getErrors(); $_SESSION['valuearray'] = $_POST; + header("Location: anmelden.php"); exit; } + else { + if(AUTH_EMAIL){ + $act = $generator->generateRandStr(10); + $act2 = $generator->generateRandStr(5); + $uid = $database->activate($_POST['name'],password_hash($_POST['pw'], PASSWORD_BCRYPT,['cost' => 12]),$_POST['email'],$_POST['vid'],$_POST['kid'],$act,$act2); + if($uid) { + $mailer->sendActivate($_POST['email'],$_POST['name'],$_POST['pw'],$act); + header("Location: activate.php?id=$uid&q=$act2"); + exit; + } + } + else { + $uid = $database->register($_POST['name'], password_hash($_POST['pw'], PASSWORD_BCRYPT, ['cost' => 12]), $_POST['email'], $_POST['vid'], $act); + if($uid) { + setcookie("COOKUSR" , $_POST['name'], time() + COOKIE_EXPIRE,COOKIE_PATH); + setcookie("COOKEMAIL" , $_POST['email'], time() + COOKIE_EXPIRE,COOKIE_PATH); + $database->updateUserField( + $uid, + ["act", "invited"], + ["", $_POST['invited']], + 1 + ); - /* - ------------------------------------------------- - REGISTRATION FLOW - ------------------------------------------------- - */ + $this->generateBase($_POST['kid'], $uid, $_POST['name']); + header("Location: login.php"); + exit; + } + } + } + } - if (AUTH_EMAIL) { + private function Activate() { + global $database; + + if(START_DATE < date('d.m.Y') or START_DATE == date('d.m.Y') && START_TIME <= date('H:i')) + { + $q = "SELECT act, username, password, email, tribe, location FROM ".TB_PREFIX."activate where act = '".$database->escape($_POST['id'])."'"; + $result = mysqli_query($database->dblink,$q); + $dbarray = mysqli_fetch_array($result); + if($dbarray['act'] == $_POST['id']) { + $uid = $database->register($dbarray['username'], $dbarray['password'], $dbarray['email'], $dbarray['tribe'], ""); + if($uid) { + $database->unreg($dbarray['username']); + $this->generateBase($dbarray['location'],$uid,$dbarray['username']); + header("Location: activate.php?e=2"); + exit; + } + } + else + { + header("Location: activate.php?e=3"); + exit; + } + } + else + { + header("Location: activate.php"); + exit; + } + } - $act = $generator->generateRandStr(10); - $act2 = $generator->generateRandStr(5); + private function Unreg() { + global $database; + + $q = "SELECT password, username FROM ".TB_PREFIX."activate where id = ".(int) $_POST['id']; + $result = mysqli_query($database->dblink,$q); + $dbarray = mysqli_fetch_array($result); + if(password_verify($_POST['pw'], $dbarray['password'])) { + $database->unreg($dbarray['username']); + header("Location: anmelden.php"); + exit; + } + else { + header("Location: activate.php?e=3"); + exit; + } + } - $uid = $database->activate( - $_POST['name'], - password_hash($_POST['pw'], PASSWORD_BCRYPT, ['cost'=>12]), - $_POST['email'], - $_POST['vid'], - $_POST['kid'], - $act, - $act2 - ); + private function Login() { + global $database, $session, $form; + + $user = $_POST['user']; + if(!isset($_POST['user']) || empty($_POST['user'])){ + $form->addError("user", $user); + }else if(!User::exists($database, $_POST['user'])){ + $form->addError("user", USR_NT_FOUND); + } + if(!isset($_POST['pw']) || empty($_POST['pw'])){ + $form->addError("pw", LOGIN_PASS_EMPTY); + }else if(!$database->login($_POST['user'], $_POST['pw']) && !$database->sitterLogin($_POST['user'], $_POST['pw'])){ + // try activation data if the user was not found + if(!$userData){ + $activateData = $database->getActivateField($_POST['user'], 'act', 1); + + if(!empty($activateData)) $form->addError("activate", $_POST['user']); + + else $form->addError("pw", LOGIN_PW_ERROR); + } + else $form->addError("pw", LOGIN_PW_ERROR); + } - if ($uid) { + $userData = $database->getUserArray($_POST['user'], 0); + + // Vacation mode by Shadow + if($userData["vac_mode"] == 1 && $userData["vac_time"] > time()){ + $form->addError("vacation", "Vacation mode is still enabled"); + } + + // Vacation mode by Shadow + if($form->returnErrors() > 0){ + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $_POST; + + header("Location: login.php"); + exit(); + }else{ + // Vacation mode by Shadow + $database->removevacationmode($userData['id']); + // Vacation mode by Shadow + if($database->login($_POST['user'], $_POST['pw'])){ + $database->UpdateOnline("login", $_POST['user'], time(), $userData['id']); + }else if($database->sitterLogin($_POST['user'], $_POST['pw'])){ + $database->UpdateOnline("sitter", $_POST['user'], time(), $userData['id']); + } + setcookie("COOKUSR", $_POST['user'], time() + COOKIE_EXPIRE, COOKIE_PATH); + $session->login($_POST['user']); + } + } - $mailer->sendActivate( - $_POST['email'], - $_POST['name'], - $_POST['pw'], - $act - ); + private function Logout() { + global $session, $database; + + unset($_SESSION['wid']); + $database->activeModify(addslashes($session->username),1); + $database->UpdateOnline("logout") or die(mysqli_error($database->dblink)); + $session->Logout(); + } - header("Location: activate.php?id=$uid&q=$act2"); - exit; - } - - } else { - - $uid = $database->register( - $_POST['name'], - password_hash($_POST['pw'], PASSWORD_BCRYPT, ['cost'=>12]), - $_POST['email'], - $_POST['vid'], - "" - ); - - if ($uid) { - - setcookie("COOKUSR", $_POST['name'], time()+COOKIE_EXPIRE, COOKIE_PATH); - setcookie("COOKEMAIL", $_POST['email'], time()+COOKIE_EXPIRE, COOKIE_PATH); - - $database->updateUserField( - $uid, - ["act", "invited"], - ["", $_POST['invited']], - 1 - ); - - $this->generateBase($_POST['kid'], $uid, $_POST['name']); - - header("Location: login.php"); - exit; - } - } - } - - - /* - ===================================================== - = LOGIN - ===================================================== - */ - - private function Login() - { - global $database, $session, $form; - - if (empty($_POST['user'])) - $form->addError("user", LOGIN_USER_EMPTY); - - elseif (!User::exists($database, $_POST['user'])) - $form->addError("user", USR_NT_FOUND); - - if (empty($_POST['pw'])) - $form->addError("pw", LOGIN_PASS_EMPTY); - - elseif ( - !$database->login($_POST['user'], $_POST['pw']) && - !$database->sitterLogin($_POST['user'], $_POST['pw']) - ) - $form->addError("pw", LOGIN_PW_ERROR); - - $userData = $database->getUserArray($_POST['user'], 0); - - if ($userData["vac_mode"] == 1 && $userData["vac_time"] > time()) - $form->addError("vacation", "Vacation mode is still enabled"); - - if ($form->returnErrors() > 0) { - - $_SESSION['errorarray'] = $form->getErrors(); - $_SESSION['valuearray'] = $_POST; - - header("Location: login.php"); - exit; - } - - /* - ------------------------------------------------- - SUCCESS LOGIN FLOW - ------------------------------------------------- - */ - - $database->removevacationmode($userData['id']); - - if ($database->login($_POST['user'], $_POST['pw'])) - $database->UpdateOnline("login", $_POST['user'], time(), $userData['id']); - - elseif ($database->sitterLogin($_POST['user'], $_POST['pw'])) - $database->UpdateOnline("sitter", $_POST['user'], time(), $userData['id']); - - setcookie("COOKUSR", $_POST['user'], time()+COOKIE_EXPIRE, COOKIE_PATH); - - $session->login($_POST['user']); - } - - - /* - ===================================================== - = LOGOUT - ===================================================== - */ - - private function Logout() - { - global $session, $database; - - unset($_SESSION['wid']); - - $database->activeModify(addslashes($session->username), 1); - $database->UpdateOnline("logout"); - - $session->Logout(); - } - - - /* - ===================================================== - = EMAIL VALIDATOR - ===================================================== - */ - - private function validEmail($email) - { - $regexp = "/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i"; - return preg_match($regexp, $email); - } - - - /* - ===================================================== - = BASE GENERATION - ===================================================== - */ - - function generateBase($kid, $uid, $username) - { - global $database; - - $message = new Message(); - - if ($kid == 0) - $kid = rand(1,4); - else - $kid = $_POST['kid']; - - $database->generateVillages( - [[ - 'wid' => 0, - 'mode' => 0, - 'type' => 3, - 'kid' => $kid, - 'capital' => 1, - 'pop' => 2, - 'name' => null, - 'natar' => 0 - ]], - $uid, - $username - ); - - $message->sendWelcome($uid, $username); - } -} + private function validEmail($email) { + $regexp="/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i"; + return preg_match($regexp, $email); + } + function generateBase($kid, $uid, $username) { + global $database; + $message = new Message(); + + if($kid == 0) $kid = rand(1,4); + else $kid = $_POST['kid']; + + $database->generateVillages([['wid' => 0, 'mode' => 0, 'type' => 3, 'kid' => $kid, 'capital' => 1, 'pop' => 2, 'name' => null, 'natar' => 0]], $uid, $username); + $message->sendWelcome($uid, $username); + } +}; $account = new Account; ?> - diff --git a/GameEngine/Alliance.php b/GameEngine/Alliance.php index 158b2f1c..5ee3dc77 100755 --- a/GameEngine/Alliance.php +++ b/GameEngine/Alliance.php @@ -16,25 +16,20 @@ ## ## ################################################################################# - -/* -========================================================= -= AUTOLOADER DISCOVERY -========================================================= -*/ +use App\Entity\User; global $autoprefix; +// even with autoloader created, we can't use it here yet, as it's not been created +// ... so, let's see where it is and include it $autoloader_found = false; +// go max 5 levels up - we don't have folders that go deeper than that $autoprefix = ''; - for ($i = 0; $i < 5; $i++) { - $autoprefix = str_repeat('../', $i); - - if (file_exists($autoprefix . 'autoloader.php')) { + if (file_exists($autoprefix.'autoloader.php')) { $autoloader_found = true; - include_once $autoprefix . 'autoloader.php'; + include_once $autoprefix.'autoloader.php'; break; } } @@ -43,409 +38,585 @@ if (!$autoloader_found) { die('Could not find autoloading class.'); } +class Alliance { -/* -========================================================= -= ALLIANCE DOMAIN CONTROLLER -========================================================= -*/ + public $gotInvite = false; + public $inviteArray = []; + public $allianceArray = []; + public $userPermArray = []; + + public function procAlliance($get) { + global $session, $database; -class Alliance -{ - /* - ===================================================== - = PROPERTIES - ===================================================== - */ + if($session->alliance > 0) { + $this->allianceArray = $database->getAlliance($session->alliance); + // Permissions Array + // [id] => id [uid] => uid [alliance] => alliance [opt1] => X [opt2] => X [opt3] => X [opt4] => X [opt5] => X [opt6] => X [opt7] => X [opt8] => X + $this->userPermArray = $database->getAlliPermissions($session->uid, $session->alliance); + } else { + $this->inviteArray = $database->getInvitation($session->uid); + $this->gotInvite = count($this->inviteArray) > 0; + } + + if(isset($get['a'])) { + switch($get['a']) { + case 2: + $this->rejectInvite($get); + break; + case 3: + $this->acceptInvite($get); + break; + } + } + if(isset($get['o'])) { + switch($get['o']) { + case 4: + $this->delInvite($get); + break; + } + } + } + + /** + * Determines if a forum is accessible or not + * + * @param int $forumID The forum ID + * @return bool Returns if the forum is accessible or not + */ + + public function isForumAccessible($forumID){ + global $session; + + //Loop through the shared forums and try to find the passed one + foreach($session->sharedForums as $forums){ + foreach($forums as $forum){ + if($forum['id'] == $forumID) return true; + } + } + return false; + } + + /** + * Determines if a player can act with the forum (edit/delete/create things, etc.) + * + * @param array $datas The array which contains: [aid, alliance, forum_perm, admin, owner, forum_owner] + * @return bool Returns true if you are able to act, false otherwise + */ + + public static function canAct($datas, $mode = 0){ + global $database, $session; - public $gotInvite = false; - public $inviteArray = []; - public $allianceArray = []; - public $userPermArray = []; + $hasSwitchedToAdmin = isset($datas['admin']) && !empty($datas['admin']) && $datas['admin'] == "switch_admin"; + return (/*$database->CheckEditRes($datas['aid']) == 1 && */($datas['alliance'] > 0 && (($database->isAllianceOwner($session->uid) == $datas['alliance'] || + ($datas['forum_perm'] == 1 && $session->alliance == $datas['alliance']))) || + ($datas['owner'] == $session->uid && $session->access != ADMIN)) || + ($session->access == ADMIN)) && + ($mode || $hasSwitchedToAdmin); + } + + /** + * Create two string, representing alliances ID and users ID which can see a specific forum + * + * @param int $alliancesID A list of alliances ID + * @param int $alliancesName A list of alliances Name + * @param int $usersID A list of users ID + * @param int $usersName A list of users name + * @return array Returns the two string, composed by alliances ID and users ID + */ + + public function createForumVisiblity($alliancesID, $alliancesName, $usersID, $usersName){ + global $database, $session; + + $alliances = $users = []; + //TODO: Reduce the code of this part and cache existing diplomacy relationship + //Deduplicate alliances + if(!empty($alliancesID)){ + foreach($alliancesID as $alliance){ + if(!empty($alliance) && is_numeric($alliance) && $database->aExist($alliance, 'id') && $alliance != $session->alliance && empty($database->diplomacyExistingRelationships($alliance))){ + $alliances[$alliance] = true; + } + } + } + if(!empty($alliancesName)){ + foreach($alliancesName as $alliance){ + if(!empty($alliance) && !empty($allianceID = $database->getAllianceID($alliance)) && $allianceID != $session->alliance && empty($database->diplomacyExistingRelationships($allianceID))){ + $alliances[$allianceID] = true; + } + } + } + + //Deduplicate users + if(!empty($usersID)){ + foreach($usersID as $user) { + if(!empty($user) && is_numeric($user) && ($userAlly = $database->getUserAllianceID($user)) > 0 && $userAlly != $session->alliance && $database->getUserField($user, 'username', 0) != "[?]" && $user != $session->uid && empty($database->diplomacyExistingRelationships($userAlly))) { + $users[$user] = true; + } + } + } + if(!empty($usersName)){ + foreach($usersName as $user){ + if(!empty($user) && !empty($userID = $database->getUserField($user, 'id', 1)) && $userID != $session->uid && ($userAlly = $database->getUserAllianceID($userID)) > 0 && $userAlly != $session->alliance && empty($database->diplomacyExistingRelationships($userAlly))) { + $users[$userID] = true; + } + } + } + + return ['alliances' => implode(',', array_keys($alliances)), 'users' => implode(',', array_keys($users))]; + } + + /** + * Redirects to the forum selection + * + * @param array $get Contains the values of a GET request + */ + + public function redirect($get = null) + { + header("Location: allianz.php?s=2".(isset($get['fid']) && !empty($get['fid']) && $get['admin'] != 'pos' ? "&fid=".$get['fid']."" : ""). + (isset($get['admin']) && !empty($get['admin']) ? "&admin=switch_admin" : "")); + exit; + } + + public function procAlliForm($post) { + if(isset($post['ft'])) { + switch($post['ft']) { + case "ali1": + $this->createAlliance($post); + break; + } - /* - ===================================================== - = INITIAL PROCESSOR - ===================================================== - */ + } + + if(isset($post['dipl']) && isset($post['a_name'])) $this->changediplomacy($post); - public function procAlliance($get) - { - global $session, $database; + if(isset($post['s'])) { + if(isset($post['o'])) { + switch($post['o']) { + case 1: + if(isset($_POST['a'])) $this->changeUserPermissions($post); + break; + case 2: + if(isset($_POST['a_user'])) $this->kickAlliUser($post); + break; + case 4: + if(isset($_POST['a']) && $_POST['a'] == 4) $this->sendInvite($post); + break; + case 3: + $this->updateAlliProfile($post); + break; + case 11: + $this->quitally($post); + break; + case 100: + $this->changeAliName($post); + break; + } + } + } + } - /* - ------------------------------------------------- - LOAD ALLIANCE OR INVITES - ------------------------------------------------- - */ + /***************************************** + Function to process of sending invitations + *****************************************/ + public function sendInvite($post) { + global $form, $database, $session; - if ($session->alliance > 0) { - - $this->allianceArray = $database->getAlliance($session->alliance); - $this->userPermArray = $database->getAlliPermissions( - $session->uid, - $session->alliance - ); - - } else { - - $this->inviteArray = $database->getInvitation($session->uid); - $this->gotInvite = count($this->inviteArray) > 0; - } - - /* - ------------------------------------------------- - INVITE ACTIONS - ------------------------------------------------- - */ - - if (isset($get['a'])) { - - switch ($get['a']) { - - case 2: - $this->rejectInvite($get); - break; - - case 3: - $this->acceptInvite($get); - break; - } - } - - /* - ------------------------------------------------- - OWNER ACTIONS - ------------------------------------------------- - */ - - if (isset($get['o'])) { - - if ($get['o'] == 4) { - $this->delInvite($get); - } - } - } - - - /* - ===================================================== - = FORUM ACCESS CONTROL - ===================================================== - */ - - public function isForumAccessible($forumID) - { - global $session; - - foreach ($session->sharedForums as $forums) { - foreach ($forums as $forum) { - if ($forum['id'] == $forumID) { - return true; + $UserData = $database->getUserArray(stripslashes($post['a_name']), 0); + if($this->userPermArray['opt4'] == 0) { + $form->addError("name", NO_PERMISSION); + }elseif(!isset($post['a_name']) || $post['a_name'] == "") { + $form->addError("name", NAME_EMPTY); + }elseif(!User::exists($database, $post['a_name'])) { + $form->addError("name", NAME_NO_EXIST."".stripslashes(stripslashes($post['a_name']))); + }elseif($UserData['id'] == $session->uid) { + $form->addError("name", SAME_NAME); + }elseif($database->getInvitation2($UserData['id'],$session->alliance)) { + $form->addError("name", $post['a_name'].ALREADY_INVITED); + }elseif($UserData['alliance'] == $session->alliance) { + $form->addError("name", $post['a_name'].ALREADY_IN_ALLY); + }elseif($UserData['alliance'] > 0) { + $form->addError("name", $post['a_name'].ALREADY_IN_AN_ALLY); + }else{ + // Obtenemos la informacion necesaria + $aid = $session->alliance; + // Insertamos invitacion + $database->sendInvitation($UserData['id'], $aid, $session->uid); + // Log the notice + $database->insertAlliNotice($session->alliance, '' . addslashes($session->username) . ' has invited ' . addslashes($UserData['username']) . ' into the alliance.'); + // send invitation via in-game messages + if(NEW_FUNCTIONS_ALLIANCE_INVITATION){ + $database->sendMessage( + $UserData['id'], + 4, + 'Invitation to Alliance', + $database->escape("Hi, ".$UserData['username']."!\n\nThis is to inform you that you have been invited to join an alliance. To accept this invitation, please visit your Embassy.\n\nYours sincerely,\nServer Robot :)"), + 0, + 0, + 0, + 0, + 0, + true); } - } - } + } + } - return false; - } + /***************************************** + Function to reject an invitation + *****************************************/ + private function rejectInvite($get) { + global $database, $session; + foreach($this->inviteArray as $invite) { + if($invite['id'] == $get['d'] && $invite['uid'] == $session->uid) { + $database->removeInvitation($get['d']); + $database->insertAlliNotice($invite['alliance'], ''.addslashes($session->username).' has rejected the invitation.'); + } + } + header("Location: build.php?gid=18"); + exit; + } - /* - ===================================================== - = PERMISSION CHECKER - ===================================================== - */ + /***************************************** + Function to del an invitation + *****************************************/ + private function delInvite($get) { + global $database, $session; - public static function canAct($datas, $mode = 0) - { - global $database, $session; + $inviteArray = $database->getAliInvitations($session->alliance); + foreach($inviteArray as $invite) { + if($invite['id'] == $get['d'] && $invite['alliance'] == $session->alliance && $this->userPermArray['opt4'] == 1) { + $invitename = $database->getUserArray($invite['uid'], 1); + $database->removeInvitation($get['d']); + $database->insertAlliNotice($session->alliance, ''.addslashes($session->username).' has deleted the invitation for '.addslashes($invitename['username']).'.'); + } + } + header("Location: allianz.php?delinvite"); + exit; + } - $hasSwitchedToAdmin = - isset($datas['admin']) && - $datas['admin'] == "switch_admin"; + /***************************************** + Function to accept an invitation + *****************************************/ + private function acceptInvite($get) { + global $form, $database, $session; - return ( - ( - $datas['alliance'] > 0 && - ( - $database->isAllianceOwner($session->uid) == $datas['alliance'] || - ($datas['forum_perm'] == 1 && - $session->alliance == $datas['alliance']) - ) - ) || - ($datas['owner'] == $session->uid && $session->access != ADMIN) || - ($session->access == ADMIN) - ) && ($mode || $hasSwitchedToAdmin); - } + foreach ($this->inviteArray as $invite) { + if ($session->alliance == 0) { + if ($invite['id'] == $get['d'] && $invite['uid'] == $session->uid) { + $memberlist = $database->getAllMember($invite['alliance']); + $alliance_info = $database->getAlliance($invite['alliance']); + if (count($memberlist) < $alliance_info['max']) { + $database->removeInvitation($get['d']); + $database->updateUserField($invite['uid'], "alliance", $invite['alliance'], 1); + $database->createAlliPermissions($invite['uid'], $invite['alliance'], '', 0, 0, 0, 0, 0, 0, 0, 0); + // Log the notice + $database->insertAlliNotice($invite['alliance'], ''.addslashes($session->username).' has joined the alliance.'); + } else { + $accept_error = 1; + $max = $alliance_info['max']; + } + } + } + } + + if($accept_error == 1) $form->addError("ally_accept", "The alliance can contain only ".$max." members at this moment."); + else + { + header("Location: build.php?gid=18"); + exit; + } + } + /***************************************** + Function to create an alliance + *****************************************/ + private function createAlliance($post) { + global $form, $database, $session, $bid18, $building; - /* - ===================================================== - = FORUM VISIBILITY BUILDER - ===================================================== - */ + if(!isset($post['ally1']) || $post['ally1'] == "") { + $form->addError("ally1", ATAG_EMPTY); + } + if(!isset($post['ally2']) || $post['ally2'] == "") { + $form->addError("ally2", ANAME_EMPTY); + } + if($database->aExist($post['ally1'], "tag")) { + $form->addError("ally1", ATAG_EXIST); + } + if($database->aExist($post['ally2'], "name")) { + $form->addError("ally2", ANAME_EXIST); + } + if($session->alliance != 0){ + $form->addError("ally3", ALREADY_ALLY_MEMBER); + } + if($building->getTypeLevel(18) < 3){ + $form->addError("ally4", ALLY_TOO_LOW); + } + if($form->returnErrors() != 0) { + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $post; + if($building->getTypeLevel(18) > 0) header("Location: build.php?gid=18"); + else header("Location: dorf2.php"); + exit; + } else { + $max = $bid18[$building->getTypeLevel(18)]['attri']; + $aid = $database->createAlliance($post['ally1'], $post['ally2'], $session->uid, $max); + $database->updateUserField($session->uid, "alliance", $aid, 1); + $database->procAllyPop($aid); + // Asign Permissions + $database->createAlliPermissions($session->uid, $aid, 'Alliance founder', '1', '1', '1', '1', '1', '1', '1', '1'); + // log the notice + $database->insertAlliNotice($aid, 'The alliance has been founded by '.addslashes($session->username).'.'); + header("Location: build.php?gid=18"); + exit; + } + } - public function createForumVisiblity( - $alliancesID, - $alliancesName, - $usersID, - $usersName - ) - { - global $database, $session; + /***************************************** + Function to change the alliance name + *****************************************/ + private function changeAliName($get) { + global $form, $database, $session; + + $userAlly = $database->getAlliance($session->alliance); + + if(!isset($get['ally1']) || $get['ally1'] == "") $form->addError("ally1", ATAG_EMPTY); + + if(!isset($get['ally2']) || $get['ally2'] == "") $form->addError("ally2", ANAME_EMPTY); + + if($get['ally1'] != $userAlly['tag'] && $database->aExist($get['ally1'], "tag")) $form->addError("ally1", ATAG_EXIST); + + if($get['ally2'] != $userAlly['name'] && $database->aExist($get['ally2'], "name")) $form->addError("ally2", ANAME_EXIST); + + if($this->userPermArray['opt3'] == 0) $form->addError("perm", NO_PERMISSION); + + if($form->returnErrors() == 0) { + $database->setAlliName($session->alliance, $get['ally2'], $get['ally1']); + // log the notice + $database->insertAlliNotice($session->alliance, ''.addslashes($session->username).' has changed the alliance name.'); + $form->addError("perm", NAME_OR_TAG_CHANGED); + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $get; + header("Location: allianz.php?s=5"); + exit; + } + } - $alliances = []; - $users = []; + /***************************************** + Function to create/change the alliance description + *****************************************/ + private function updateAlliProfile($post) { + global $database, $session, $form; - /* - ------------------------------------------------- - DEDUPLICATE ALLIANCES - ------------------------------------------------- - */ + if($this->userPermArray['opt3'] == 0) { + $form->addError("perm", NO_PERMISSION); + } + if($form->returnErrors() > 0) { + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $post; + } else { + $database->submitAlliProfile($session->alliance, $post['be2'], $post['be1']); + // log the notice + $database->insertAlliNotice($session->alliance, ''.addslashes($session->username).' has changed the alliance description.'); + } + } - if (!empty($alliancesID)) { + /***************************************** + Function to change the user permissions + *****************************************/ + private function changeUserPermissions($post) + { + global $database, $session, $form; - foreach ($alliancesID as $alliance) { + if($this->userPermArray['opt1'] == 0) $form->addError("perm", NO_PERMISSION); + elseif($database->getUserField($post['a_user'], "alliance", 0) != $session->alliance) $form->addError("perm", USER_NOT_IN_YOUR_ALLY); + elseif($post['a_user'] == $session->uid) $form->addError("perm", CANT_EDIT_YOUR_PERMISSIONS); + elseif($database->isAllianceOwner($_POST['a_user'])) $form->addError("perm", CANT_EDIT_LEADER_PERMISSIONS); + else + { + $database->updateAlliPermissions($post['a_user'], $session->alliance, $post['a_titel'], $post['e1'], $post['e2'], $post['e3'], $post['e4'], $post['e5'], $post['e6'], $post['e7']); + // log the notice + $database->insertAlliNotice($session->alliance, ''.addslashes($session->username).' has changed permissions of '.addslashes($database->getUserField($post['a_user'], "username", 0)).'.'); + $form->addError("perm", ALLY_PERMISSIONS_UPDATED); + } + + if($form->returnErrors() > 0) + { + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $post; + header("Location: allianz.php?s=5"); + exit; + } + } + /***************************************** + Function to kick a user from alliance + *****************************************/ + private function kickAlliUser($post) { + global $database, $session, $form; - if ( - !empty($alliance) && - is_numeric($alliance) && - $database->aExist($alliance, 'id') && - $alliance != $session->alliance && - empty($database->diplomacyExistingRelationships($alliance)) - ) { - $alliances[$alliance] = true; - } - } - } + $UserData = $database->getUserArray($post['a_user'], 1); + if($this->userPermArray['opt2'] == 0) { + $form->addError("perm", NO_PERMISSION); + } else if($database->getUserField($post['a_user'], "alliance", 0) != $session->alliance){ + $form->addError("perm", USER_NOT_IN_YOUR_ALLY); + } else if($UserData['id'] != $session->uid){ + $database->updateUserField($post['a_user'], 'alliance', 0, 1); + $database->deleteAlliPermissions($post['a_user']); + $database->deleteAlliance($session->alliance); + // log the notice + $database->insertAlliNotice($session->alliance, ''.($kickedUsername = addslashes($database->getUserField($post['a_user'], "username", 0))).' has been expelled from the alliance by '.addslashes($session->username).'.'); + if($session->alliance && $database->isAllianceOwner($UserData['id']) == $session->alliance){ + $newowner = $database->getAllMember2($session->alliance); + $newleader = $newowner['id']; + $q = "UPDATE " . TB_PREFIX . "alidata set leader = ".(int) $newleader." where id = ".(int) $session->alliance.""; + $database->query($q); + $database->updateAlliPermissions($newleader, 1, 1, 1, 1, 1, 1, 1, 1, 1); + Automation::updateMax($newleader); + } + $form->addError("perm", $kickedUsername.ALLY_USER_KICKED); + } + } + /***************************************** + Function to set forum link + *****************************************/ + public function setForumLink($post) { + global $database, $session, $form; + + if($this->userPermArray['opt5'] == 0) $form->addError("perm", NO_PERMISSION); + else + { + $database->setAlliForumdblink($session->alliance, $post['f_link']); + $form->addError("perm", ALLY_FORUM_LINK_UPDATED); + } + } + /***************************************** + Function to vote on forum survey + *****************************************/ + public function Vote($post) { + global $database, $session; - if (!empty($alliancesName)) { + if($database->checkSurvey($post['tid']) && !$database->checkVote($post['tid'], $session->uid)){ + $survey = $database->getSurvey($post['tid']); + $text = ''.$survey['voted'].','.$session->uid.','; + $database->Vote($post['tid'], $post['vote'], $text); + } + header("Location: allianz.php?s=2&fid2=".$post['fid2']."&tid=".$post['tid']); + exit; + } + /***************************************** + Function to quit from alliance + *****************************************/ + private function quitally($post) { + global $database, $session, $form; - foreach ($alliancesName as $alliance) { + if(!isset($post['pw']) || $post['pw'] == "") { + $form->addError("pw", PW_EMPTY); + } elseif(!password_verify($post['pw'], $session->userinfo['password'])) { + $form->addError("pw", LOGIN_PW_ERROR); + } else { + // check whether this is not the founder leaving and if he is, see whether + // his replacement has been selected + if ( + $session->alliance && + $database->isAllianceOwner($session->uid) == $session->alliance && + $database->countAllianceMembers($session->alliance) > 1 + ) { + // check that we have a valid new founder + if (!isset($post['new_founder'])) { + $form->addError("founder", 'Founder was not selected.'); + return; + } else { + $post['new_founder'] = (int) $post['new_founder']; + } - $allianceID = $database->getAllianceID($alliance); + $members = $database->getAllMember($session->alliance); + $validMemberFound = false; - if ( - !empty($allianceID) && - $allianceID != $session->alliance && - empty($database->diplomacyExistingRelationships($allianceID)) - ) { - $alliances[$allianceID] = true; - } - } - } + foreach ($members as $member) { + if ($member['id'] == $post['new_founder']) { + $validMemberFound = true; + break; + } + } - /* - ------------------------------------------------- - DEDUPLICATE USERS - ------------------------------------------------- - */ + if (!$validMemberFound || $post['new_founder'] == $session->uid) { + $form->addError("founder", 'Invalid founder.'); + return; + } - if (!empty($usersID)) { + $newleader = (int) $post['new_founder']; + $q = "UPDATE " . TB_PREFIX . "alidata set leader = ".$newleader." where id = ".(int) $session->alliance; + $_SESSION['alliance_user'] = 0; + $database->query($q); + $database->createAlliPermissions($newleader, $session->alliance, 'Alliance Leader', 1, 1, 1, 1, 1, 1, 1, 1); + Automation::updateMax($newleader); - foreach ($usersID as $user) { + // send the new founder an in-game message, notifying them of their election + $database->sendMessage( + $newleader, + 4, + 'You are now leader of your alliance', + "Hi!\n\nThis is to inform you that the former leader of your alliance - ".$database->escape($session->username).", has decided to quit and elected you as his replacement. You now gain full access, administration and responsibilities to your alliance.\n\nGood luck!\n\nYours sincerely,\nServer Robot :)", + 0, + 0, + 0, + 0, + 0, + true); + } - $userAlly = $database->getUserAllianceID($user); + $database->updateUserField($session->uid, 'alliance', 0, 1); + $database->deleteAlliPermissions($session->uid); + // log the notice + $database->deleteAlliance($session->alliance); + $database->insertAlliNotice($session->alliance, '' . addslashes($session->username) . ' has quit the alliance.'); + header("Location: spieler.php?uid=".$session->uid); + exit; + } + } - if ( - !empty($user) && - is_numeric($user) && - $userAlly > 0 && - $userAlly != $session->alliance && - $user != $session->uid && - empty($database->diplomacyExistingRelationships($userAlly)) - ) { - $users[$user] = true; - } - } - } + private function changediplomacy($post) { + global $database, $session, $form; - if (!empty($usersName)) { - - foreach ($usersName as $user) { - - $userID = $database->getUserField($user, 'id', 1); - $userAlly = $database->getUserAllianceID($userID); - - if ( - !empty($userID) && - $userID != $session->uid && - $userAlly > 0 && - $userAlly != $session->alliance && - empty($database->diplomacyExistingRelationships($userAlly)) - ) { - $users[$userID] = true; - } - } - } - - return [ - 'alliances' => implode(',', array_keys($alliances)), - 'users' => implode(',', array_keys($users)) - ]; - } - - - /* - ===================================================== - = REDIRECTION HANDLER - ===================================================== - */ - - public function redirect($get = null) - { - header( - "Location: allianz.php?s=2" . - (isset($get['fid']) && $get['admin'] != 'pos' - ? "&fid=" . $get['fid'] - : "" - ) . - (isset($get['admin']) - ? "&admin=switch_admin" - : "" - ) - ); - exit; - } - - - /* - ===================================================== - = ALLIANCE FORM PROCESSOR - ===================================================== - */ - - public function procAlliForm($post) - { - if (isset($post['ft']) && $post['ft'] == "ali1") { - $this->createAlliance($post); - } - - if (isset($post['dipl'], $post['a_name'])) { - $this->changediplomacy($post); - } - - if (isset($post['s'], $post['o'])) { - - switch ($post['o']) { - - case 1: - if (isset($post['a'])) - $this->changeUserPermissions($post); - break; - - case 2: - if (isset($post['a_user'])) - $this->kickAlliUser($post); - break; - - case 3: - $this->updateAlliProfile($post); - break; - - case 4: - if ($post['a'] == 4) - $this->sendInvite($post); - break; - - case 11: - $this->quitally($post); - break; - - case 100: - $this->changeAliName($post); - break; - } - } - } - - - /* - ===================================================== - = INVITATION MANAGEMENT - ===================================================== - */ - - public function sendInvite($post) - { - global $form, $database, $session; - - $UserData = $database->getUserArray( - stripslashes($post['a_name']), - 0 - ); - - if ($this->userPermArray['opt4'] == 0) - $form->addError("name", NO_PERMISSION); - - elseif (!User::exists($database, $post['a_name'])) - $form->addError("name", NAME_NO_EXIST); - - elseif ($UserData['alliance'] > 0) - $form->addError("name", ALREADY_IN_AN_ALLY); - - else { - - $database->sendInvitation( - $UserData['id'], - $session->alliance, - $session->uid - ); - - $database->insertAlliNotice( - $session->alliance, - '' . - addslashes($session->username) . - ' has invited ' . - addslashes($UserData['username']) . - '.' - ); - } - } - - /* - ===================================================== - = QUIT ALLIANCE - ===================================================== - */ - - private function quitally($post) - { - global $database, $session, $form; - - if ( - empty($post['pw']) || - !password_verify($post['pw'], $session->userinfo['password']) - ) { - $form->addError("pw", LOGIN_PW_ERROR); - return; - } - - $database->updateUserField($session->uid, 'alliance', 0, 1); - $database->deleteAlliPermissions($session->uid); - - $database->insertAlliNotice( - $session->alliance, - '' . - addslashes($session->username) . - ' has quit the alliance.' - ); - - header("Location: spieler.php?uid=" . $session->uid); - exit; - } + if($this->userPermArray['opt6'] == 1){ + if(!empty($post['a_name']) || !empty($post['dipl'])){ + $aName = $post['a_name']; + $aType = (int)intval($post['dipl']); + if($database->aExist($aName, "tag")) { + $allianceID = $database->getAllianceID($aName); + if($allianceID != $session->alliance) { + if($aType >= 1 and $aType <= 3) { + if(!$database->diplomacyInviteCheck2($session->alliance, $allianceID)) { + if($database->diplomacyCheckLimits($session->alliance, $aType)){ + $database->diplomacyInviteAdd($session->alliance, $allianceID, $aType); + if($aType == 1){ + $notice = OFFERED_CONFED_TO; + }else if($aType == 2){ + $notice = OFFERED_NON_AGGRESION_PACT_TO; + }else if($aType == 3){ + $notice = DECLARED_WAR_ON; + } + $database->insertAlliNotice($session->alliance, ''.$database->getAllianceName($session->alliance).' '.$notice.' '.$aName.'.'); + $database->insertAlliNotice($allianceID, ''.$database->getAllianceName($session->alliance).' '.$notice.' '.$aName.'.'); + $form->addError("name", INVITE_SENT); + + } + else $form->addError("name", ALLY_TOO_MUCH_PACTS); + } + else $form->addError("name", INVITE_ALREADY_SENT); + } + else $form->addError("name", WRONG_DIPLOMACY); + } + else $form->addError("name", CANNOT_INVITE_SAME_ALLY); + } + else $form->addError("name", ALLY_DOESNT_EXISTS); + } + else $form->addError("name", NAME_OR_DIPL_EMPTY); + } + else $form->addError("name", NO_PERMISSION); + } } - -/* -========================================================= -= INSTANTIATION -========================================================= -*/ - $alliance = new Alliance; ?> - diff --git a/GameEngine/Artifacts.php b/GameEngine/Artifacts.php index 194369bc..c005d218 100644 --- a/GameEngine/Artifacts.php +++ b/GameEngine/Artifacts.php @@ -1,318 +1,527 @@ - [["type" => 1, "size" => 1, "name" => ARCHITECTS_SMALL, "vname" => ARCHITECTS_SMALLVILLAGE, "effect" => "(4x)", "quantity" => 6, "img" => 2], + ["type" => 1, "size" => 2, "name" => ARCHITECTS_LARGE, "vname" => ARCHITECTS_LARGEVILLAGE, "effect" => "(3x)", "quantity" => 4, "img" => 2], + ["type" => 1, "size" => 3, "name" => ARCHITECTS_UNIQUE,"vname" => ARCHITECTS_UNIQUEVILLAGE, "effect" => "(5x)", "quantity" => 1, "img" => 2]], + + HASTE_DESC => [["type" => 2, "size" => 1, "name" => HASTE_SMALL, "vname" => HASTE_SMALLVILLAGE, "effect" => "(2x)", "quantity" => 6, "img" => 4], + ["type" => 2, "size" => 2, "name" => HASTE_LARGE, "vname" => HASTE_LARGEVILLAGE, "effect" => "(1.5x)", "quantity" => 4, "img" => 4], + ["type" => 2, "size" => 3, "name" => HASTE_UNIQUE, "vname" => HASTE_UNIQUEVILLAGE, "effect" => "(3x)", "quantity" => 1, "img" => 4]], + + EYESIGHT_DESC => [["type" => 3, "size" => 1, "name" => EYESIGHT_SMALL, "vname" => EYESIGHT_SMALLVILLAGE, "effect" => "(5x)", "quantity" => 6, "img" => 5], + ["type" => 3, "size" => 2, "name" => EYESIGHT_LARGE, "vname" => EYESIGHT_LARGEVILLAGE, "effect" => "(3x)", "quantity" => 4, "img" => 5], + ["type" => 3, "size" => 3, "name" => EYESIGHT_UNIQUE, "vname" => EYESIGHT_UNIQUEVILLAGE, "effect" => "(10x)", "quantity" => 1, "img" => 5]], + + DIET_DESC => [["type" => 4, "size" => 1, "name" => DIET_SMALL, "vname" => DIET_SMALLVILLAGE, "effect" => "(50%)", "quantity" => 6, "img" => 6], + ["type" => 4, "size" => 2, "name" => DIET_LARGE, "vname" => DIET_LARGEVILLAGE, "effect" => "(25%)", "quantity" => 4, "img" => 6], + ["type" => 4, "size" => 3, "name" => DIET_UNIQUE, "vname" => DIET_UNIQUEVILLAGE, "effect" => "(50%)", "quantity" => 1, "img" => 6]], + + ACADEMIC_DESC => [["type" => 5, "size" => 1, "name" => ACADEMIC_SMALL, "vname" => ACADEMIC_SMALLVILLAGE, "effect" => "(50%)", "quantity" => 6, "img" => 8], + ["type" => 5, "size" => 2, "name" => ACADEMIC_LARGE, "vname" => ACADEMIC_LARGEVILLAGE, "effect" => "(25%)", "quantity" => 4, "img" => 8], + ["type" => 5, "size" => 3, "name" => ACADEMIC_UNIQUE, "vname" => ACADEMIC_UNIQUEVILLAGE, "effect" => "(50%)", "quantity" => 1, "img" => 8]], + + STORAGE_DESC => [["type" => 6, "size" => 1, "name" => STORAGE_SMALL, "vname" => STORAGE_SMALLVILLAGE, "effect" => "(50%)", "quantity" => 6, "img" => 9], + ["type" => 6, "size" => 2, "name" => STORAGE_LARGE, "vname" => STORAGE_LARGEVILLAGE, "effect" => "(25%)", "quantity" => 4, "img" => 9]], + + CONFUSION_DESC => [["type" => 7, "size" => 1, "name" => CONFUSION_SMALL, "vname" => CONFUSION_SMALLVILLAGE, "effect" => "(200)", "quantity" => 6, "img" => 10], + ["type" => 7, "size" => 2, "name" => CONFUSION_LARGE, "vname" => CONFUSION_LARGEVILLAGE, "effect" => "(100)", "quantity" => 4, "img" => 10], + ["type" => 7, "size" => 3, "name" => CONFUSION_UNIQUE, "vname" => CONFUSION_UNIQUEVILLAGE, "effect" => "(500)", "quantity" => 1, "img" => 10]], + + FOOL_DESC => [["type" => 8, "size" => 1, "name" => FOOL_SMALL, "vname" => FOOL_SMALLVILLAGE, "effect" => "", "quantity" => 10, "img" => "fool"], + 2 => ["type" => 8, "size" => 3, "name" => FOOL_UNIQUE, "vname" => FOOL_UNIQUEVILLAGE, "effect" => "", "quantity" => 1, "img" => "fool"]]], + + /** + * @var array WW building plans Natars' artifacts + */ + + NATARS_WW_BUILDING_PLANS = [PLAN_DESC => [["type" => 11, "size" => 1, "name" => PLAN, "vname" => PLANVILLAGE, "effect" => "", "quantity" => 13, "img" => 1]]], + + /** + * @var array Natars' normal artifacts buildings + */ + + NATARS_ARTIFACTS_BUILDINGS = [ + //Treasury of the 20th level, Residence of the 10th level, Rally Point of the 1th level + "f22t" => 27, "f22" => 20, "f28t" => 25, "f28" => 10, "f39t" => 16, "f39" => 1, + //18 Cranny of the 10th level + "f19t" => 23, "f19" => 10, "f20t" => 23, "f20" => 10, "f21t" => 23, "f21" => 10, + "f23t" => 23, "f23" => 10, "f24t" => 23, "f24" => 10, "f25t" => 23, "f25" => 10, + "f26t" => 23, "f26" => 10, "f27t" => 23, "f27" => 10, "f29t" => 23, "f29" => 10, + "f30t" => 23, "f30" => 10, "f31t" => 23, "f31" => 10, "f32t" => 23, "f32" => 10, + "f33t" => 23, "f33" => 10, "f34t" => 23, "f34" => 10, "f35t" => 23, "f35" => 10, + "f36t" => 23, "f36" => 10, "f37t" => 23, "f37" => 10, "f38t" => 23, "f38" => 10], + + + /** + * @var array Natars' WW villages buildings + */ + + NATARS_WW_VILLAGES_BUILDINGS = [ + //WW of the 0th level, Main Building of the 10th level, Marketplace of the 1th level + "f99t" => 40, "f99" => 0, "f22t" => 15, "f22" => 10, "f34t" => 17, "f34" => 1, + //Warehouse of the 20th & 10th level, Granary of the 20th & 10th level + "f20t" => 10, "f20" => 20, "f19t" => 10, "f19" => 10, "f23t" => 11, "f23" => 20, "f27t" => 11, "f27" => 10, + //All Woodcutter of the 5th level + "f1" => 5, "f3" => 5, "f14" => 5, "f17" => 5, + //All Clay Pit of the 5th level + "f5" => 5, "f6" => 5, "f16" => 5, "f18" => 5, + //All Iron Mine of the 5th level + "f4" => 5, "f7" => 5, "f10" => 5, "f11" => 5, + //All Cropland of the 6th level + "f2" => 6, "f8" => 6, "f9" => 6, "f12" => 6, "f13" => 6, "f15" => 6], + + /** + * @var int The base amount of Natars' spying units, used when Natars account is created + */ + + NATARS_BASE_SPY = 1500, - /* - ===================================================== - = NATARS WORLD CONFIGURATION - ===================================================== - */ - - const NATARS_BASE_SPY = 1500; - const NATARS_BASE_WW_VILLAGES = 13; - - /* - ===================================================== - = NATARS CAPITAL POSSIBLE LOCATIONS - ===================================================== - */ - - const NATARS_CAPITAL_COORDINATES = [ - [WORLD_MAX, WORLD_MAX], - [WORLD_MAX, 0], - [WORLD_MAX, -WORLD_MAX], - [0, -WORLD_MAX], - [-WORLD_MAX, -WORLD_MAX], - [-WORLD_MAX, 0], - [-WORLD_MAX, WORLD_MAX], - [0, WORLD_MAX], - [WORLD_MAX / 10, WORLD_MAX / 20], - [WORLD_MAX / 10, -WORLD_MAX / 10], - [-WORLD_MAX / 20, -WORLD_MAX / 10], - [-WORLD_MAX / 10, 0], - [-WORLD_MAX / 20, WORLD_MAX / 10] - ]; - - - /* - ===================================================== - = DYNAMIC TROOP GENERATORS - ===================================================== - */ - - public $natarsArtifactsUnits; - public $natarsWWVillagesUnits; - public function __construct() - { - /* - ------------------------------------------------- - ARTIFACT VILLAGE TROOPS - ------------------------------------------------- - */ - - $this->natarsArtifactsUnits = function ($multiplier) { - - return [ - 41 => rand(1000*$multiplier, 2000*$multiplier) * NATARS_UNITS, - 42 => rand(1500*$multiplier, 2000*$multiplier) * NATARS_UNITS, - 43 => rand(2300*$multiplier, 2800*$multiplier) * NATARS_UNITS, - 44 => rand(25*$multiplier, 75*$multiplier) * NATARS_UNITS, - 45 => rand(1200*$multiplier, 1900*$multiplier) * NATARS_UNITS, - 46 => rand(1500*$multiplier, 2000*$multiplier) * NATARS_UNITS, - 47 => rand(500*$multiplier, 900*$multiplier) * NATARS_UNITS, - 48 => rand(100*$multiplier, 300*$multiplier) * NATARS_UNITS, - 49 => rand(1*$multiplier, 5*$multiplier) * NATARS_UNITS, - 50 => rand(1*$multiplier, 5*$multiplier) * NATARS_UNITS - ]; + /** + * @var int the base amount of Natars' WW villages + */ + + NATARS_BASE_WW_VILLAGES = 13; + + public + + /** + * @var funct Natars' troops for normal artifact + */ + + $natarsArtifactsUnits, + + /** + * @var funct WW villages Natars' troops + */ + + $natarsWWVillagesUnits; + + public function __construct(){ + + $this->natarsArtifactsUnits = function($multiplier){ + return [41 => rand(1000 * $multiplier, 2000 * $multiplier) * NATARS_UNITS, + 42 => rand(1500 * $multiplier, 2000 * $multiplier) * NATARS_UNITS, + 43 => rand(2300 * $multiplier, 2800 * $multiplier) * NATARS_UNITS, + 44 => rand(25 * $multiplier, 75 * $multiplier) * NATARS_UNITS, + 45 => rand(1200 * $multiplier, 1900 * $multiplier) * NATARS_UNITS, + 46 => rand(1500 * $multiplier, 2000 * $multiplier) * NATARS_UNITS, + 47 => rand(500 * $multiplier, 900 * $multiplier) * NATARS_UNITS, + 48 => rand(100 * $multiplier, 300 * $multiplier) * NATARS_UNITS, + 49 => rand(1 * $multiplier, 5 * $multiplier) * NATARS_UNITS, + 50 => rand(1 * $multiplier, 5 * $multiplier) * NATARS_UNITS]; }; - - /* - ------------------------------------------------- - WW VILLAGE TROOPS - ------------------------------------------------- - */ - - $this->natarsWWVillagesUnits = function () { - - return [ - 41 => rand(500, 12000) * NATARS_UNITS, - 42 => rand(1000, 14000) * NATARS_UNITS, - 43 => rand(2000, 16000) * NATARS_UNITS, - 44 => rand(100, 500) * NATARS_UNITS, - 45 => rand(480, 17000) * NATARS_UNITS, - 46 => rand(600, 18000) * NATARS_UNITS, - 47 => rand(2000, 16000) * NATARS_UNITS, - 48 => rand(400, 2000) * NATARS_UNITS, - 49 => rand(40, 200) * NATARS_UNITS, - 50 => rand(50, 250) * NATARS_UNITS - ]; + + $this->natarsWWVillagesUnits = function(){ + return [41 => rand(500, 12000) * NATARS_UNITS, + 42 => rand(1000 , 14000) * NATARS_UNITS, + 43 => rand(2000, 16000) * NATARS_UNITS, + 44 => rand(100, 500) * NATARS_UNITS, + 45 => rand(480, 17000) * NATARS_UNITS, + 46 => rand(600, 18000) * NATARS_UNITS, + 47 => rand(2000, 16000) * NATARS_UNITS, + 48 => rand(400, 2000) * NATARS_UNITS, + 49 => rand(40, 200) * NATARS_UNITS, + 50 => rand(50, 250) * NATARS_UNITS]; }; + } - - - /* - ===================================================== - = NATARS ACCOUNT CREATION - ===================================================== - */ - - public function createNatars() - { + + /** + * Called when Natars account needs to be created, creates his account and capital village + * + */ + + public function createNatars(){ global $database; - + + //Register the Natars account, the Natars' password is the same as the MH's one $password = $database->getUserField(5, 'password', 0); - - $database->register( - TRIBE5, - $password, - self::NATARS_EMAIL, - self::NATARS_TRIBE, - null, - self::NATARS_UID, - self::NATARS_DESC - ); - + $database->register(TRIBE5, $password, self::NATARS_EMAIL, self::NATARS_TRIBE, null, self::NATARS_UID, self::NATARS_DESC); + + //Convert from coordinates to village IDs $possibleWids = $database->getVilWrefs(self::NATARS_CAPITAL_COORDINATES); - $wid = $database->getFreeVillage($possibleWids); + + //Check if the villages aren't already taken + $wid = $database->getFreeVillage($possibleWids); - $wid = $database->generateVillages( - [[ - 'wid' => $wid, - 'mode' => 2, - 'type' => 3, - 'kid' => 0, - 'capital' => 1, - 'pop' => 834, - 'name' => null, - 'natar' => 0 - ]], - self::NATARS_UID, - TRIBE5 - ); + //Generate the Natars' capital + $wid = $database->generateVillages([['wid' => $wid, 'mode' => 2, 'type' => 3, 'kid' => 0, 'capital' => 1, 'pop' => 834, 'name' => null, 'natar' => 0]], self::NATARS_UID, TRIBE5); + //Scouts all players $this->scoutAllPlayers($wid); + + //Add artifacts $this->addArtifactVillages(self::NATARS_ARTIFACTS); } - - - /* - ===================================================== - = ACTIVATE ARTIFACTS ENGINE - ===================================================== - */ - - public function activateArtifacts() - { + + /** + * Called when Natars account has been created + * + * @param int $wid The village ID of the Natars' capital + */ + + public function scoutAllPlayers($wid){ + global $database; + + $array = $database->getProfileVillages(0, 1); + $refs = []; + $vils = []; + + foreach($array as $vill){ + $refs[] = $database->addAttack($wid, 0, 0, 0, self::NATARS_BASE_SPY * NATARS_UNITS, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 0); + $vils[] = $vill['wref']; + } + + $type = []; + $from = []; + $to = []; + $ref = []; + $time = []; + $timeValue = time(); + $endtime = []; + $endtimeValue = $timeValue + round(10000 / SPEED); + $counter = 0; + + foreach ($refs as $index => $refID) { + $type[] = 3; + $from[] = $wid; + $to[] = $vils[$index]; + $ref[] = $refID; + $time[] = $timeValue; + $endtime[] = $endtimeValue; + + // limit the insert, so it can push through any reasonable network limits imposed + if (++$counter > 25) { + $database->addMovement($type, $from, $to, $ref, $time, $endtime); + + $type = []; + $from = []; + $to = []; + $ref = []; + $time = []; + $endtime = []; + $counter = 0; + } + } + + if ($counter > 0) $database->addMovement($type, $from, $to, $ref, $time, $endtime); + } + + /** + * Creates villages and puts the desired artifacts in it + * + * @param array $artifactArrays The array containing the artifacts to insert + * @param int $uid The owner's user ID (Natars) + * @param bool $addTroops Add troops to the village if true, and vice versa if false + */ + + public function addArtifactVillages($artifactArrays, $uid = self::NATARS_UID, $addTroops = true) { global $database; - $activationTime = 86400 / ( - SPEED == 2 ? 1.5 : - (SPEED == 3 ? 2 : SPEED) - ); - - $artifacts = $database->getInactiveArtifacts( - round(time() - $activationTime) - ); - - if (empty($artifacts)) { - return; + //Variables initialization + $artifactNumber = 0; + $artifactVillages = $artifactTroops = $artifactBuildings = $artifactsToAdd = $wids = []; + + //Create the artifact villages array + foreach($artifactArrays as $desc => $artifactType){ + foreach($artifactType as $artifact){ + for($i = 0; $i < $artifact['quantity']; $i++){ + //Generate the villages array + $artifactVillages[] = ['wid' => 0, 'mode' => $artifact['size'] + 1, 'type' => 3, 'kid' => rand(1, 4), 'capital' => 0, 'pop' => 163, 'name' => $artifact['vname'], 'natar' => 0]; + + //Set the unit arrays (1, 2 or 4) + $multiplier = $artifact['size'] == 3 ? 4 : $artifact['size']; + $unitArrays = ($this->natarsArtifactsUnits)($multiplier); + + //Generate the unit arrays + if($addTroops) $artifactTroops[1][] = array_values($unitArrays); + $artifactBuildings[1][] = array_values(self::NATARS_ARTIFACTS_BUILDINGS); + + //Generate the artifacts array + $artifactsToAdd[] = ['owner' => $uid, 'type' => $artifact['type'], 'size' => $artifact['size'], + 'name' => $artifact['name'], 'desc' => $desc, 'effect' => $artifact['effect'], + 'img' => "type".$artifact['img'].".gif"]; + } + } + } + + //Set the unit types by using the last $unitArrays + if($addTroops) $artifactTroops[0] = array_keys($unitArrays); + $artifactBuildings[0] = array_keys(self::NATARS_ARTIFACTS_BUILDINGS); + + //Generate the wids + $wids = array_merge($wids, (array)$database->generateVillages($artifactVillages, $uid, TRIBE5, $addTroops ? $artifactTroops : null, $artifactBuildings)); + + //Create the artifacts for the generated wids + $database->addArtefacts($wids, $artifactsToAdd); + } + + /** + * Called when WW villages need to be created + * + * @param int $numberOfVillages The number of villages that have to be added + * @param int $uid The player ID + * @param bool $addTroops Add troops to the village if true, and vice versa if false + */ + + public function createWWVillages($numberOfVillages = self::NATARS_BASE_WW_VILLAGES, $uid = self::NATARS_UID, $addTroops = true){ + global $database; + + $villageArrays = $troopArrays = $buildingArrays = $wids = []; + for($i = 1; $i <= $numberOfVillages; $i++){ + $villageArrays[] = ['wid' => 0, 'mode' => 5, 'type' => 3, 'kid' => ($i == $numberOfVillages ? rand(1, 4) : ($i % 4) + 1), 'capital' => 0, 'pop' => 233, 'name' => WWVILLAGE, 'natar' => 1]; + if($addTroops) $troopArrays[1][] = array_values(($this->natarsWWVillagesUnits)()); + $buildingArrays[1][] = array_values(self::NATARS_WW_VILLAGES_BUILDINGS); } - /* - ------------------------------------------------- - GROUP BY OWNER - ------------------------------------------------- - */ - - $grouped = []; - - foreach ($artifacts as $artifact) { - $grouped[$artifact['owner']][] = $artifact; - } - - /* - ------------------------------------------------- - PROCESS PER OWNER - ------------------------------------------------- - */ - - foreach ($grouped as $owner => $inactiveArtifacts) { - - $ownArtifacts = $database->getOwnArtifactsSum($owner, true); - - foreach ($inactiveArtifacts as $artifact) { - - if ($ownArtifacts['totals'] < 3) { - - $database->activateArtifact($artifact['id']); - $ownArtifacts['totals']++; - + if($addTroops) $troopArrays[0] = array_keys(($this->natarsWWVillagesUnits)()); + $buildingArrays[0] = array_keys(self::NATARS_WW_VILLAGES_BUILDINGS); + + $wids = $database->generateVillages($villageArrays, $uid, null, $addTroops ? $troopArrays : null, $buildingArrays); + } + + /** + * Called when WW building plans need to be created + * + */ + + public function createWWBuildingPlans(){ + + //Add the artifacts and villages + $this->addArtifactVillages(self::NATARS_WW_BUILDING_PLANS); + } + + /** + * Automatically activate all artifacts that need to be activated + * + */ + + public function activateArtifacts(){ + global $database; + + //Get all inactive artifacts that have to be activated --> (24 hours / Speed of the server) + $time = time(); + $artifacts = $database->getInactiveArtifacts(round($time - (86400 / (SPEED == 2 ? 1.5 : (SPEED == 3 ? 2 : SPEED))))); + + if(!empty($artifacts)){ + + //Cache inactive artifacts by owner + $inactiveArtifactsCache = []; + foreach($artifacts as $artifact) $inactiveArtifactsCache[$artifact['owner']][] = $artifact; + + foreach($inactiveArtifactsCache as $owner => $inactiveArtifacts){ + + //Initialize the array + $activeArtifacts = []; + + //Get cached active artifacts + $ownArtifacts = $database->getOwnArtifactsSum($owner, true); + + //Activate activable artifacts + foreach($inactiveArtifacts as $artifact){ + if($ownArtifacts['totals'] < 3){ + if($artifact['size'] == 1){ //Village effect + $database->activateArtifact($artifact['id']); + $ownArtifacts['totals']++; + $ownArtifacts['small']++; + }elseif($artifact['size'] == 2 && !$ownArtifacts['unique'] && !$ownArtifacts['great']){ //Account effect + $database->activateArtifact($artifact['id']); + $ownArtifacts['totals']++; + $ownArtifacts['great']++; + }elseif($artifact['size'] == 3 && !$ownArtifacts['unique'] && !$ownArtifacts['great']){ //Unique effect + $database->activateArtifact($artifact['id']); + $ownArtifacts['totals']++; + $ownArtifacts['unique']++; + } + }elseif($ownArtifacts['small'] == 3 && $artifact['size'] > 1){ + //If we've 3 village effect artifacts activated and at least one account/unique effect not activated + //then we need to deactivate the most recent village effect artifact and activate the oldest account + //or unique effect artifact + + //Deactivate the most recent village effect artifact + $database->activateArtifact($database->getNewestArtifactBySize($owner, 1)['id'], 0); + + //Activate the great/unique artifact + $database->activateArtifact($artifact['id']); + + $ownArtifacts['small']--; + $ownArtifacts['totals']++; + if($artifact['size'] == 2) $ownArtifacts['great']++; + else $ownArtifacts['unique']++; + } } } } } - - - /* - ===================================================== - = RETURN ARTIFACT TO NATARS - ===================================================== - */ - - public function returnArtifactToNatars($artifactArray) - { + /** + * Return the selected artifact, to the Natars account, by creating a new village and + * by moving the artifact into it + * + * @param array $artifact The artifact array + */ + + public function returnArtifactToNatars($artifactArray){ global $database; - - $multiplier = $artifactArray['size'] == 3 - ? 4 - : $artifactArray['size']; - + + //Set the village arrays + $artifactArrays = array_merge(self::NATARS_ARTIFACTS, self::NATARS_WW_BUILDING_PLANS); + $villageArrays = [['wid' => 0, 'mode' => $artifactArray['size'] + 1, 'type' => 3, + 'kid' => rand(1, 4), 'capital' => 0, 'pop' => 163, + 'name' => $artifactArrays[$artifactArray['desc']][$artifactArray['size'] - 1]['vname'], + 'natar' => 0]]; + + //Set the unit arrays + $multiplier = $artifactArray['size'] == 3 ? 4 : $artifactArray['size']; $unitsArray = ($this->natarsArtifactsUnits)($multiplier); - + + //Set the unit types $artifactTroops[1][] = array_values($unitsArray); - $artifactTroops[0] = array_keys($unitsArray); - + $artifactTroops[0] = array_keys($unitsArray); + + //Set the buildings array $artifactBuildings[1][] = array_values(self::NATARS_ARTIFACTS_BUILDINGS); - $artifactBuildings[0] = array_keys(self::NATARS_ARTIFACTS_BUILDINGS); + $artifactBuildings[0] = array_keys(self::NATARS_ARTIFACTS_BUILDINGS); - $wid = $database->generateVillages( - [[ - 'wid' => 0, - 'mode' => $artifactArray['size'] + 1, - 'type' => 3, - 'kid' => rand(1,4), - 'capital' => 0, - 'pop' => 163, - 'name' => 'Artifact Village', - 'natar' => 0 - ]], - self::NATARS_UID, - TRIBE5, - $artifactTroops, - $artifactBuildings - ); - - $database->updateArtifactDetails( - $artifactArray['id'], - [ - 'vref' => $wid, - 'owner' => self::NATARS_UID, - 'active'=> 0, - 'del' => 0 - ] - ); + //Generate the village + $wid = $database->generateVillages($villageArrays, self::NATARS_UID, TRIBE5, $artifactTroops, $artifactBuildings); + + //Update the artifact with the new village id and owner + $database->updateArtifactDetails($artifactArray['id'], ['vref' => $wid, 'owner' => self::NATARS_UID, 'active' => 0, 'del' => 0]); } - - - /* - ===================================================== - = ARTIFACT INFO HELPER - ===================================================== - */ - - public static function getArtifactInfo($artifact) - { - if (!is_array($artifact)) { - return [ - "requiredLevel" => 0, - "active" => 0, - "bonus" => 0, - "effectInfluence" => 0, - "nextEffect" => 0 - ]; - } - - $activationTime = 86400 / ( - SPEED == 2 ? 1.5 : - (SPEED == 3 ? 2 : SPEED) - ); - + + /** + * Gets the artifact informations in plain text + * + * @param int $artifact The artifact + * @return array Returns the information of the artifacts + */ + + public static function getArtifactInfo($artifact){ + + $activationTime = 86400 / (SPEED == 2 ? 1.5 : (SPEED == 3 ? 2 : SPEED)); $time = time(); + $nextEffect = "-"; - $requiredLevel = - ($artifact['size'] == 1 && $artifact['type'] != 11) - ? 10 - : 20; + if ( is_array($artifact) ) { + if($artifact['size'] == 1 && $artifact['type'] != 11){ + $requiredLevel = 10; + $effectInfluence = VILLAGE; + }else{ + $requiredLevel = $artifact['type'] != 11 ? 20 : 10; + $effectInfluence = ACCOUNT; + } - $active = - $artifact['owner'] == self::NATARS_UID - ? "-" - : ($artifact['active'] ? "".ACTIVE."" : "-"); + if($artifact['owner'] == 3) $active = "-"; + elseif(!$artifact['active'] && $artifact['conquered'] < $time - $activationTime) $active = "Can't be activated"; + elseif (!$artifact['active']) $active = date("d.m.Y H:i:s", $artifact['conquered'] + $activationTime); + else + { + $active = "".ACTIVE.""; + $nextEffect = date("d.m.Y H:i:s", $artifact['lastupdate'] + (86400 / (SPEED == 2 ? 1.5 : (SPEED == 3 ? 2 : SPEED)))); + } - return [ - "requiredLevel" => $requiredLevel, - "active" => $active, - "bonus" => $artifact['effect'] ?? '', - "effectInfluence" => ACCOUNT, - "nextEffect" => $time + $activationTime - ]; + //// Added by brainiac - thank you + if ($artifact['type'] == 8) + { + $kind = $artifact['kind']; + $effect = $artifact['effect2']; + }else{ + $kind = $artifact['type']; + $effect = $artifact['effect']; + } + + $artifactBadEffect = $artifact['type'] == 8 && $artifact['bad_effect'] == 1; + switch($kind){ + case 1: + $betterorbadder = $artifactBadEffect ? BUILDING_WEAKER : BUILDING_STRONGER; + break; + case 2: + $betterorbadder = $artifactBadEffect ? TROOPS_SLOWEST : TROOPS_FASTER; + break; + case 3: + $betterorbadder = $artifactBadEffect ? SPIES_DECRESE : SPIES_INCREASE; + break; + case 4: + $betterorbadder = $artifactBadEffect ? CONSUME_HIGH : CONSUME_LESS; + break; + case 5: + $betterorbadder = $artifactBadEffect ? TROOPS_MAKE_SLOWEST : TROOPS_MAKE_FASTER; + break; + case 6: + $betterorbadder = $artifactBadEffect ? YOU_CONSTRUCT : YOU_CONSTRUCT; + break; + case 7: + $betterorbadder = $artifactBadEffect ? CRANNY_DECRESE : CRANNY_INCREASED; + break; + case 8: + $betterorbadder = $artifactBadEffect ? SPIES_INCREASE : SPIES_DECRESE; + break; + } + $bonus = isset($betterorbadder) ? $betterorbadder." (".str_replace(["(", ")"], "" , $effect).")" : (($kind == 11 && $artifact['active']) ? "".WW_BUILDING_PLAN."" : "Not yet active"); + } else { + $requiredLevel = 0; + $active = 0; + $bonus = 0; + $effectInfluence = 0; + $nextEffect = 0; + } + + return ["requiredLevel" => $requiredLevel, "active" => $active, + "bonus" => $bonus, "effectInfluence" => $effectInfluence, + "nextEffect" => $nextEffect]; } } -?> +?> \ No newline at end of file diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index d6e34398..1ea28d21 100644 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -880,29 +880,12 @@ class Automation { $totalattackdead = $data_num = 0; if ($dataarray && count($dataarray)) { - // preload village data + // preload village data $vilIDs = []; - foreach ($dataarray as $data) { - $moveid = (int)$data['moveid']; - - // =============================== - // ATOMIC CLAIM (Race condition fix) - // =============================== - $claimQuery = "UPDATE " . TB_PREFIX . "movement - SET proc = 1 - WHERE moveid = $moveid AND proc = 0"; - mysqli_query($database->dblink, $claimQuery); - // If this process didn't successfully claim it, - // another process already did — skip it. - if (mysqli_affected_rows($database->dblink) !== 1) { - continue; - } - // =============================== - // SAFE: Now process this battle - // =============================== + foreach($dataarray as $data) { $vilIDs[$data['from']] = true; $vilIDs[$data['to']] = true; - } + } $vilIDs = array_keys($vilIDs); $database->getProfileVillages($vilIDs, 5); $database->getUnit($vilIDs); @@ -2750,90 +2733,81 @@ class Automation { } } -private function returnunitsComplete() { - if (!$this->acquireFunctionLock('returnunits', 2)) { - return; // Another process is handling returns - } - - try { - // ... existing logic with atomic per-record processing ... - } finally { - $this->releaseFunctionLock('returnunits'); - } - global $database, $technology; - $time = time(); - - // Get pending returns - $q = "SELECT moveid FROM " . TB_PREFIX . "movement - WHERE proc = 0 AND sort_type = 4 AND endtime < $time"; - $pendingMoves = $database->query_return($q); - - if (!$pendingMoves) return; - - foreach ($pendingMoves as $move) { - $moveid = (int)$move['moveid']; - - // ATOMIC: Claim this movement record - $claimQuery = "UPDATE " . TB_PREFIX . "movement - SET proc = 1 - WHERE moveid = $moveid AND proc = 0"; - mysqli_query($database->dblink, $claimQuery); - - // Only process if WE claimed it - if (mysqli_affected_rows($database->dblink) !== 1) { - continue; // Another process got it - } - - // Now safe to process - we have exclusive ownership - $dataQuery = "SELECT m.*, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, - a.t7, a.t8, a.t9, a.t10, a.t11 - FROM " . TB_PREFIX . "movement m - JOIN " . TB_PREFIX . "attacks a ON m.ref = a.id - WHERE m.moveid = $moveid"; - $result = mysqli_query($database->dblink, $dataQuery); - $data = mysqli_fetch_assoc($result); - - if (!$data) continue; - - try { - // Process troop return - $tribe = $database->getUserField( - $database->getVillageField($data['to'], "owner"), - "tribe", 0 - ); - - if ($tribe <= 0) continue; - - $u = $tribe == 1 ? "" : $tribe - 1; - $database->modifyUnit( - $data['to'], - [$u."1", $u."2", $u."3", $u."4", $u."5", - $u."6", $u."7", $u."8", $u."9", $tribe."0", "hero"], - [$data['t1'], $data['t2'], $data['t3'], $data['t4'], $data['t5'], - $data['t6'], $data['t7'], $data['t8'], $data['t9'], $data['t10'], - $data['t11']], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] - ); - - // Add resources - if ($data['wood'] + $data['clay'] + $data['iron'] + $data['crop'] > 0) { - $database->modifyResource( - $data['to'], - $data['wood'], $data['clay'], $data['iron'], $data['crop'], - 1 - ); + private function returnunitsComplete() { + global $database, $technology; + + $time = time(); + $q = " + SELECT + `to`, `from`, moveid, starttime, endtime, wood, clay, iron, crop, + t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11 + FROM + ".TB_PREFIX."movement, + ".TB_PREFIX."attacks + WHERE + ".TB_PREFIX."movement.ref = ".TB_PREFIX."attacks.id + AND + ".TB_PREFIX."movement.proc = 0 + AND + ".TB_PREFIX."movement.sort_type = 4 + AND + endtime < $time"; + $dataarray = $database->query_return($q); + + if ($dataarray && count($dataarray)) { + // preload village data + $vilIDs = []; + foreach($dataarray as $data) { + $vilIDs[$data['from']] = true; + $vilIDs[$data['to']] = true; + } + $database->getProfileVillages(array_keys($vilIDs), 5); + $database->getOasisEnforce($vilIDs, 0); + $database->getOasisEnforce($vilIDs, 1); + + $movementProcIDs = []; + foreach($dataarray as $data) { + $tribe = $database->getUserField($database->getVillageField($data['to'], "owner"), "tribe", 0); + $u = $tribe == 1 ? "" : $tribe - 1; + $database->modifyUnit( + $data['to'], + [$u."1", $u."2", $u."3", $u."4", $u."5", $u."6", $u."7", $u."8", $u."9", $tribe."0", "hero"], + [$data['t1'], $data['t2'], $data['t3'], $data['t4'], $data['t5'], $data['t6'], $data['t7'], $data['t8'], $data['t9'], $data['t10'], $data['t11']], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + ); + + //If there's at least 1 resource, add it to the village + if($data['wood'] + $data['clay'] + $data['iron'] + $data['crop'] > 0){ + $database->modifyResource($data['to'], $data['wood'], $data['clay'], $data['iron'], $data['crop'], 1); + } + + $movementProcIDs[] = $data['moveid']; + + //Update starvation data + $database->addStarvationData($data['to']); } - $database->addStarvationData($data['to']); - - } catch (Throwable $e) { - error_log("returnunitsComplete error moveid $moveid: " . $e->getMessage()); - // proc=1 already set, so it won't retry infinitely + $database->setMovementProc(implode(', ', $movementProcIDs)); + $this->pruneResource(); + } + + // Settlers + $q = "SELECT `to`, moveid FROM ".TB_PREFIX."movement where ref = 0 and proc = '0' and sort_type = '4' and endtime < $time"; + $dataarray = $database->query_return($q); + $movementProcIDs = []; + + if ($dataarray && count($dataarray)) { + foreach($dataarray as $data) { + $tribe = $database->getUserField($database->getVillageField($data['to'], "owner"), "tribe", 0); + $database->modifyUnit($data['to'], [$tribe."0"], [3], [1]); + + //If a settling is canceled, add 750 for each resource type + $database->modifyResource($data['to'], 750, 750, 750, 750, 1); + $movementProcIDs[] = $data['moveid']; + } + $database->setMovementProc(implode(', ', $movementProcIDs)); } } - - $this->pruneResource(); -} private function sendSettlersComplete() { global $database; @@ -4632,26 +4606,6 @@ private function returnunitsComplete() { $database->query($q); } } - - // Add to Automation.php - new helper method - private function acquireFunctionLock($functionName, $timeout = 5) { - global $database; - - $lockName = "automation_$functionName"; - $result = mysqli_query($database->dblink, - "SELECT GET_LOCK('$lockName', $timeout) as acquired" - ); - $row = mysqli_fetch_assoc($result); - - return ($row && $row['acquired'] == 1); - } - - private function releaseFunctionLock($functionName) { - global $database; - - $lockName = "automation_$functionName"; - mysqli_query($database->dblink, "SELECT RELEASE_LOCK('$lockName')"); - } private function artefactOfTheFool() { global $database; diff --git a/GameEngine/BBCode.php b/GameEngine/BBCode.php index 0c55ac09..822ffe17 100755 --- a/GameEngine/BBCode.php +++ b/GameEngine/BBCode.php @@ -1,178 +1,255 @@ - 20000) { - $input = substr($input, 0, 20000); -} - -/* =============================== - SAFE OUTPUT ESCAPER - =============================== */ -function bb_e(string $value): string -{ - return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); -} - -/* =============================== - BUILD PATTERNS ENTERPRISE STYLE - =============================== */ +include_once ("config.php"); +include_once ("Lang/".LANG.".php"); $pattern = []; +$pattern[0] = "/\[b\](.*?)\[\/b\]/is"; +$pattern[1] = "/\[i\](.*?)\[\/i\]/is"; +$pattern[2] = "/\[u\](.*?)\[\/u\]/is"; +$pattern[3] = "/\[tid1\]/"; +$pattern[4] = "/\[tid2\]/"; +$pattern[5] = "/\[tid3\]/"; +$pattern[6] = "/\[tid4\]/"; +$pattern[7] = "/\[tid5\]/"; +$pattern[8] = "/\[tid6\]/"; +$pattern[9] = "/\[tid7\]/"; +$pattern[10] = "/\[tid8\]/"; +$pattern[11] = "/\[tid9\]/"; +$pattern[12] = "/\[tid10\]/"; +$pattern[13] = "/\[tid11\]/"; +$pattern[14] = "/\[tid12\]/"; +$pattern[15] = "/\[tid13\]/"; +$pattern[16] = "/\[tid14\]/"; +$pattern[17] = "/\[tid15\]/"; +$pattern[18] = "/\[tid16\]/"; +$pattern[19] = "/\[tid17\]/"; +$pattern[20] = "/\[tid18\]/"; +$pattern[21] = "/\[tid19\]/"; +$pattern[22] = "/\[tid20\]/"; +$pattern[23] = "/\[tid21\]/"; +$pattern[24] = "/\[tid22\]/"; +$pattern[25] = "/\[tid23\]/"; +$pattern[26] = "/\[tid24\]/"; +$pattern[27] = "/\[tid25\]/"; +$pattern[28] = "/\[tid26\]/"; +$pattern[29] = "/\[tid27\]/"; +$pattern[30] = "/\[tid28\]/"; +$pattern[31] = "/\[tid29\]/"; +$pattern[32] = "/\[tid30\]/"; +$pattern[33] = "/\[tid31\]/"; +$pattern[34] = "/\[tid32\]/"; +$pattern[35] = "/\[tid33\]/"; +$pattern[36] = "/\[tid34\]/"; +$pattern[37] = "/\[tid35\]/"; +$pattern[38] = "/\[tid36\]/"; +$pattern[39] = "/\[tid37\]/"; +$pattern[40] = "/\[tid38\]/"; +$pattern[41] = "/\[tid39\]/"; +$pattern[42] = "/\[tid40\]/"; +$pattern[43] = "/\[tid41\]/"; +$pattern[44] = "/\[tid42\]/"; +$pattern[45] = "/\[tid43\]/"; +$pattern[46] = "/\[tid44\]/"; +$pattern[47] = "/\[tid45\]/"; +$pattern[48] = "/\[tid46\]/"; +$pattern[49] = "/\[tid47\]/"; +$pattern[50] = "/\[tid48\]/"; +$pattern[51] = "/\[tid49\]/"; +$pattern[52] = "/\[tid50\]/"; +$pattern[53] = "/\[hero\]/"; +$pattern[54] = "/\[lumber\]/"; +$pattern[55] = "/\[clay\]/"; +$pattern[56] = "/\[iron\]/"; +$pattern[57] = "/\[crop\]/"; +$pattern[58] = "/\*aha\*/"; +$pattern[59] = "/\*angry\*/"; +$pattern[60] = "/\*cool\*/"; +$pattern[61] = "/\*cry\*/"; +$pattern[62] = "/\*cute\*/"; +$pattern[63] = "/\*depressed\*/"; +$pattern[64] = "/\*eek\*/"; +$pattern[65] = "/\*ehem\*/"; +$pattern[66] = "/\*emotional\*/"; +$pattern[67] = "/\:D/"; +$pattern[68] = "/\:\)/"; +$pattern[69] = "/\*hit\*/"; +$pattern[70] = "/\*hmm\*/"; +$pattern[71] = "/\*hmpf\*/"; +$pattern[72] = "/\*hrhr\*/"; +$pattern[73] = "/\*huh\*/"; +$pattern[74] = "/\*lazy\*/"; +$pattern[75] = "/\*love\*/"; +$pattern[76] = "/\*nocomment\*/"; +$pattern[77] = "/\*noemotion\*/"; +$pattern[78] = "/\*notamused\*/"; +$pattern[79] = "/\*pout\*/"; +$pattern[80] = "/\*redface\*/"; +$pattern[81] = "/\*rolleyes\*/"; +$pattern[82] = "/\:\(/"; +$pattern[83] = "/\*shy\*/"; +$pattern[84] = "/\*smile\*/"; +$pattern[85] = "/\*tongue\*/"; +$pattern[86] = "/\*veryangry\*/"; +$pattern[87] = "/\*veryhappy\*/"; +$pattern[88] = "/\;\)/"; + $replace = []; +$replace[0] = "$1"; +$replace[1] = "$1"; +$replace[2] = "$1"; +$replace[3] = "".U1.""; +$replace[4] = "".U2.""; +$replace[5] = "".U3.""; +$replace[6] = "".U4.""; +$replace[7] = "".U5.""; +$replace[8] = "".U6.""; +$replace[9] = "".U7.""; +$replace[10] = "".U8.""; +$replace[11] = "".U9.""; +$replace[12] = "".U10.""; +$replace[13] = "".U11.""; +$replace[14] = "".U12.""; +$replace[15] = "".U13.""; +$replace[16] = "".U14.""; +$replace[17] = "".U15.""; +$replace[18] = "".U16.""; +$replace[19] = "".U17.""; +$replace[20] = "".U18.""; +$replace[21] = "".U19.""; +$replace[22] = "".U20.""; +$replace[23] = "".U21.""; +$replace[24] = "".U22.""; +$replace[25] = "".U23.""; +$replace[26] = "".U24.""; +$replace[27] = "".U25.""; +$replace[28] = "".U26.""; +$replace[29] = "".U27.""; +$replace[30] = "".U28.""; +$replace[31] = "".U29.""; +$replace[32] = "".U30.""; +$replace[33] = "".U31.""; +$replace[34] = "".U32.""; +$replace[35] = "".U33.""; +$replace[36] = "".U34.""; +$replace[37] = "".U35.""; +$replace[38] = "".U36.""; +$replace[39] = "".U37.""; +$replace[40] = "".U38.""; +$replace[41] = "".U39.""; +$replace[42] = "".U40.""; +$replace[43] = "".U41.""; +$replace[44] = "".U42.""; +$replace[45] = "".U43.""; +$replace[46] = "".U44.""; +$replace[47] = "".U45.""; +$replace[48] = "".U46.""; +$replace[49] = "".U47.""; +$replace[50] = "".U48.""; +$replace[51] = "".U49.""; +$replace[52] = "".U50.""; +$replace[53] = "".U0.""; +$replace[54] = "".LUMBER.""; +$replace[55] = "".CLAY.""; +$replace[56] = "".IRON.""; +$replace[57] = "".CROP.""; +$replace[54] = "".LUMBER.""; +$replace[55] = "".CLAY.""; +$replace[56] = "".IRON.""; +$replace[57] = "".CROP.""; +$replace[58] = "*aha*"; +$replace[59] = "*angry*"; +$replace[60] = "*cool*"; +$replace[61] = "*cry*"; +$replace[62] = "*cute*"; +$replace[63] = "*depressed*"; +$replace[64] = "*eek*"; +$replace[65] = "*ehem*"; +$replace[66] = "*emotional*"; +$replace[67] = ":D"; +$replace[68] = ":)"; +$replace[69] = "*hit*"; +$replace[70] = "*hmm*"; +$replace[71] = "*hmpf*"; +$replace[72] = "*hrhr*"; +$replace[73] = "*huh*"; +$replace[74] = "*lazy*"; +$replace[75] = "*love*"; +$replace[76] = "*nocomment*"; +$replace[77] = "*noemotion*"; +$replace[78] = "*notamused*"; +$replace[79] = "*pout*"; +$replace[80] = "*redface*"; +$replace[81] = "*rolleyes*"; +$replace[82] = ":("; +$replace[83] = "*shy*"; +$replace[84] = "*smile*"; +$replace[85] = "*tongue*"; +$replace[86] = "*veryangry*"; +$replace[87] = "*veryhappy*"; +$replace[88] = ";)"; -/* -------- BASIC TAGS (bounded, no catastrophic backtracking) -------- */ -$pattern[] = "/\[b\]([^[]{0,5000})\[\/b\]/i"; -$replace[] = "$1"; - -$pattern[] = "/\[i\]([^[]{0,5000})\[\/i\]/i"; -$replace[] = "$1"; - -$pattern[] = "/\[u\]([^[]{0,5000})\[\/u\]/i"; -$replace[] = "$1"; - -/* -------- UNIT TAGS (tid1–tid50) -------- */ -for ($i = 1; $i <= 50; $i++) { - $pattern[] = "/\[tid{$i}\]/i"; - $const = "U{$i}"; - $title = defined($const) ? bb_e(constant($const)) : ''; - $replace[] = "{$title}"; -} - -/* -------- HERO -------- */ -$pattern[] = "/\[hero\]/i"; -$replace[] = "".bb_e(U0).""; - -/* -------- RESOURCES -------- */ -$resources = [ - 'lumber' => ['class' => 'r1', 'title' => LUMBER], - 'clay' => ['class' => 'r2', 'title' => CLAY], - 'iron' => ['class' => 'r3', 'title' => IRON], - 'crop' => ['class' => 'r4', 'title' => CROP], -]; - -foreach ($resources as $tag => $data) { - $title = bb_e($data['title']); - $pattern[] = "/\[{$tag}\]/i"; - $replace[] = "{$title}"; -} - -/* -------- SMILEYS -------- */ -$smileys = [ - "*aha*" => "aha","*angry*" => "angry","*cool*" => "cool","*cry*" => "cry", - "*cute*" => "cute","*depressed*" => "depressed","*eek*" => "eek", - "*ehem*" => "ehem","*emotional*" => "emotional","*hit*" => "hit", - "*hmm*" => "hmm","*hmpf*" => "hmpf","*hrhr*" => "hrhr","*huh*" => "huh", - "*lazy*" => "lazy","*love*" => "love","*nocomment*" => "nocomment", - "*noemotion*" => "noemotion","*notamused*" => "notamused","*pout*" => "pout", - "*redface*" => "redface","*rolleyes*" => "rolleyes","*shy*" => "shy", - "*smile*" => "smile","*tongue*" => "tongue", - "*veryangry*" => "veryangry","*veryhappy*" => "veryhappy", -]; - -foreach ($smileys as $code => $class) { - $pattern[] = "/" . preg_quote($code, '/') . "/"; - $replace[] = "{$code}"; -} - -/* basic emoticons */ -$basic = [":D"=>"grin",":)"=>"happy",":("=>"sad",";)"=>"wink"]; -foreach ($basic as $code => $class) { - $pattern[] = "/" . preg_quote($code, '/') . "/"; - $replace[] = "{$code}"; -} - -/* =============================== - SECURE PLACEHOLDER CALLBACKS - =============================== */ - -/* -------- ALLIANCE -------- */ +// replace alliance placeholders $input = preg_replace_callback( - "/\[alliance(\d{1,20})\]([0-9]{1,20})\[\/alliance\d{1,20}\]/i", - static function ($m) { + "/\[alliance(\d{0,20})\]([^\]]*)\[\/alliance\d{0,20}\]/is", + function($matches) { global $database; - $aid = (int)$m[2]; - $aname = $database->getAllianceName($aid); - return $aname - ? "".bb_e($aname)."" - : "Alliance not found!"; - }, - $input -); -/* -------- PLAYER -------- */ + $aname = $database->getAllianceName($matches[2]); + if (!empty($aname)) return "".$aname.""; + else return "Alliance not found!"; + }, + $input); + +// replace player placeholders $input = preg_replace_callback( - "/\[player(\d{1,20})\]([0-9]{1,20})\[\/player\d{1,20}\]/i", - static function ($m) { + "/\[player(\d{0,20})\]([^\]]*)\[\/player\d{0,20}\]/is", + function($matches) { global $database; - $uid = (int)$m[2]; - $uname = $database->getUserField($uid, "username", 0); - return ($uname && $uname !== "[?]") - ? "".bb_e($uname)."" - : "Player not found!"; + + $uname = $database->getUserField((int) $matches[2], "username", 0); + if (!empty($uname) && $uname != "[?]") return "".$uname.""; + else return "Player not found!"; }, - $input -); + $input); -/* -------- REPORT -------- */ +// replace report placeholders $input = preg_replace_callback( - "/\[report(\d{1,20})\]([0-9]{0,20})\[\/report\d{1,20}\]/i", - static function ($m) { + "/\[report(\d{0,20})\]([^\]]*)\[\/report\d{0,20}\]/is", + function($matches) { global $database; - $rid = (int)($m[1] ?: $m[2]); - $report = $database->getNotice2($rid, null, false); - return $report - ? "".bb_e($report['topic'])."" - : "Report not found!"; + + $reportID = $matches[1] > 0 ? $matches[1] : $matches[2]; + $report = $database->getNotice2((int) $reportID, null, false); + + if (!empty($report)) return "".$report['topic'].""; + else return "Report not found!"; }, - $input -); + $input); -/* -------- COORDINATES -------- */ +// replace coordinate placeholders $input = preg_replace_callback( - "/\[coor(\d{1,20})\](-?\d{1,4}\|-?\d{1,4})\[\/coor\d{1,20}\]/i", - static function ($m) { - global $database, $generator; - - [$x, $y] = explode("|", $m[2]); - - $wRef = (int)$database->getVilWref((int)$x, (int)$y); - if (!$wRef) return "Village not found!"; - - $cwref = (int)$generator->getMapCheck($wRef); + "/\[coor(\d{0,20})\]([^\]]*)\[\/coor\d{0,20}\]/is", + function($matches) { + global $generator, $database; + + $name = ""; + $coordinates = explode("|", $matches[2]); + $wRef = $database->getVilWref($coordinates[0], $coordinates[1]); + $cwref = $generator->getMapCheck($wRef); $state = $database->getVillageType($wRef); - - if ($state > 0) { - $name = $database->getVillageState($wRef) - ? $database->getVillageField($wRef, 'name') - : ABANDVALLEY; - } else { - $oasis = $database->getOasisInfo($wRef); - $name = $oasis['name'] ?? ''; + if($state > 0){ + if($database->getVillageState($wRef)) $name = $database->getVillageField($wRef, 'name'); + else $name = ABANDVALLEY; } - - return $name - ? "".bb_e($name)." ({$x}|{$y})" - : "Village not found!"; + else $name = $database->getOasisInfo($wRef)['name']; + + if(!empty($name)) return "".$name." (".$coordinates[0]."|".$coordinates[1].")".""; + return "Village not found!"; }, - $input -); - -/* -------- REMOVE MESSAGE TAGS -------- */ -$input = preg_replace('/\[\/?message\]/i', '', $input); - -/* =============================== - FINAL BBCode REPLACE - =============================== */ + $input); +$input = preg_replace('/\[message\]/', '', $input); +$input = preg_replace('/\[\/message\]/', '', $input); $bbcoded = preg_replace($pattern, $replace, $input); +?> diff --git a/GameEngine/Battle.php b/GameEngine/Battle.php index fb77b9a0..c90da0a6 100644 --- a/GameEngine/Battle.php +++ b/GameEngine/Battle.php @@ -18,324 +18,772 @@ ## ## ################################################################################# -/* -========================================================= -= BATTLE ENGINE – CORE COMBAT CALCULATION -========================================================= -= Responsible for: -= - Battle simulation (warsim) -= - Real combat calculation -= - Hero combat logic -= - Wall / Residence bonus -= - Catapults & Rams damage -= - Casualties computation -= - Bounty calculation -========================================================= -*/ -class Battle -{ - /* - ===================================================== - = INTERNAL MATH ENGINE - ===================================================== - */ +class Battle { - private $sigma; - - public function __construct() - { - // Kirilloid sigma curve for catapult damage - $this->sigma = function ($x) { - return ($x > 1 ? 2 - $x ** -1.5 : $x ** 1.5) / 2; - }; - } - - /* - ===================================================== - = ================= SIMULATION ====================== - ===================================================== - */ - - public function procSim($post) - { - global $form; - - if (!isset($post['a1_v'])) { - return; - } - - $sum = 0; - for ($i = 1; $i <= 10; $i++) { - $sum += (int)($post['a1_'.$i] ?? 0); - } - - if ($sum <= 0) { - return; - } - - $_POST['result'] = $this->simulate($post); - $form->valuearray = $post; - } - - /* - ===================================================== - = SIMULATION CORE - ===================================================== - */ - - private function simulate($post) - { - $attacker = $this->buildAttackerArray($post); - $defender = $this->buildDefenderArray($post); - - return $this->calculateBattle( - $attacker, - $defender, - $post['walllevel'], - $post['a1_v'], - $post['tribe'], - $post['palast'], - $post['ew1'], - $post['ew2'], - $post['ktyp'] + 3, - [], - 0,0,0,0,0,0,0,0, - $post['kata'], - $post['stonemason'], - $post['walllevel'], - $post['h_off_bonus'], - $post['h_off'], - $post['h_def_bonus'], - 0,0,0,0,0 - ); - } - - /* - ===================================================== - = HERO ENGINE - ===================================================== - */ - - private function getBattleHero($uid) - { - global $database; - - $hero = $database->getHero($uid); - if (!count($hero)) { - return [ - 'heroid'=>0,'unit'=>'','atk'=>0, - 'di'=>0,'dc'=>0,'ob'=>0,'db'=>0,'health'=>0 - ]; - } - - $unitData = $GLOBALS["h".$hero[0]['unit']]; - - $atk = $unitData['atk'] + ($hero[0]['attack'] * $unitData['atkp']); - $di = $unitData['di'] + 5 * floor($hero[0]['defence'] * $unitData['dip'] / 5); - $dc = $unitData['dc'] + 5 * floor($hero[0]['defence'] * $unitData['dcp'] / 5); - - return [ - 'heroid' => (int)$hero[0]['heroid'], - 'unit' => $hero[0]['unit'], - 'atk' => $atk, - 'di' => $di, - 'dc' => $dc, - 'ob' => 1 + 0.010 * ($hero[0]['attackbonus'] / 5), - 'db' => 1 + 0.010 * ($hero[0]['defencebonus'] / 5), - 'health' => $hero[0]['health'] - ]; - } - - /* - ===================================================== - = MAIN BATTLE CALCULATION - ===================================================== - */ - - public function calculateBattle( - $Attacker, - $Defender, - $def_wall, - $att_tribe, - $def_tribe, - $residence, - $attpop, - $defpop, - $type, - $def_ab, - $att_ab1,$att_ab2,$att_ab3,$att_ab4, - $att_ab5,$att_ab6,$att_ab7,$att_ab8, - $tblevel, - $stonemason, - $walllevel, - $offhero, - $hero_strenght, - $deffhero, - $AttackerID, - $DefenderID, - $AttackerWref, - $DefenderWref, - $conqureby, - $defReinforcements = null - ) - { - global $database; - - /* - ================================================= - = 1. CALCULATE RAW ATTACK / DEFENSE - ================================================= + /** + * + * @author Kirilloid --> https://github.com/kirilloid/travian/blob/master/src/model/base/combat.ts + * @var double The number of attacking catapults: 1 = 100%, 0 = 0% + * */ + + private $sigma; + + public function __construct(){ + + $this->sigma = function($x) { return ($x > 1 ? 2 - $x ** -1.5 : $x ** 1.5) / 2; }; + + } + + public function procSim($post) { + global $form; + + // receive form and process + if(isset($post['a1_v']) && (isset($post['a2_v1']) || isset($post['a2_v2']) || isset($post['a2_v3']) || isset($post['a2_v4']) || isset($post['a2_v5']))){ + $_POST['mytribe'] = $post['a1_v']; + + $target = []; + if(isset($post['a2_v1'])) array_push($target, 1); + if(isset($post['a2_v2'])) array_push($target, 2); + if(isset($post['a2_v3'])) array_push($target, 3); + if(isset($post['a2_v4'])) array_push($target, 4); + if(isset($post['a2_v5'])) array_push($target, 5); + + $_POST['target'] = $target; + if(isset($post['h_off_bonus'])){ + if(intval($post['h_off_bonus']) > 20) $post['h_off_bonus'] = 20; + } + else $post['h_off_bonus'] = 0; + + if(isset($post['h_def_bonus'])){ + if(intval($post['h_def_bonus']) > 20) $post['h_def_bonus'] = 20; + } + else $post['h_def_bonus'] = 0; + + $sum = 0; + for($i = 1; $i <= 10; $i++) $sum += (!empty($post['a1_'.$i]) ? $post['a1_'.$i] : 0); + + if($sum > 0){ + $post['palast'] = intval($post['palast']); + if($post['palast'] > 20) $post['palast'] = 20; + + for($i = 1; $i <= 5; $i++){ + if(isset($post['wall'.$i])){ + $post['wall'.$i] = intval($post['wall'.$i]); + if($post['wall'.$i] > 20) $post['wall'.$i] = 20; + elseif($post['wall'.$i] < 0) $post['wall'.$i] = 0; + $post['walllevel'] = $post['wall'.$i]; + } + } - $attackPoints = $this->calculateAttackPoints($Attacker, $att_tribe); - $defensePoints = $this->calculateDefensePoints($Defender); + $post['tribe'] = $target[0]; + $_POST['result'] = $this->simulate($post); + $newWallLevel = $_POST['result'][7]; + $oldWallLevel = $_POST['result'][8]; + + //If the wall level is reduce, we have to re-do the whole battle + if($newWallLevel != $oldWallLevel){ + $post['walllevel'] = $newWallLevel; + $_POST['result'] = $this->simulate($post); + + //Reset the datas + $_POST['result'][7] = $newWallLevel; + $_POST['result'][8] = $post['walllevel'] = $oldWallLevel; + } + + $form->valuearray = $post; + } + } + } + + private function getBattleHero($uid) { + global $database; + $heroarray = $database->getHero($uid); - /* - ================================================= - = 2. WALL & RESIDENCE BONUS - ================================================= - */ + if (!count($heroarray)) return ['heroid' => 0, 'unit' =>'','atk' => 0,'di' => 0,'dc' => 0,'ob' => 0,'db' => 0,'health' => 0]; - $defensePoints = $this->applyWallBonus( - $defensePoints, - $def_wall, - $def_tribe, - $residence - ); + $herodata = $GLOBALS["h".$heroarray[0]['unit']]; + if(!isset($heroarray['health'])) $heroarray['health'] = 0; + $h_atk = $herodata['atk'] + ($heroarray[0]['attack'] * $herodata['atkp']); + $h_di = $herodata['di'] + 5 * floor($heroarray[0]['defence'] * $herodata['dip'] / 5); + $h_dc = $herodata['dc'] + 5 * floor($heroarray[0]['defence'] * $herodata['dcp'] / 5); + $h_ob = 1 + 0.010 * ($heroarray[0]['attackbonus'] / 5); + $h_db = 1 + 0.010 * ($heroarray[0]['defencebonus'] / 5); - /* - ================================================= - = 3. FINAL RAP / RDP - ================================================= - */ + return ['heroid' => (int) $heroarray[0]['heroid'], 'unit' => $heroarray[0]['unit'], 'atk' => $h_atk, 'di' => $h_di, 'dc' => $h_dc, 'ob' => $h_ob, 'db' => $h_db, 'health' => $heroarray['health']]; + } - $rap = round($attackPoints); - $rdp = round($defensePoints); + private function getBattleHeroSim($attbonus) { + $h_atk = 0; + $h_ob = 1 + 0.010 * $attbonus; - $winner = $rap > $rdp; + return ['unit' => 16,'atk' => $h_atk,'ob' => $h_ob]; + } - /* - ================================================= - = 4. CASUALTY FACTOR - ================================================= - */ + private function simulate($post) { + //set the arrays with attacking and defending units + $attacker = ['u1' => 0, 'u2' => 0, 'u3' => 0, 'u4' => 0, 'u5' => 0, 'u6' => 0, 'u7' => 0, 'u8' => 0, 'u9' => 0, 'u10' => 0, 'u11' => 0, 'u12' => 0, 'u13' => 0, 'u14' => 0, 'u15' => 0, 'u16' => 0, 'u17' => 0, 'u18' => 0, 'u19' => 0, 'u20' => 0, 'u21' => 0, 'u22' => 0, 'u23' => 0, 'u24' => 0, + 'u25' => 0, 'u26' => 0, 'u27' => 0, 'u28' => 0, 'u29' => 0, 'u30' => 0, 'u31' => 0, 'u32' => 0, 'u33' => 0, 'u34' => 0, 'u35' => 0, 'u36' => 0, 'u37' => 0, 'u38' => 0, 'u39' => 0, 'u40' => 0, 'u41' => 0, 'u42' => 0, 'u43' => 0, 'u44' => 0, 'u45' => 0, 'u46' => 0, 'u47' => 0, 'u48' => 0, + 'u49' => 0, 'u50' => 0]; + $start = ($post['a1_v'] - 1) * 10 + 1; + $offhero = intval($post['h_off_bonus']); + $hero_strenght = intval($post['h_off']); + $deffhero = intval($post['h_def_bonus']); + for($i = $start, $index = 1; $i <= $start + 9; $i++, $index++) { + if(isset($post['a1_'.$index]) && !empty($post['a1_'.$index])) { + $attacker['u'.$i] = $post['a1_'.$index]; + } + else $attacker['u'.$i] = 0; + + if($index <=8 && isset($post['f1_'.$index]) && !empty($post['f1_'.$index])) { + ${'att_ab'.$index} = $post['f1_'.$index]; + } + else ${'att_ab'.$index} = 0; + } - $ratio = $rap > 0 - ? pow(($rdp / $rap), 1.5) - : 1; + $defender = []; + $defscout = 0; + //fix by ronix + for($i = 1;$i <= 50; $i++) { + if(isset($post['a2_'.$i]) && !empty($post['a2_'.$i])) { + $defender['u'.$i] = $post['a2_'.$i]; + $def_ab[$i] = $post['f2_'.$i]; + if($i == 4 || $i == 14 || $i == 23 || $i == 44){ + $defscout += $defender['u'.$i]; + } + + } + else { + $defender['u'.$i] = 0; + $def_ab[$i] = 0; + } + } + + $deftribe = $post['tribe']; + $wall = 0; - if ($ratio > 1) $ratio = 1; + if(empty($post['kata'])) $post['kata'] = 0; + // check scout + + $scout = 1; + for($i = $start; $i <= $start + 9 ; $i++) { + if($i == 4 || $i == 14 || $i == 23 || $i == 44){ + }else{ + if($attacker['u'.$i] > 0) { + $scout = 0; + break; + } + } + } + + $walllevel = $post['walllevel']; + $wall = $walllevel; + $palast = $post['palast']; + + if($scout == 1 && $defscout == 0) $walllevel = $wall = $palast = 0; + + if($scout == 1) $palast = 0; //no def point palace and residence when scout + + if(!$scout) return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$palast,$post['ew1'],$post['ew2'],$post['ktyp']+3,$def_ab,$att_ab1,$att_ab2,$att_ab3,$att_ab4,$att_ab5,$att_ab6,$att_ab7,$att_ab8,$post['kata'],$post['stonemason'],$walllevel,$offhero,$post['h_off'],$deffhero,0,0,0,0,0); + else return $this->calculateBattle($attacker,$defender,$wall,$post['a1_v'],$deftribe,$palast,$post['ew1'],$post['ew2'],1,$def_ab,$att_ab1,$att_ab2,$att_ab3,$att_ab4,$att_ab5,$att_ab6,$att_ab7,$att_ab8,$post['kata'],$post['stonemason'],$walllevel,0,0,0,0,0,0,0,0); + + } + + public function getTypeLevel($tid,$vid) { + global $village,$database; + + $keyholder = []; + $resourcearray = $database->getResourceLevel($vid); + + foreach(array_keys($resourcearray, $tid) as $key) { + if(strpos($key,'t')) { + $key = preg_replace("/[^0-9]/", '', $key); + array_push($keyholder, $key); + } + } + + $element = count($keyholder); + if($element >= 2) { + if($tid <= 4) { + $temparray = []; + for($i = 0; $i <= $element - 1; $i++){ + array_push($temparray, $resourcearray['f'.$keyholder[$i]]); + } + foreach ($temparray as $key => $val) { + if ($val == max($temparray)) + $target = $key; + } + } + else { + $target = 0; + for($i=1;$i<=$element-1;$i++) { + if($resourcearray['f'.$keyholder[$i]] > $resourcearray['f'.$keyholder[$target]]) { + $target = $i; + } + } + } + } + else if($element == 1) $target = 0; + else return 0; + + + if(!empty($keyholder[$target])) return $resourcearray['f'.$keyholder[$target]]; + else return 0; + } + + //1 raid 0 normal + function calculateBattle($Attacker, $Defender, $def_wall, $att_tribe, $def_tribe, $residence, $attpop, $defpop, $type, $def_ab, $att_ab1, $att_ab2, $att_ab3, $att_ab4, $att_ab5, $att_ab6, $att_ab7, $att_ab8, $tblevel, $stonemason, $walllevel, $offhero, $hero_strenght, $deffhero, $AttackerID, $DefenderID, $AttackerWref, $DefenderWref, $conqureby, $defReinforcements = null) { + global $bid34, $bid35, $database; + + // Define the array, with the units + $calvary = [4, 5, 6, 15, 16, 23, 24, 25, 26, 45, 46]; + $catapult = [8, 18, 28, 48]; + $rams = [7, 17, 27, 47]; + $catp = $ram = 0; + + // Array to return the result of the calculation back $result = []; - $result['Attack_points'] = $rap; - $result['Defend_points'] = $rdp; - $result['Winner'] = $winner ? "attacker" : "defender"; - $result[1] = $ratio; - $result[2] = 1 - $ratio; + $involve = 0; + $winner = false; + + // at 0 all partial results + + //cap = Cavalry attack points + //ap = Infantry attack points + //cdp = Cavalry attack points + //dp = Infantry defense points + //rap = Result attack points + //rdp = Result defense points + //detected = Detected or not by defender spies + $cap = $ap = $dp = $cdp = $rap = $rdp = 0; + $detected = false; + + //Get involved artifacts + $attacker_artefact = $database->getArtifactsValueInfluence($AttackerID, $AttackerWref, 3, 1, false); + $defender_artefact = $database->getArtifactsValueInfluence($DefenderID, $DefenderWref, 3, 1, false); + $strongerbuildings = $database->getArtifactsValueInfluence($DefenderID, $DefenderWref, 1, 1, false); + $isWWVillage = $database->getVillageField($DefenderWref, 'natar'); + + if(isset($Attacker['uhero']) && $Attacker['uhero'] > 0){ + $atkhero = $this->getBattleHero($AttackerID); + } + if(isset($Defender['hero']) && $Defender['hero'] > 0){ + $defenderhero = $this->getBattleHero($DefenderID); + } + //own defender units + if ($type == 1) { + $datadefScout = $this->getDataDefScout($Defender, $def_ab, $defender_artefact); + $dp += $datadefScout['dp']; + $cdp += $datadefScout['cdp']; + $involve = $datadefScout['involve']; + if(!$detected && $datadefScout['detect']) $detected = $datadefScout['detect']; + }else{ + $datadef = $this->getDataDef($Defender, $def_ab); + $dp += $datadef['dp']; + $cdp += $datadef['cdp']; + $involve = $datadef['involve']; + if(isset($Defender['hero']) && $Defender['hero'] != 0){ + $units['Def_unit']['hero'] = $Defender['hero']; + $cdp += $defenderhero['dc']; + $dp += $defenderhero['di']; + $dp *= $defenderhero['db']; + $cdp *= $defenderhero['db']; + } + } + $DefendersAll = (!is_null($defReinforcements) ? $database->getEnforceVillage($DefenderWref, 0) : $defReinforcements); - /* - ================================================= - = 5. CASUALTIES - ================================================= - */ + if(!empty($DefendersAll) && $DefenderWref > 0){ + // preload village IDs + $vilIDs = []; + foreach($DefendersAll as $defenders) { + $vilIDs[$defenders['from']] = true; + $vilIDs[$defenders['to']] = true; + } + $vilIDs = array_keys($vilIDs); + $database->getABTech($vilIDs); - $result['casualties_attacker'] = - $this->calculateCasualties($Attacker, $ratio, $att_tribe); + foreach($DefendersAll as $defenders) { + for ($i = 1; $i <= 50; $i++) $def_ab[$i] = 0; + $fromvillage = $defenders['from']; - /* - ================================================= - = 6. BOUNTY - ================================================= - */ + $userdataCache[$fromvillage] = $database->getUserArray($database->getVillageField($fromvillage, "owner"), 1); - $result['bounty'] = - $this->calculateBounty($Attacker, $result['casualties_attacker'], $att_tribe); + $enforcetribe = $userdataCache[$fromvillage]["tribe"]; + $ud=($enforcetribe - 1) * 10; + if($defenders['from'] > 0) { //don't check nature tribe + $armory = $database->getABTech($defenders['from']); // Armory level every village enforcement + $def_ab[$ud + 1] = $armory['a1']; + $def_ab[$ud + 2] = $armory['a2']; + $def_ab[$ud + 3] = $armory['a3']; + $def_ab[$ud + 4] = $armory['a4']; + $def_ab[$ud + 5] = $armory['a5']; + $def_ab[$ud + 6] = $armory['a6']; + $def_ab[$ud + 7] = $armory['a7']; + $def_ab[$ud + 8] = $armory['a8']; + } + if ($type == 1) { + $datadefScout = $this->getDataDefScout($defenders, $def_ab, $defender_artefact); + $dp += $datadefScout['dp']; + $cdp += $datadefScout['cdp']; + $involve = $datadefScout['involve']; + if(!$detected && $datadefScout['detect']) $detected = $datadefScout['detect']; + }else{ + $datadef = $this->getDataDef($defenders, $def_ab); + $dp += $datadef['dp']; + $cdp += $datadef['cdp']; + $involve = $datadef['involve']; + } + $reinfowner = $database->getVillageField($fromvillage, "owner"); + $defhero = $this->getBattleHero($reinfowner); + + //calculate def hero from enforcement + if($defenders['hero'] != 0){ + $cdp += $defhero['dc']; + $dp += $defhero['di']; + $dp *= $defhero['db']; + $cdp *= $defhero['db']; + } + } + } + // Calculate the total number of points Attacker + $start = ($att_tribe - 1) * 10 + 1; + $end = $att_tribe * 10; + + if($att_tribe == 3) $abcount = 3; + else $abcount = 4; + if($type == 1) {//scout + for($i = $start;$i <= $end; $i++) { + global ${'u'.$i}; + $j = $i - $start + 1; + if($Attacker['u'.$i] > 0 && ($i == 4 || $i == 14 || $i == 23 || $i == 44)){ + if(${'att_ab'.$abcount} > 0) { + $ap += round(35 + (35 + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, ${'att_ab'.$abcount}) - 1), 4) * $Attacker['u'.$i]; + } + else $ap += $Attacker['u'.$i] * 35; + } + $involve += $Attacker['u'.$i]; + $units['Att_unit'][$i] = $Attacker['u'.$i]; + + } + $ap *= $attacker_artefact; + + }else{ //type=3 normal 4=raid + $abcount = 1; + for($i = $start; $i <= $end; $i++) { + global ${'u'.$i}; + $j = $i - $start + 1; + if($abcount <= 8 && ${'att_ab'.$abcount} > 0) { + if(in_array($i,$calvary)) { + $cap += round(${'u'.$i}['atk'] + (${'u'.$i}['atk'] + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, ${'att_ab'.$abcount}) - 1), 4) * (int) $Attacker['u'.$i]; + }else{ + $ap += round(${'u'.$i}['atk'] + (${'u'.$i}['atk'] + 300 * ${'u'.$i}['pop'] / 7) * (pow(1.007, ${'att_ab'.$abcount}) - 1), 4) * (int) $Attacker['u'.$i]; + } + }else{ + if(in_array($i,$calvary)) $cap += (int) $Attacker['u'.$i]*${'u'.$i}['atk']; + else $ap += (int) $Attacker['u'.$i]*${'u'.$i}['atk']; + } + + $abcount += 1; + + // Points catapult the attacker + if(in_array($i, $catapult)) $catp += (int) $Attacker['u'.$i]; + + // Points of the Rams attacker + if(in_array($i, $rams)) $ram += (int) $Attacker['u'.$i]; + + $involve += (int) $Attacker['u'.$i]; + $units['Att_unit'][$i] = (int) $Attacker['u'.$i]; + } + if (isset($Attacker['uhero']) && $Attacker['uhero'] != 0){ + $units['Att_unit']['hero'] = $Attacker['uhero']; + $ap *= $atkhero['ob']; + $cap *= $atkhero['ob']; + $ap += $atkhero['atk']; + } + + if ($offhero > 0 || $hero_strenght > 0) { + $atkhero= $this->getBattleHeroSim($offhero); + $ap *= $atkhero['ob']; + $cap *= $atkhero['ob']; + $ap += $hero_strenght; + } + if ($deffhero > 0) { + $dfdhero = $this->getBattleHeroSim($deffhero); + $dp *= $dfdhero['ob']; + $cdp *= $dfdhero['ob']; + } + } + // Formula for calculating the bonus defensive wall and Residence + + if($def_wall > 0) { + // Set the factor calculation for the "wall" as the type of the civilization + // Factor = 1030 Wall Roman + // Factor = 1020 Wall Teuton + // Factor = 1025 Wall Goul + $factor = ($def_tribe == 1)? 1.030 : (($def_tribe == 2)? 1.020 : 1.025); + $wallMultiplier = round(pow($factor, $def_wall), 3); + // Defense infantry = Infantry * Wall (%) + // Defense calvary calvary = * Wall (%) + if ($dp > 0 || $cdp > 0){ + if($type == 1) { + $dp *= $wallMultiplier; + $dp += 10; + }else{ + $dp *= $wallMultiplier; + $cdp *= $wallMultiplier; + + // Calculation of the Basic defense bonus "Residence" + $dp += (2 * (pow($residence, 2)) + 10) * $wallMultiplier; + $cdp += (2 * (pow($residence, 2)) + 10) * $wallMultiplier; + } + }else{ + $dp = 10 * $wallMultiplier * $def_wall; + // Defense calvary calvary = * Wall (%) + $cdp = 10 * $wallMultiplier * $def_wall; + if($type != 1){ + // Calculation of the Basic defense bonus "Residence" + $dp += (2 * (pow($residence, 2)) + 10) * $wallMultiplier; + $cdp += (2 * (pow($residence, 2)) + 10) * $wallMultiplier; + }else{ + $dp += 10; + $cdp = 0; + } + } + }elseif($type != 1) { + + // Calculation of the Basic defense bonus "Residence" + $dp += (2 * (pow($residence, 2)) + 10); + $cdp += (2 * (pow($residence, 2)) + 10); + } + + // Formula for calculating Attacking Points (Infantry & Cavalry) + if($AttackerWref != 0){ + $rap = round(($ap + $cap) + (($ap + $cap) / 100 * (isset($bid35[$this->getTypeLevel(35, $AttackerWref)]) ? $bid35[$this->getTypeLevel(35, $AttackerWref)]['attri'] : 0))); + } + else $rap = round($ap + $cap); + + // Formula for calculating Defensive Points + if ($rap == 0) $rdp = round(($dp) + ($cdp)); + else $rdp = round(round($cap / $rap, 4) * ($cdp) + round($ap / $rap, 4) * ($dp)); + + // The Winner is....: + $result['Attack_points'] = $rap; + $result['Defend_points'] = $rdp; + $winner = ($rap > $rdp); + + // Formula for calculating the Morale bonus + // WW villages aren't affected by this bonus + if($attpop > $defpop && !$isWWVillage) { + $moralbonus = 1 / round(max(0.667, pow($defpop / $attpop, 0.2 * min(1, $rap / ($rdp > 0 ? $rdp : 1)))), 3); + } + else $moralbonus = 1.0; + + if($involve >= 1000 && $type != 1) $Mfactor = 2 * round((1.8592 - pow($involve, 0.015)), 4); + else $Mfactor = 1.5; + + if ($Mfactor < 1.2578) $Mfactor = 1.2578; + elseif ($Mfactor > 1.5) $Mfactor = 1.5; + + // Formula for calculating losses + // $type = 1 Scout, 2 Enforcement + // $type = 3 Normal, 4 Raid + if($type == 1){ + $holder = pow((($rdp * $moralbonus) / $rap), $Mfactor); + if($holder > 1) $holder = 1; + if ($rdp > $rap) $holder = 1; + + //Birds of Prey cannot die when scouting + //Spies cannot die if the attacked village has no defending spies + //Attacker result + $result[1] = ($att_tribe == 5 || !$detected) ? 0 : $holder; + + //Defender result + $result[2] = 0; + }else if($type == 4) { + $holder = ($winner) ? pow((($rdp * $moralbonus) / $rap), $Mfactor) : pow(($rap / ($rdp * $moralbonus)), $Mfactor); + $holder = $holder / (1 + $holder); + //Attacker result + $result[1] = $winner ? $holder : 1 - $holder; + //Defender result + $result[2] = $winner ? 1 - $holder : $holder; + $ram -= round($ram * $result[1] / 100); + $catp -= round($catp * $result[1] / 100); + }else if($type == 3){ + + // Attacker + $result[1] = ($winner) ? pow((($rdp * $moralbonus) / $rap), $Mfactor) : 1; + + if ($result[1] > 1){ + $result[1] = 1; + $winner = false; + $result['Winner'] = "defender"; + } + + // Defender + $result[2] = (!$winner) ? pow(($rap / ($rdp * $moralbonus)), $Mfactor) : 1; + + if ($result[1] == 1) $result[2] = pow(($rap / ($rdp * $moralbonus)), $Mfactor); + + if ($result[2] > 1) { + $result[2] = 1; + $result['Winner'] = "attacker"; + $winner = true; + } + + // If attacked with "Hero" + $ku = ($att_tribe - 1) * 10 + 9; + $kings = (int) $Attacker['u'.$ku]; + + $aviables = $kings - round($kings * (int) $result[1]); + if ($aviables > 0){ + switch($aviables){ + case 1: $fealthy = rand(20, 30); break; + case 2: $fealthy = rand(40, 60); break; + case 3: $fealthy = rand(60, 80); break; + case 4: $fealthy = rand(80, 100); break; + default: $fealthy = 100; break; + } + $result['hero_fealthy'] = $fealthy; + } + + $ram -= ($winner) ? round($ram * $result[1] / 100) : round($ram * $result[2] / 100); + $catp -= ($winner) ? round($catp * $result[1] / 100) : round($catp * $result[2] / 100); + } + + if($catp > 0 && $tblevel != 0) { + + //Catapults blacksmith upgrades + $upgrades = round(200 * pow(1.0205, $att_ab8)) / 200; + + //Buildings durability + $durability = ($stonemason > 0 ? $bid34[$stonemason]['attri'] / 100 : 1); + + //Calculates the catapults morale bonus + $catpMoraleBonus = min(max(($attpop / ($defpop > 0 ? $defpop : 1)) ** 0.3, 1), 3); + + //New level of the building (only for warsim.php) + $catapultsDamage = $this->calculateCatapultsDamage($catp, $upgrades, $durability, $rap / $rdp, $strongerbuildings, $catpMoraleBonus); + $result[3] = $this->calculateNewBuildingLevel($tblevel, $catapultsDamage); + $result[4] = $tblevel; + + //Results for Automation.php + $result['catapults']['upgrades'] = $upgrades; + $result['catapults']['durability'] = $durability; + $result['catapults']['attackDefenseRatio'] = $rap / $rdp; + $result['catapults']['strongerBuildings'] = $strongerbuildings; + $result['catapults']['moraleBonus'] = $catpMoraleBonus; + } + + if($ram > 0 && $walllevel != 0) { + + //Rams blacksmith upgrades + $upgrades = round(200 * pow(1.0205, $att_ab7)) / 200; + + //Building durability + $durability = ($stonemason > 0 ? $bid34[$stonemason]['attri'] / 100 : 1); + + // New level of the building (only for warsim.php) + $ramsDamage = $this->calculateCatapultsDamage($ram, $upgrades, $durability, $rap / $rdp, $strongerbuildings, 1); + $result[7] = $this->calculateNewBuildingLevel($walllevel, $ramsDamage); + $result[8] = $walllevel; + + // Results for Automation.php + $result['rams']['upgrades'] = $upgrades; + $result['rams']['durability'] = $durability; + $result['rams']['attackDefenseRatio'] = $rap / $rdp; + $result['rams']['strongerBuildings'] = $strongerbuildings; + $result['rams']['moraleBonus'] = 1; + } + + $result[6] = pow($rap / ($rdp * $moralbonus > 0 ? $rdp * $moralbonus : 1), $Mfactor); + $result['moralBonus'] = $moralbonus; + + $total_att_units = count($units['Att_unit']); + $start = intval(($att_tribe - 1) * 10 + 1); + $end = intval($att_tribe * 10); + + for($i = $start; $i <= $end; $i++){ + $y = $i - (($att_tribe - 1) * 10); + $result['casualties_attacker'][$y] = round($result[1] * $units['Att_unit'][$i]); + } + + if (isset($units['Att_unit']['hero']) && $units['Att_unit']['hero'] >0){ + + $_result = mysqli_query($database->dblink,"select heroid, health from " . TB_PREFIX . "hero where `dead`='0' and `heroid`=".(int) $atkhero['heroid']); + $fdb = mysqli_fetch_array($_result); + $hero_id = (int) $fdb['heroid']; + $hero_health = $fdb['health']; + $damage_health = round(100 * $result[1]); + + if ($hero_health <= $damage_health || $damage_health > 90){ + //hero die + $result['casualties_attacker'][11] = 1; + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `dead` = 1, `health` = 0 where `heroid`=".(int) $hero_id); + }else{ + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `health`=`health`-".(int) $damage_health." where `heroid`=".(int) $hero_id); + } + } + unset($_result, $fdb, $hero_id, $hero_health, $damage_health); + + + if (isset($units['Def_unit']['hero']) && $units['Def_unit']['hero'] >0){ + + $_result = mysqli_query($database->dblink,"select heroid, health from " . TB_PREFIX . "hero where `dead`='0' and `heroid`=".(int) $defenderhero['heroid']); + $fdb = mysqli_fetch_array($_result); + $hero_id = (int) $fdb['heroid']; + $hero_health = $fdb['health']; + $damage_health = round(100 * $result[2]); + if ($hero_health <= $damage_health || $damage_health > 90){ + //hero die + $result['deadherodef'] = 1; + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `dead` = 1, `health` = 0 where `heroid`=".(int) $hero_id); + }else{ + $result['deadherodef'] = 0; + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `health`=`health`-".(int) $damage_health." where `heroid`=".(int) $hero_id); + } + } + unset($_result, $fdb, $hero_id, $hero_health, $damage_health); + + if(!empty($DefendersAll)){ + $battleHeroesCache = []; + foreach($DefendersAll as $defenders) { + if($defenders['hero'] > 0) { + $battleHeroesCache[$defenders['from']] = $this->getBattleHero($database->getVillageField($defenders['from'],"owner")); + $heroarraydefender = $battleHeroesCache[$defenders['from']]; + $_result = mysqli_query($database->dblink,"select heroid, health from " . TB_PREFIX . "hero where `dead`='0' and `heroid`=".(int) $heroarraydefender['heroid']); + $fdb = mysqli_fetch_array($_result); + $hero_id = (int) $fdb['heroid']; + $hero_health = $fdb['health']; + $damage_health = round(100 * $result[2]); + if ($hero_health <= $damage_health || $damage_health > 90){ + //hero die + $result['deadheroref'][$defenders['id']] = 1; + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `dead` = 1, `health` = 0 where `heroid`=".(int) $hero_id); + }else{ + $result['deadheroref'][$defenders['id']] = 0; + mysqli_query($database->dblink,"update " . TB_PREFIX . "hero set `health`=`health`-".(int) $damage_health." where `heroid`=".(int) $hero_id); + } + } + } + } + unset($_result, $fdb, $hero_id, $hero_health, $damage_health); + + + // Work out bounty + $start = ($att_tribe - 1) * 10 + 1; + $end = ($att_tribe * 10); + + $max_bounty = 0; + + for($i = $start; $i <= $end; $i++) { + $j = $i - $start + 1; + $y = $i -(($att_tribe - 1) * 10); + + $max_bounty += ((int) $Attacker['u'.$i] - (int) $result['casualties_attacker'][$y]) * (int) ${'u'.$i}['cap']; + } + + $result['bounty'] = $max_bounty; return $result; } - /* - ===================================================== - = ATTACK / DEFENSE HELPERS - ===================================================== - */ + public function getDataDefScout($defenders, $def_ab, $defender_artefact) { + $abcount = 1; + $invol = $dp = $cdp = 0; + $detected = false; + + for($y = 4; $y <= 50; $y++) { + if($y == 4 || $y == 14 || $y == 23 || $y == 44){ + global ${'u'.$y}; - private function calculateAttackPoints($Attacker, $tribe) - { - $start = ($tribe - 1) * 10 + 1; - $end = $tribe * 10; - - $points = 0; - - for ($i = $start; $i <= $end; $i++) { - global ${'u'.$i}; - $points += (int)$Attacker['u'.$i] * ${'u'.$i}['atk']; + if($defenders['u'.$y] > 0 && $def_ab[$y] > 0){ + $dp += round(20 + (20 + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab[$y]) - 1), 4) * $defenders['u'.$y] * $defender_artefact; + $detected = true; + }else{ + if($defenders['u'.$y] > 0){ + $dp += $defenders['u'.$y] * 20 * $defender_artefact; + $detected = true; + } + } + + $invol += $defenders['u'.$y]; //total troops + $units['Def_unit'][$y] = $defenders['u'.$y]; + } } - return $points; + $datadef['dp'] = $dp; + $datadef['cdp'] = $cdp; + $datadef['detect'] = $detected; + $datadef['involve'] = $invol; + return $datadef; } - private function calculateDefensePoints($Defender) - { - $points = 0; + public function getDataDef($defenders,$def_ab) { + $dp = $cdp = $invol = 0; + for($y = 1;$y <= 50; $y++) { + global ${'u'.$y}; + if ($defenders['u'.$y] > 0) { + if (!isset($def_ab[$y])) { + $def_ab[$y] = 0; + } + if ($def_ab[$y] > 0) { + $dp += round(${'u'.$y}['di'] + (${'u'.$y}['di'] + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab[$y]) - 1), 4) * $defenders['u'.$y]; + $cdp += round(${'u'.$y}['dc'] + (${'u'.$y}['dc'] + 300 * ${'u'.$y}['pop'] / 7) * (pow(1.007, $def_ab[$y]) - 1), 4) * $defenders['u'.$y]; + }else{ + $dp += $defenders['u'.$y] * ${'u'.$y}['di']; + $cdp += $defenders['u'.$y] * ${'u'.$y}['dc']; + } - for ($i = 1; $i <= 50; $i++) { - global ${'u'.$i}; - $points += (int)$Defender['u'.$i] * ${'u'.$i}['di']; + } + $invol += $defenders['u'.$y]; //total troops + $units['Def_unit'][$y] = $defenders['u'.$y]; } - - return $points; + $datadef['dp'] = $dp; + $datadef['cdp'] = $cdp; + $datadef['involve'] = $invol; + return $datadef; } - - private function applyWallBonus($defPoints, $wall, $tribe, $residence) - { - if ($wall <= 0) { - return $defPoints + (2 * pow($residence,2) + 10); - } - - $factor = ($tribe == 1) - ? 1.030 - : (($tribe == 2) ? 1.020 : 1.025); - - return $defPoints * pow($factor, $wall); + + /** + * @author Kirilloid --> https://github.com/kirilloid/travian/blob/master/src/model/base/combat.ts + * + * Calculates the new building level, after damaging it + * + * @param int $oldLevel The old building level + * @param float $damage The damage done by catapults + * @return int Returns the new building level + */ + + public function calculateNewBuildingLevel($oldLevel, $damage){ + $damage -= 0.5; + if ($damage < 0) return $oldLevel; + + while ($damage >= $oldLevel && $oldLevel) $damage -= $oldLevel--; + + return $oldLevel; } - - private function calculateCasualties($Attacker, $ratio, $tribe) - { - $casualties = []; - - $start = ($tribe - 1) * 10 + 1; - $end = $tribe * 10; - - for ($i = $start; $i <= $end; $i++) { - $index = $i - (($tribe - 1) * 10); - $casualties[$index] = - round($ratio * (int)$Attacker['u'.$i]); - } - - return $casualties; + + /** + * @author Kirilloid --> https://github.com/kirilloid/travian/blob/master/src/model/base/combat.ts + * + * Calculates the damage done by catapults + * + * @param int $catapultsQuantity The quantity of catapults which take part in the attack + * @param double $catapultsUpgrade The catapults upgrade multiplier, affected by the cataputls level in the blacksmith + * @param double $durability The building durability, affected by the stonemason's lodge + * @param double $ADRatio The attack points / defensive points ratio + * @param double $strongerBuildings The artifacts multiplier, which strengthens the building, affected by durability artifacts + * @param double $moraleBonus The defender morale bonus + * @return double Returns the damage done by catapults + */ + + public function calculateCatapultsDamage($catapultsQuantity, $catapultsUpgrade, $durability, $ADRatio, $strongerBuildings, $moraleBonus){ + $catapultsEfficiency = floor($catapultsQuantity / ($durability * $strongerBuildings)); + return 4 * ($this->sigma)($ADRatio) * $catapultsEfficiency * $catapultsUpgrade / $moraleBonus; } - - private function calculateBounty($Attacker, $casualties, $tribe) - { - $start = ($tribe - 1) * 10 + 1; - $end = $tribe * 10; - - $bounty = 0; - - for ($i = $start; $i <= $end; $i++) { - global ${'u'.$i}; - $index = $i - (($tribe - 1) * 10); - - $alive = (int)$Attacker['u'.$i] - (int)$casualties[$index]; - - $bounty += $alive * (int)${'u'.$i}['cap']; - } - - return $bounty; - } -} +}; $battle = new Battle; ?> diff --git a/GameEngine/Chat.php b/GameEngine/Chat.php index 04e50c0e..b71624c5 100755 --- a/GameEngine/Chat.php +++ b/GameEngine/Chat.php @@ -4,7 +4,6 @@ ## --------------------------------------------------------------------------- ## ## Filename Chat.php ## ## Developed by: TTMMTT ## -## Refactored by: Shadow ## ## License: TravianZ Project ## ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## ## ## @@ -12,196 +11,377 @@ if (!isset($SAJAX_INCLUDED)) { - $GLOBALS['sajax_version'] = '0.12'; - $GLOBALS['sajax_debug_mode'] = 0; - $GLOBALS['sajax_export_list'] = []; - $GLOBALS['sajax_request_type'] = 'GET'; - $GLOBALS['sajax_remote_uri'] = $_SERVER['REQUEST_URI'] ?? ''; - $GLOBALS['sajax_failure_redirect'] = ''; + $GLOBALS['sajax_version'] = '0.12'; + $GLOBALS['sajax_debug_mode'] = 0; + $GLOBALS['sajax_export_list'] = array(); + $GLOBALS['sajax_request_type'] = 'GET'; + $GLOBALS['sajax_remote_uri'] = ''; + $GLOBALS['sajax_failure_redirect'] = ''; - /* ============================== - SECURITY HELPERS - ============================== */ - function sajax_safe_string($value) { - return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); - } + function sajax_init() { + } - function sajax_validate_function($func_name) { - global $sajax_export_list; - return in_array($func_name, $sajax_export_list, true); - } + function sajax_get_my_uri() { + return $_SERVER["REQUEST_URI"]; + } + $sajax_remote_uri = sajax_get_my_uri(); - /* ============================== - CLIENT REQUEST HANDLER (HARDENED) - ============================== */ - function sajax_handle_client_request() { + function sajax_get_js_repr($value) { + $type = gettype($value); - global $sajax_export_list; + if ($type == "boolean") { + return ($value) ? "Boolean(true)" : "Boolean(false)"; + } + elseif ($type == "integer") { + return "parseInt($value)"; + } + elseif ($type == "double") { + return "parseFloat($value)"; + } + elseif ($type == "array" || $type == "object" ) { - $mode = ''; + $s = "{ "; + if ($type == "object") { + $value = get_object_vars($value); + } + foreach ($value as $k=>$v) { + $esc_key = sajax_esc($k); + if (is_numeric($k)) + $s .= "$k: " . sajax_get_js_repr($v) . ", "; + else + $s .= "\"$esc_key\": " . sajax_get_js_repr($v) . ", "; + } + if (count($value)) + $s = substr($s, 0, -2); + return $s . " }"; + } + else { + $esc_val = sajax_esc($value); + $s = "'$esc_val'"; + return $s; + } + } - if (isset($_GET['rs'])) $mode = 'get'; - if (isset($_POST['rs'])) $mode = 'post'; + function sajax_handle_client_request() { + global $sajax_export_list; - if (!$mode) return; + $mode = ""; - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Pragma: no-cache"); + if (! empty($_GET["rs"])) + $mode = "get"; - $func_name = $mode === 'get' - ? (string)$_GET['rs'] - : (string)$_POST['rs']; + if (!empty($_POST["rs"])) + $mode = "post"; - $args = $mode === 'get' - ? ($_GET['rsargs'] ?? []) - : ($_POST['rsargs'] ?? []); + if (empty($mode)) + return; - if (!is_array($args)) { - $args = [$args]; - } + $target = ""; - if (!sajax_validate_function($func_name) || !function_exists($func_name)) { - echo "-:Function not callable"; - exit; - } + if ($mode == "get") { - echo "+:"; - $result = call_user_func_array($func_name, $args); - echo "var res = " . trim(sajax_get_js_repr($result)) . "; res;"; - exit; - } + header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - /* ============================== - SAFE JS ENCODER - ============================== */ + header ("Cache-Control: no-cache, must-revalidate"); + header ("Pragma: no-cache"); + $func_name = $_GET["rs"]; + if (! empty($_GET["rsargs"])) + $args = $_GET["rsargs"]; + else + $args = array(); + } + else { + $func_name = $_POST["rs"]; + if (! empty($_POST["rsargs"])) + $args = $_POST["rsargs"]; + else + $args = array(); + } - function sajax_get_js_repr($value) { + if (! in_array($func_name, $sajax_export_list)) + echo "-:$func_name not callable"; + else { + echo "+:"; + $result = call_user_func_array($func_name, $args); + echo "var res = " . trim(sajax_get_js_repr($result)) . "; res;"; + } + exit; + } - if (is_bool($value)) { - return $value ? "Boolean(true)" : "Boolean(false)"; - } + function sajax_get_common_js() { + global $sajax_debug_mode; + global $sajax_request_type; + global $sajax_remote_uri; + global $sajax_failure_redirect; - if (is_int($value)) { - return "parseInt($value)"; - } + $t = strtoupper($sajax_request_type); + if ($t != "" && $t != "GET" && $t != "POST") + return "// Invalid type: $t.. \n\n"; - if (is_float($value)) { - return "parseFloat($value)"; - } + ob_start(); + ?> - if (is_array($value) || is_object($value)) { + // remote scripting library + // (c) copyright 2005 modernmethod, inc + // edited by ttmtt + var sajax_debug_mode = ; + var sajax_request_type = ""; + var sajax_target_id = ""; + var sajax_failure_redirect = ""; - $value = (array)$value; - $pairs = []; + function sajax_debug(text) { + if (sajax_debug_mode) + alert(text); + } - foreach ($value as $k => $v) { - $k = sajax_safe_string($k); - $pairs[] = is_numeric($k) - ? "$k: " . sajax_get_js_repr($v) - : "\"$k\": " . sajax_get_js_repr($v); - } + function sajax_init_object() { + sajax_debug("sajax_init_object() called..") - return "{ " . implode(', ', $pairs) . " }"; - } + var A; - return "'" . sajax_safe_string($value) . "'"; - } + var msxmlhttp = new Array( + 'Msxml2.XMLHTTP.5.0', + 'Msxml2.XMLHTTP.4.0', + 'Msxml2.XMLHTTP.3.0', + 'Msxml2.XMLHTTP', + 'Microsoft.XMLHTTP'); + for (var i = 0; i < msxmlhttp.length; i++) { + try { + A = new ActiveXObject(msxmlhttp[i]); + } catch (e) { + A = null; + } + } - function sajax_export() { - global $sajax_export_list; - foreach (func_get_args() as $func) { - if (is_string($func)) { - $sajax_export_list[] = $func; - } - } - } + if(!A && typeof XMLHttpRequest != "undefined") + A = new XMLHttpRequest(); + if (!A) + sajax_debug("Could not create connection object."); + return A; + } - $SAJAX_INCLUDED = 1; + var sajax_requests = new Array(); + + function sajax_cancel() { + for (var i = 0; i < sajax_requests.length; i++) + sajax_requests[i].abort(); + } + + function sajax_do_call(func_name, args) { + var i, x, n; + var uri; + var post_data; + var target_id; + + sajax_debug("in sajax_do_call().." + sajax_request_type + "/" + sajax_target_id); + target_id = sajax_target_id; + if (typeof(sajax_request_type) == "undefined" || sajax_request_type == "") + sajax_request_type = "GET"; + + uri = ""; + if (sajax_request_type == "GET") { +// alert(args); + if (uri.indexOf("?") == -1) + uri += "?rs=" + escape(func_name); + else + uri += "&rs=" + escape(func_name); + uri += "&rst=" + escape(sajax_target_id); + uri += "&rsrnd=" + new Date().getTime(); + + for (i = 0; i < args.length-1; i++) { + uri += "&rsargs[]=" + args[i]; + } + post_data = null; + } + else if (sajax_request_type == "POST") { + post_data = "rs=" + escape(func_name); + post_data += "&rst=" + escape(sajax_target_id); + post_data += "&rsrnd=" + new Date().getTime(); + + for (i = 0; i < args.length-1; i++) + post_data = post_data + "&rsargs[]=" + escape(args[i]); + } + else { + alert("Illegal request type: " + sajax_request_type); + } + + x = sajax_init_object(); + if (x == null) { + if (sajax_failure_redirect != "") { + location.href = sajax_failure_redirect; + return false; + } else { + sajax_debug("NULL sajax object for user agent:\n" + navigator.userAgent); + return false; + } + } else { + x.open(sajax_request_type, uri, true); + // window.open(uri); + + sajax_requests[sajax_requests.length] = x; + + if (sajax_request_type == "POST") { + x.setRequestHeader("Method", "POST " + uri + " HTTP/1.1"); + x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + } + + x.onreadystatechange = function() { + if (x.readyState != 4) + return; + + sajax_debug("received " + x.responseText); + + var status; + var data; + var txt = x.responseText.replace(/^\s*|\s*$/g,""); + status = txt.charAt(0); + data = txt.substring(2); + + if (status == "") { + // let's just assume this is a pre-response bailout and let it slide for now + } else if (status == "-") + alert("Error: " + data); + else { + if (target_id != "") + document.getElementById(target_id).innerHTML = eval(data); + else { + try { + var callback; + var extra_data = false; + if (typeof args[args.length-1] == "object") { + callback = args[args.length-1].callback; + extra_data = args[args.length-1].extra_data; + } else { + callback = args[args.length-1]; + } + callback(eval(data), extra_data); + } catch (e) { + sajax_debug("Caught error " + e + ": Could not eval " + data ); + } + } + } + } + } + + sajax_debug(func_name + " uri = " + uri + "/post = " + post_data); + x.send(post_data); + sajax_debug(func_name + " waiting.."); + delete x; + return true; + } + + + + // wrapper for + + function x_() { + sajax_do_call("", + x_.arguments); + } + + escape($msg); +// $msg=htmlspecialchars($msg); + $name = addslashes($session->username); - global $session, $database; + if ($msg != ""){ + $id_user = (int) $session->uid; + $alliance = $database->escape($session->alliance); + $now = time(); + echo $q = "INSERT into ".TB_PREFIX."chat (id_user,name,alli,date,msg) values ($id_user,'$name','$alliance','$now','$msg')"; + mysqli_query($database->dblink,$q); + } + } - if (!$session->uid) return; + function get_data() { + global $session,$database; - $msg = is_array($data) ? ($data[1] ?? '') : $data; - $msg = trim((string)$msg); + $alliance = $database->escape($session->alliance); + $query = mysqli_query($database->dblink,"select id_user, name, date, msg from ".TB_PREFIX."chat where alli='$alliance' order by id desc limit 0,13"); + while ($r = mysqli_fetch_array($query)) { + $dates = date("g:i",$r['date']); + $data .= "[{$dates}] {$r['name']}: {$r['msg']}
"; + } + return $data; + } - if ($msg === '') return; + $sajax_request_type = "GET"; + sajax_init(); + sajax_export("add_data","get_data"); + sajax_handle_client_request(); - $id_user = (int)$session->uid; - $name = $database->escape($session->username); - $alliance = $database->escape($session->alliance); - $now = time(); - - $stmt = mysqli_prepare( - $database->dblink, - "INSERT INTO ".TB_PREFIX."chat (id_user, name, alli, date, msg) VALUES (?, ?, ?, ?, ?)" - ); - - if ($stmt) { - mysqli_stmt_bind_param($stmt, "issis", - $id_user, - $name, - $alliance, - $now, - $msg - ); - mysqli_stmt_execute($stmt); - mysqli_stmt_close($stmt); - } -} - -function get_data() { - - global $session, $database; - - $alliance = $database->escape($session->alliance); - - $stmt = mysqli_prepare( - $database->dblink, - "SELECT id_user, name, date, msg - FROM ".TB_PREFIX."chat - WHERE alli = ? - ORDER BY id DESC - LIMIT 13" - ); - - $data = ''; - - if ($stmt) { - mysqli_stmt_bind_param($stmt, "s", $alliance); - mysqli_stmt_execute($stmt); - $result = mysqli_stmt_get_result($stmt); - - while ($r = mysqli_fetch_assoc($result)) { - - $dates = date("H:i", (int)$r['date']); - $uid = (int)$r['id_user']; - - $username = sajax_safe_string($r['name']); - $message = sajax_safe_string($r['msg']); - - $data .= "[{$dates}] {$username}: {$message}
"; - } - - mysqli_stmt_close($stmt); - } - - return $data; -} - -/* ============================== - SAJAX BOOTSTRAP -============================== */ - -$sajax_request_type = "GET"; -sajax_export("add_data", "get_data"); -sajax_handle_client_request(); +?> diff --git a/GameEngine/Database.php b/GameEngine/Database.php index e81cb16b..15a9af43 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -1036,24 +1036,6 @@ public function getBestOasisCropBonus($x, $y) { $result = mysqli_query($this->dblink,$q); return $this->mysqli_fetch_all($result); } - - // Add to Database.php - function checkAttackRateLimit($uid, $maxPerMinute = 30) { - $uid = (int)$uid; - $oneMinuteAgo = time() - 60; - - // Count recent attacks from this user - $q = "SELECT COUNT(*) as cnt FROM " . TB_PREFIX . "movement m - JOIN " . TB_PREFIX . "vdata v ON m.from = v.wref - WHERE v.owner = $uid - AND m.sort_type = 3 - AND m.starttime > $oneMinuteAgo"; - - $result = mysqli_query($this->dblink, $q); - $row = mysqli_fetch_assoc($result); - - return ($row['cnt'] < $maxPerMinute); - } function getVrefField($ref, $field, $use_cache = true) { return $this->getVillage($ref, 0, $use_cache)[$field]; diff --git a/GameEngine/Form.php b/GameEngine/Form.php index 2b7d2e4b..2196c091 100755 --- a/GameEngine/Form.php +++ b/GameEngine/Form.php @@ -9,107 +9,67 @@ ## ## ################################################################################# -class Form -{ - private array $errorarray = []; - public array $valuearray = []; - private int $errorcount = 0; +class Form { - public function __construct() - { - if ( - isset($_SESSION['errorarray'], $_SESSION['valuearray']) && - is_array($_SESSION['errorarray']) && - is_array($_SESSION['valuearray']) - ) { + private $errorarray = array(); + public $valuearray = array(); + private $errorcount; - // Defensive copy (avoid reference issues) - $this->errorarray = $this->sanitizeArray($_SESSION['errorarray']); - $this->valuearray = $this->sanitizeArray($_SESSION['valuearray']); - $this->errorcount = count($this->errorarray); + public function __construct() { + if(isset($_SESSION['errorarray']) && isset($_SESSION['valuearray'])) { + $this->errorarray = $_SESSION['errorarray']; + $this->valuearray = $_SESSION['valuearray']; + $this->errorcount = count($this->errorarray); - unset($_SESSION['errorarray'], $_SESSION['valuearray']); - } - } + unset($_SESSION['errorarray']); + unset($_SESSION['valuearray']); + } + else $this->errorcount = 0; + } - /* ============================== - INTERNAL SANITIZER - ============================== */ + public function addError($field,$error) { + $this->errorarray[$field] = $error; + $this->errorcount = count($this->errorarray); + } - private function sanitizeArray(array $array): array - { - $clean = []; + public function getError($field) { + if(array_key_exists($field,$this->errorarray)) { + return $this->errorarray[$field]; + } + else return ""; + } - foreach ($array as $key => $value) { + public function getValue($field) { + if(array_key_exists($field,$this->valuearray)) { + return $this->valuearray[$field]; + } + else return ""; + } + + public function setValue($field, $value) { + $this->valuearray[$field] = $value; + } - // Force string keys - $safeKey = (string)$key; + public function getDiff($field,$cookie) { + if(array_key_exists($field,$this->valuearray) && $this->valuearray[$field] != $cookie) { + return $this->valuearray[$field]; + } + else return $cookie; + } - // Prevent object injection / unexpected types - if (is_scalar($value) || is_null($value)) { - $clean[$safeKey] = $value; - } else { - $clean[$safeKey] = ''; - } - } + public function getRadio($field,$value) { + if(array_key_exists($field,$this->valuearray) && $this->valuearray[$field] == $value) { + return "checked"; + } + else return ""; + } - return $clean; - } + public function returnErrors() { + return $this->errorcount; + } - /* ============================== - PUBLIC API (UNCHANGED BEHAVIOR) - ============================== */ - - public function addError($field, $error): void - { - $this->errorarray[(string)$field] = $error; - $this->errorcount = count($this->errorarray); - } - - public function getError($field) - { - return $this->errorarray[(string)$field] ?? ""; - } - - public function getValue($field) - { - return $this->valuearray[(string)$field] ?? ""; - } - - public function setValue($field, $value): void - { - $this->valuearray[(string)$field] = $value; - } - - public function getDiff($field, $cookie) - { - $field = (string)$field; - - if (isset($this->valuearray[$field]) && $this->valuearray[$field] != $cookie) { - return $this->valuearray[$field]; - } - - return $cookie; - } - - public function getRadio($field, $value) - { - $field = (string)$field; - - if (isset($this->valuearray[$field]) && $this->valuearray[$field] == $value) { - return "checked"; - } - - return ""; - } - - public function returnErrors(): int - { - return $this->errorcount; - } - - public function getErrors(): array - { - return $this->errorarray; - } -} + public function getErrors() { + return $this->errorarray; + } +}; +?> \ No newline at end of file diff --git a/GameEngine/Generator.php b/GameEngine/Generator.php index 729eb7bb..65900738 100755 --- a/GameEngine/Generator.php +++ b/GameEngine/Generator.php @@ -9,193 +9,136 @@ ## ## ################################################################################# -class MyGenerator -{ - /* =============================== - RANDOM GENERATORS - =============================== */ +class MyGenerator { - public function generateRandID() - { - return md5($this->generateRandStr(16)); - } + public function generateRandID(){ + return md5($this->generateRandStr(16)); + } - public function generateRandStr($length) - { - $length = (int)$length; - if ($length <= 0) return ''; + public function generateRandStr($length){ + $randstr = ""; + for($i = 0; $i < $length; $i++){ + $randnum = random_int(0, 61); + if($randnum < 10) $randstr .= chr($randnum + 48); + else if($randnum < 36) $randstr .= chr($randnum + 55); + else $randstr .= chr($randnum + 61); + } + return $randstr; + } - // Hard cap to prevent abuse - if ($length > 256) $length = 256; + public function encodeStr($str, $length) { + $encode = md5($str); + return substr($encode, 0 ,$length); + } - $randstr = ''; + public function procDistanceTime($coor, $thiscoor, $ref, $mode, $vid = 0) { + global $database, $bid28, $bid14, $village; - for ($i = 0; $i < $length; $i++) { - $randnum = random_int(0, 61); + if($vid == 0) $vid = $village->wid; + + $xdistance = ABS($thiscoor['x'] - $coor['x']); + if($xdistance > WORLD_MAX) $xdistance = (2 * WORLD_MAX + 1) - $xdistance; + + $ydistance = ABS($thiscoor['y'] - $coor['y']); + if($ydistance > WORLD_MAX) $ydistance = (2 * WORLD_MAX + 1) - $ydistance; + + $distance = SQRT(POW($xdistance,2) + POW($ydistance,2)); + if(!$mode){ + if($ref == 1) $speed = 16; + else if($ref == 2) $speed = 12; + else if($ref == 3) $speed = 24; + else if($ref == 300) $speed = 5; + else $speed = 1; + }else{ + $speed = $ref; + if(($tSquareLevel = $database->getFieldLevelInVillage($vid, 14)) > 0 && $distance >= TS_THRESHOLD) { + $speed *= ($bid14[$tSquareLevel]['attri'] / 100) ; + } + } + + if($speed > 0) return round(($distance / $speed) * 3600 / INCREASE_SPEED); + else return round($distance * 3600 / INCREASE_SPEED); + } - if ($randnum < 10) { - $randstr .= chr($randnum + 48); - } elseif ($randnum < 36) { - $randstr .= chr($randnum + 55); - } else { - $randstr .= chr($randnum + 61); - } - } + public function getTimeFormat($time) { + $min = $hr = $days = 0; + + while($time >= 60){ + $time -= 60; + $min += 1; + } + + while($min >= 60){ + $min -= 60; + $hr += 1; + } + + if($min < 10) $min = "0" . $min; + if($time < 10) $time = "0" . $time; + + return $hr . ":" . $min . ":" . $time; + } - return $randstr; - } + public function procMtime($time, $pref = 3){ + /* + * $timezone = 7; + * switch($timezone) { + * case 7: + * $time -= 3600; + * break; + * } + */ + // $time += 3600*0; //Edit this yourself + $time += 0; // Edit this yourself + + $today = date('d', time()) - 1; + if(date('Ymd', time()) == date('Ymd', $time)) $day = "today"; + elseif($today == date('d', $time)) $day = "yesterday"; + else + { + switch($pref){ + case 1 : + $day = date("m/j/y", $time); + break; + case 2 : + $day = date("j/m/y", $time); + break; + case 3 : + $day = date("j.m.y", $time); + break; + default : + $day = date("y/m/j", $time); + break; + } + } + $new = date("H:i:s", $time); + if($pref == "9" || $pref == 9) return $new; + else return array($day, $new); + } - public function encodeStr($str, $length) - { - $length = (int)$length; - if ($length <= 0) return ''; - $hash = md5((string)$str); + public function getBaseID($x, $y){ + return ((WORLD_MAX - $y) * (WORLD_MAX * 2 + 1)) + (WORLD_MAX + $x + 1); + } - if ($length > 32) $length = 32; + public function getMapCheck($wref){ + return substr(md5($wref), 5, 2); + } - return substr($hash, 0, $length); - } + public function pageLoadTimeStart(){ + if(isset($_SERVER["REQUEST_TIME_FLOAT"])) return $_SERVER["REQUEST_TIME_FLOAT"]; + $starttime = microtime(true); + $startarray = explode(" ", $starttime); + //$starttime = $startarray[1] + $startarray[0]; + return $startarray[0]; + } - /* =============================== - DISTANCE / TIME CALCULATIONS - =============================== */ + public function pageLoadTimeEnd(){ + $endtime = microtime(true); + $endarray = explode(" ", $endtime); + //$endtime = $endarray[1] + $endarray[0]; + return $endarray[0]; + } - public function procDistanceTime($coor, $thiscoor, $ref, $mode, $vid = 0) - { - global $database, $bid28, $bid14, $village; - - if ($vid == 0 && isset($village->wid)) { - $vid = (int)$village->wid; - } - - $x1 = (int)$thiscoor['x']; - $y1 = (int)$thiscoor['y']; - $x2 = (int)$coor['x']; - $y2 = (int)$coor['y']; - - $xdistance = abs($x1 - $x2); - if ($xdistance > WORLD_MAX) { - $xdistance = (2 * WORLD_MAX + 1) - $xdistance; - } - - $ydistance = abs($y1 - $y2); - if ($ydistance > WORLD_MAX) { - $ydistance = (2 * WORLD_MAX + 1) - $ydistance; - } - - $distance = sqrt(pow($xdistance, 2) + pow($ydistance, 2)); - - if (!$mode) { - switch ((int)$ref) { - case 1: $speed = 16; break; - case 2: $speed = 12; break; - case 3: $speed = 24; break; - case 300: $speed = 5; break; - default: $speed = 1; break; - } - } else { - $speed = (float)$ref; - - if ($speed > 0) { - $tSquareLevel = (int)$database->getFieldLevelInVillage($vid, 14); - - if ($tSquareLevel > 0 && $distance >= TS_THRESHOLD) { - if (isset($bid14[$tSquareLevel]['attri'])) { - $speed *= ($bid14[$tSquareLevel]['attri'] / 100); - } - } - } - } - - if ($speed <= 0) { - return round($distance * 3600 / INCREASE_SPEED); - } - - return round(($distance / $speed) * 3600 / INCREASE_SPEED); - } - - /* =============================== - TIME FORMATTING - =============================== */ - - public function getTimeFormat($time) - { - $time = (int)$time; - if ($time < 0) $time = 0; - - $hr = floor($time / 3600); - $min = floor(($time % 3600) / 60); - $sec = $time % 60; - - return sprintf("%d:%02d:%02d", $hr, $min, $sec); - } - - public function procMtime($time, $pref = 3) - { - $time = (int)$time; - $pref = (int)$pref; - - $today = date('Ymd'); - $target = date('Ymd', $time); - - if ($today === $target) { - $day = "today"; - } elseif (date('Ymd', strtotime("-1 day")) === $target) { - $day = "yesterday"; - } else { - switch ($pref) { - case 1: $day = date("m/j/y", $time); break; - case 2: $day = date("j/m/y", $time); break; - case 3: $day = date("j.m.y", $time); break; - default:$day = date("y/m/j", $time); break; - } - } - - $clock = date("H:i:s", $time); - - if ($pref === 9) { - return $clock; - } - - return [$day, $clock]; - } - - /* =============================== - MAP HELPERS - =============================== */ - - public function getBaseID($x, $y) - { - $x = (int)$x; - $y = (int)$y; - - return ((WORLD_MAX - $y) * (WORLD_MAX * 2 + 1)) + (WORLD_MAX + $x + 1); - } - - public function getMapCheck($wref) - { - $wref = (int)$wref; - return substr(md5((string)$wref), 5, 2); - } - - /* =============================== - PAGE LOAD TIMERS - =============================== */ - - public function pageLoadTimeStart() - { - if (isset($_SERVER["REQUEST_TIME_FLOAT"])) { - return (float)$_SERVER["REQUEST_TIME_FLOAT"]; - } - - return microtime(true); - } - - public function pageLoadTimeEnd() - { - return microtime(true); - } -} - -$generator = new MyGenerator(); +}; +$generator = new MyGenerator; diff --git a/GameEngine/Logging.php b/GameEngine/Logging.php index 9730a306..d8d763d1 100755 --- a/GameEngine/Logging.php +++ b/GameEngine/Logging.php @@ -5,187 +5,106 @@ ## --------------------------------------------------------------------------- ## ## Filename Logging.php ## ## License: TravianZ Project ## -## Refactor by: Shadow ## ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## ## ## ################################################################################# class Logging { - /* ============================== - INTERNAL SAFE EXECUTOR - ============================== */ + public function addIllegal($uid,$ref,$type) { + global $database; + list($uid,$ref,$type) = $database->escape_input((int) $uid,$ref,$type); + if(LOG_ILLEGAL) { + $log = "Attempted to "; + switch($type) { + case 1: + $log .= "access village $ref"; + break; + } + $q = "Insert into ".TB_PREFIX."illegal_log SET user = $uid, log = '$log'"; + $database->query($q); + } + } - private function safeInsert($query, $types, $params) { - global $database; + public function addLoginLog($id,$ip) { + global $database; + list($id,$ip) = $database->escape_input((int) $id,$ip); + if(LOG_LOGIN) { + $q = "Insert into ".TB_PREFIX."login_log SET uid = $id, ip = '".$_SERVER['REMOTE_ADDR']."'"; + $database->query($q); + } + } - $stmt = mysqli_prepare($database->dblink, $query); - if ($stmt) { - mysqli_stmt_bind_param($stmt, $types, ...$params); - mysqli_stmt_execute($stmt); - mysqli_stmt_close($stmt); - } - } + public function addBuildLog($wid,$building,$level,$type) { + global $database; + list($wid,$building,$level,$type) = $database->escape_input((int) $wid,$building,$level,$type); + if(LOG_BUILD) { + if($type) { + $log = "Start Construction of "; + } + else { + $log = "Start Upgrade of "; + } + $log .= $building." to level ".$level; + $q = "Insert into ".TB_PREFIX."build_log SET wid = $wid, log = '$log'"; + $database->query($q); + } + } - /* ============================== - ILLEGAL LOG - ============================== */ + public function addTechLog($wid,$tech,$level) { + global $database; + list($wid,$tech,$level) = $database->escape_input((int) $wid,$tech,$level); + if(LOG_TECH) { + $log = "Upgrading of tech ".$tech." to level ".$level; + $q = "Insert into ".TB_PREFIX."tech_log SET wid = $wid, log = '$log'"; + $database->query($q); + } + } - public function addIllegal($uid, $ref, $type) { - if (!LOG_ILLEGAL) return; + public function goldFinLog($wid) { + global $database; + list($wid) = $database->escape_input((int) $wid); + if(LOG_GOLD_FIN) { + $log = "Finish construction and research with gold"; + $q = "Insert into ".TB_PREFIX."gold_fin_log values (0,$wid,'$log')"; + $database->query($q); + } + } - $uid = (int)$uid; - $ref = (string)$ref; - $type = (int)$type; + public function addAdminLog() { + global $database; + } - $log = "Attempted to "; - if ($type === 1) { - $log .= "access village " . $ref; - } + public function addMarketLog($wid,$type,$data) { + global $database; + list($wid,$type,$data) = $database->escape_input((int) $wid,$type,$data); + if(LOG_MARKET) { + if($type == 1) { + $log = "Sent ".$data[0].",".$data[1].",".$data[2].",".$data[3]." to village ".$data[4]; + } + else if($type == 2) { + $log = "Traded resource between ".$wid." and ".$data[0]." market ref is ".$data[1]; + } + $q = "Insert into ".TB_PREFIX."market_log SET wid = $wid, log = '$log'"; + $database->query($q); + } + } - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."illegal_log (user, log) VALUES (?, ?)", - "is", - array($uid, $log) - ); - } + public function addWarLog() { + global $database; + } - /* ============================== - LOGIN LOG - ============================== */ + public function clearLogs() { + global $database; + } - public function addLoginLog($id, $ip) { - if (!LOG_LOGIN) return; + public static function debug($debug_info, $time = 0) { + global $database, $generator; + list($debug_info) = $database->escape_input($debug_info); + + echo ''; + } +}; - $id = (int)$id; - $ip = $_SERVER['REMOTE_ADDR'] ?? ''; - - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."login_log (uid, ip) VALUES (?, ?)", - "is", - array($id, $ip) - ); - } - - /* ============================== - BUILD LOG - ============================== */ - - public function addBuildLog($wid, $building, $level, $type) { - if (!LOG_BUILD) return; - - $wid = (int)$wid; - $building = (string)$building; - $level = (int)$level; - $type = (int)$type; - - $log = $type - ? "Start Construction of " - : "Start Upgrade of "; - - $log .= $building . " to level " . $level; - - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."build_log (wid, log) VALUES (?, ?)", - "is", - array($wid, $log) - ); - } - - /* ============================== - TECH LOG - ============================== */ - - public function addTechLog($wid, $tech, $level) { - if (!LOG_TECH) return; - - $wid = (int)$wid; - $tech = (string)$tech; - $level = (int)$level; - - $log = "Upgrading of tech " . $tech . " to level " . $level; - - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."tech_log (wid, log) VALUES (?, ?)", - "is", - array($wid, $log) - ); - } - - /* ============================== - GOLD FINISH LOG - ============================== */ - - public function goldFinLog($wid) { - if (!LOG_GOLD_FIN) return; - - $wid = (int)$wid; - $log = "Finish construction and research with gold"; - - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."gold_fin_log (wid, log) VALUES (?, ?)", - "is", - array($wid, $log) - ); - } - - /* ============================== - MARKET LOG - ============================== */ - - public function addMarketLog($wid, $type, $data) { - if (!LOG_MARKET) return; - - $wid = (int)$wid; - $type = (int)$type; - - if (!is_array($data)) return; - - if ($type === 1) { - $log = "Sent " - . (int)$data[0] . "," - . (int)$data[1] . "," - . (int)$data[2] . "," - . (int)$data[3] - . " to village " . (int)$data[4]; - } - elseif ($type === 2) { - $log = "Traded resource between " - . $wid . " and " - . (int)$data[0] - . " market ref is " - . (int)$data[1]; - } else { - return; - } - - $this->safeInsert( - "INSERT INTO ".TB_PREFIX."market_log (wid, log) VALUES (?, ?)", - "is", - array($wid, $log) - ); - } - - /* ============================== - DEBUG (SAFE) - ============================== */ - - public static function debug($debug_info, $time = 0) { - global $generator; - - $prefix = ''; - - if ($time > 0 && isset($generator)) { - $t = $generator->procMtime($time); - if (is_array($t) && isset($t[1])) { - $prefix = "[" . $t[1] . "] "; - } - } - - $safe = json_encode($prefix . (string)$debug_info, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); - - echo ""; - } -} - -$logging = new Logging(); +$logging = new Logging; +?> diff --git a/GameEngine/Mailer.php b/GameEngine/Mailer.php index ade3148d..ca35c36a 100755 --- a/GameEngine/Mailer.php +++ b/GameEngine/Mailer.php @@ -1,9 +1,10 @@ sanitizeEmail($email); - if (!$email) return false; - - $username = $this->sanitizeBody($username); - $pass = $this->sanitizeBody($pass); - $act = $this->sanitizeBody($act); - - $subject = "Welcome to " . SERVER_NAME; - - $message = -"Hello ".$username." + $message = "Hello ".$username." Thank you for your registration. @@ -66,69 +32,38 @@ Click the following link in order to activate your account: Greetings, Travian adminision"; - $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL); + $headers = "From: ".ADMIN_EMAIL."\n"; - return mail($email, $subject, $message, $headers); - } + mail($email, $subject, $message, $headers); + } - /* ===================================================== - SEND INVITE (BACKWARD COMPATIBLE) - ====================================================== */ + function sendInvite($email,$uid,$text) { - public function sendInvite($email, $uid, $text, $username = null) { + $subject = "".SERVER_NAME." registeration"; - $email = $this->sanitizeEmail($email); - if (!$email) return false; - - $uid = (int)$uid; - $text = $this->sanitizeBody($text); - $username = $username !== null ? $this->sanitizeBody($username) : ''; - - $subject = SERVER_NAME . " registeration"; - - $greeting = $username !== '' - ? "Hello " . $username - : "Hello"; - - $message = -$greeting." + $message = "Hello ".$username." Try the new ".SERVER_NAME."! + Link: ".SERVER."anmelden.php?id=ref".$uid." ".$text." + Greetings, Travian"; - $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL); + $headers = "From: ".ADMIN_EMAIL."\n"; - return mail($email, $subject, $message, $headers); - } + mail($email, $subject, $message, $headers); + } - /* ===================================================== - SEND PASSWORD RESET - ====================================================== */ + function sendPassword($email,$uid,$username,$npw,$cpw) { - public function sendPassword($email, $uid, $username, $npw, $cpw) { + $subject = "Password forgotten"; - $email = $this->sanitizeEmail($email); - if (!$email) return false; - - $uid = (int)$uid; - $username = $this->sanitizeBody($username); - $npw = $this->sanitizeBody($npw); - $cpw = $this->sanitizeBody($cpw); - - $host = isset($_SERVER['HTTP_HOST']) - ? $this->sanitizeHeader($_SERVER['HTTP_HOST']) - : 'localhost'; - - $subject = "Password forgotten"; - - $message = -"Hello ".$username." + $message = "Hello ".$username." You have requested a new password for Travian. @@ -140,20 +75,21 @@ Password: ".$npw." Please click this link to activate your new password. The old password then becomes invalid: -http://".$host."/password.php?cpw=".$cpw."&npw=".$uid." +http://${_SERVER['HTTP_HOST']}/password.php?cpw=$cpw&npw=$uid If you want to change your new password, you can enter a new one in your profile on tab \"account\". In case you did not request a new password you may ignore this email. -Travian"; +Travian +"; - $headers = "From: " . $this->sanitizeHeader(ADMIN_EMAIL); + $headers = "From: ".ADMIN_EMAIL."\n"; - return mail($email, $subject, $message, $headers); - } -} + mail($email, $subject, $message, $headers); + } -$mailer = new Mailer(); -?> +}; +$mailer = new Mailer; +?> \ No newline at end of file diff --git a/GameEngine/Market.php b/GameEngine/Market.php index 8f89ea7b..75ad7bf2 100755 --- a/GameEngine/Market.php +++ b/GameEngine/Market.php @@ -5,7 +5,6 @@ ## Filename Market.php ## ## Developed by: Dzoki ## ## Some fixes: aggenkeech ## -## Refactor: Shadow ## ## License: TravianZ Project ## ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## ## ## @@ -13,532 +12,377 @@ class Market { - public $onsale = array(); - public $onmarket = array(); - public $sending = array(); - public $recieving = array(); - public $return = array(); - public $maxcarry = 0; - public $merchant = 0; - public $used = 0; - - /* ========================================================= - INPUT NORMALIZATION LAYER - ========================================================== */ - - private function int($value) { - return (int)$value; - } - - private function str($value) { - return trim((string)$value); - } - - private function arr($value) { - return is_array($value) ? $value : array(); - } - - private function safeRedirect($url) { - header("Location: ".$url); - exit; - } - - /* ========================================================= - MARKET ENTRY POINT - ========================================================== */ + public $onsale, $onmarket, $sending, $recieving, $return = []; + public $maxcarry, $merchant, $used; public function procMarket($post) { $this->loadMarket(); - - if(isset($_SESSION['loadMarket'])) { + if(isset($_SESSION['loadMarket'])) + { $this->loadOnsale(); unset($_SESSION['loadMarket']); } - - if(!is_array($post) || !isset($post['ft'])) { - return; - } - - $ft = $this->str($post['ft']); - - switch($ft) { - case "mk1": - $this->sendResource($post); - break; - case "mk2": - $this->addOffer($post); - break; - case "mk3": - $this->tradeResource($post); - break; + if(isset($post['ft'])) + { + switch($post['ft']) + { + case "mk1": $this->sendResource($post); break; + case "mk2": $this->addOffer($post); break; + case "mk3": $this->tradeResource($post); break; + } } } - /* ========================================================= - REMOVE / ACCEPT HANDLER - ========================================================== */ - public function procRemove($get) { global $database, $village, $session; - if(!is_array($get)) return; - - $t = isset($get['t']) ? $this->int($get['t']) : 0; - $id = isset($get['id']) ? $this->int($get['id']) : 0; - - if($t === 1) { + if(isset($get['t']) && $get['t'] == 1) + { $this->filterNeed($get); } - - if($t === 2 - && isset($get['a']) - && $this->int($get['a']) === 5 - && isset($get['del'])) + else if(isset($get['t']) && $get['t'] == 2 && isset($get['a']) && $get['a'] == 5 && isset($get['del'])) { - $del = $this->int($get['del']); - - $type = $database->getMarketField($village->wid, $del, "gtype"); - $amt = $database->getMarketField($village->wid, $del, "gamt"); - + //GET ALL FIELDS FROM MARKET + $type = $database->getMarketField($village->wid, $get['del'], "gtype"); + $amt = $database->getMarketField($village->wid, $get['del'], "gamt"); $database->getResourcesBack($village->wid, $type, $amt); - $database->addMarket($village->wid, $del, 0,0,0,0,0,0,1); - - $this->safeRedirect("build.php?id=".$id."&t=2"); + $database->addMarket($village->wid, $get['del'], 0, 0, 0, 0, 0, 0, 1); + header("Location: build.php?id=".$get['id']."&t=2"); + exit; } - - if($t === 1 - && isset($get['a']) - && $this->int($get['a']) === $session->mchecker - && !isset($get['del'])) + if(isset($get['t']) && $get['t'] == 1 && isset($get['a']) && $get['a'] == $session->mchecker && !isset($get['del'])) { $session->changeChecker(); - $this->acceptOffer($get); + $this->acceptOffer($get); } } - /* ========================================================= - MERCHANTS - ========================================================== */ - public function merchantAvail() { - return max(0, $this->merchant - $this->used); + return $this->merchant - $this->used; } - - /* ========================================================= - LOAD MARKET DATA - ========================================================== */ private function loadMarket() { global $session,$building,$bid28,$bid17,$database,$village; $this->recieving = $database->getMovement(0,$village->wid,1); - $this->sending = $database->getMovement(0,$village->wid,0); - $this->return = $database->getMovement(2,$village->wid,1); - - $lvl17 = $building->getTypeLevel(17); - $this->merchant = ($lvl17 > 0) ? $bid17[$lvl17]['attri'] : 0; - - $this->used = (int)$database->totalMerchantUsed($village->wid); + $this->sending = $database->getMovement(0,$village->wid,0); + $this->return = $database->getMovement(2,$village->wid,1); + $this->merchant = ($building->getTypeLevel(17) > 0)? $bid17[$building->getTypeLevel(17)]['attri'] : 0; + $this->used = $database->totalMerchantUsed($village->wid); $this->onmarket = $database->getMarket($village->wid,0); - - $baseCarry = ($session->tribe == 1) - ? 500 - : (($session->tribe == 2) ? 1000 : 750); - - $this->maxcarry = $baseCarry * TRADER_CAPACITY; - - $lvl28 = $building->getTypeLevel(28); - if($lvl28 > 0) { - $this->maxcarry *= $bid28[$lvl28]['attri'] / 100; + $this->maxcarry = ($session->tribe == 1)? 500 : (($session->tribe == 2)? 1000 : 750); + $this->maxcarry *= TRADER_CAPACITY; + if($building->getTypeLevel(28) != 0) + { + $this->maxcarry *= $bid28[$building->getTypeLevel(28)]['attri'] / 100; } } - /* ========================================================= - SEND RESOURCE (FULL HARDENED) - ========================================================== */ - private function sendResource($post) { global $database, $village, $session, $generator, $logging, $form; - if(!is_array($post)) return; - - $r1 = isset($post['r1']) ? max(0,$this->int($post['r1'])) : 0; - $r2 = isset($post['r2']) ? max(0,$this->int($post['r2'])) : 0; - $r3 = isset($post['r3']) ? max(0,$this->int($post['r3'])) : 0; - $r4 = isset($post['r4']) ? max(0,$this->int($post['r4'])) : 0; - - $getwref = isset($post['getwref']) ? $this->int($post['getwref']) : 0; - $repeat = isset($post['send3']) ? $this->int($post['send3']) : 1; - $buildId = isset($post['id']) ? $this->int($post['id']) : 0; - - if($getwref <= 0) { - $form->addError("error", NO_COORDINATES_SELECTED); - return; - } - - if(!$database->checkVilExist($getwref)) { - $form->addError("error", NO_COORDINATES_SELECTED); - return; - } - - if($getwref == $village->wid) { - $form->addError("error", CANNOT_SEND_RESOURCES); - return; - } - - if($repeat < 1 || $repeat > 3 || ($repeat > 1 && !$session->goldclub)) { - $form->addError("error", INVALID_MERCHANTS_REPETITION); - return; - } - + $wtrans = (isset($post['r1']) && !empty($post['r1']))? $post['r1'] : 0; + $ctrans = (isset($post['r2']) && !empty($post['r2']))? $post['r2'] : 0; + $itrans = (isset($post['r3']) && !empty($post['r3']))? $post['r3'] : 0; + $crtrans = (isset($post['r4']) && !empty($post['r4']))? $post['r4'] : 0; + $wtrans = str_replace("-", "", $wtrans); + $ctrans = str_replace("-", "", $ctrans); + $itrans = str_replace("-", "", $itrans); + $crtrans = str_replace("-", "", $crtrans); + + // preload all village data, since we're retrieving some of those separately below $database->getVillage($village->wid); - $availableWood = (int)$database->getWoodAvailable($village->wid); - $availableClay = (int)$database->getClayAvailable($village->wid); - $availableIron = (int)$database->getIronAvailable($village->wid); - $availableCrop = (int)$database->getCropAvailable($village->wid); + $availableWood = $database->getWoodAvailable($village->wid); + $availableClay = $database->getClayAvailable($village->wid); + $availableIron = $database->getIronAvailable($village->wid); + $availableCrop = $database->getCropAvailable($village->wid); + + //check if on vacation: + if($database->getvacmodexy($id)) $form->addError("error", USER_ON_VACATION); - if( - $availableWood < $r1 || - $availableClay < $r2 || - $availableIron < $r3 || - $availableCrop < $r4 - ) { - $form->addError("error", TOO_FEW_RESOURCES); - return; + if(!$database->checkVilExist($post['getwref'])) $form->addError("error", NO_COORDINATES_SELECTED); + elseif($post['getwref'] == $village->wid) $form->addError("error", CANNOT_SEND_RESOURCES); + elseif($post['send3'] < 1 || $post['send3'] > 3 || ($post['send3'] > 1 && !$session->goldclub)) $form->addError("error", INVALID_MERCHANTS_REPETITION); + elseif($availableWood >= $post['r1'] && $availableClay >= $post['r2'] && $availableIron >= $post['r3'] && $availableCrop >= $post['r4']) + { + $resource = [$wtrans, $ctrans, $itrans, $crtrans]; + $reqMerc = ceil((array_sum($resource) - 0.1) / $this->maxcarry); + + if($this->merchantAvail() > 0 && $reqMerc <= $this->merchantAvail()) + { + $id = $post['getwref']; + $coor = $database->getCoor($id); + if($database->getVillageState($id)) + { + $timetaken = $generator->procDistanceTime($coor, $village->coor, $session->tribe, 0); + $res = $resource[0] + $resource[1] + $resource[2] + $resource[3]; + if($res != 0){ + $reference = $database->sendResource($resource[0], $resource[1], $resource[2], $resource[3], $reqMerc, 0); + $database->modifyResource($village->wid, $resource[0], $resource[1], $resource[2], $resource[3], 0); + $database->addMovement(0, $village->wid, $id, $reference, time(), time() + $timetaken, $post['send3']); + $logging->addMarketLog($village->wid, 1, [$resource[0], $resource[1], $resource[2], $resource[3], $id]); + } + } + header("Location: build.php?id=".$post['id']); + exit; + } + else $form->addError("error", TOO_FEW_MERCHANTS); } - - $total = $r1 + $r2 + $r3 + $r4; - if($total <= 0) return; - - $reqMerc = ceil(($total - 0.1) / $this->maxcarry); - - if($this->merchantAvail() <= 0 || $reqMerc > $this->merchantAvail()) { - $form->addError("error", TOO_FEW_MERCHANTS); - return; - } - - if(!$database->getVillageState($getwref)) { - return; - } - - $coor = $database->getCoor($getwref); - $timetaken = $generator->procDistanceTime( - $coor, - $village->coor, - $session->tribe, - 0 - ); - - $reference = $database->sendResource( - $r1,$r2,$r3,$r4,$reqMerc,0 - ); - - $database->modifyResource( - $village->wid, - $r1,$r2,$r3,$r4, - 0 - ); - - $database->addMovement( - 0, - $village->wid, - $getwref, - $reference, - time(), - time() + $timetaken, - $repeat - ); - - $logging->addMarketLog( - $village->wid, - 1, - array($r1,$r2,$r3,$r4,$getwref) - ); - - $this->safeRedirect("build.php?id=".$buildId); + else $form->addError("error", TOO_FEW_RESOURCES); } - /* ========================================================= - ADD OFFER (ANTI EXPLOIT HARDENED) - ========================================================== */ - private function addOffer($post) { global $database,$village,$session; - if(!is_array($post)) return; - $rid1 = isset($post['rid1']) ? $this->int($post['rid1']) : 0; - $rid2 = isset($post['rid2']) ? $this->int($post['rid2']) : 0; - $m1 = isset($post['m1']) ? max(0,$this->int($post['m1'])) : 0; - $m2 = isset($post['m2']) ? max(0,$this->int($post['m2'])) : 0; - $buildId = isset($post['id']) ? $this->int($post['id']) : 0; - - if($rid1 < 1 || $rid1 > 4 || $rid2 < 1 || $rid2 > 4) { - $this->safeRedirect("build.php?id=".$buildId."&t=2&e2"); + if($post['rid1'] == $post['rid2']) + { + // Trading res for res of same type (invalid) + header("Location: build.php?id=".$post['id']."&t=2&e2"); + exit; } - - if($rid1 === $rid2 || $m1 <= 0 || $m2 <= 0) { - $this->safeRedirect("build.php?id=".$buildId."&t=2&e2"); + elseif(!isset($post['m1']) || !isset($post['m2']) || $post['m1'] <= 0 || $post['m2'] <= 0) + { + // No resources selected (invalid) + header("Location: build.php?id=".$post['id']."&t=2&e2"); + exit; } - - if($m1 > (2 * $m2) || $m2 > (2 * $m1)) { - $this->safeRedirect("build.php?id=".$buildId."&t=2&e2"); + elseif($post['m1'] > (2 * $post['m2'])) + { + // Trade is for more than 2x (invalid) + header("Location: build.php?id=".$post['id']."&t=2&e2"); + exit; } - - $wood = ($rid1 === 1) ? $m1 : 0; - $clay = ($rid1 === 2) ? $m1 : 0; - $iron = ($rid1 === 3) ? $m1 : 0; - $crop = ($rid1 === 4) ? $m1 : 0; - - $database->getVillage($village->wid); - - if( - $database->getWoodAvailable($village->wid) < $wood || - $database->getClayAvailable($village->wid) < $clay || - $database->getIronAvailable($village->wid) < $iron || - $database->getCropAvailable($village->wid) < $crop - ) { - $this->safeRedirect("build.php?id=".$buildId."&t=2&e1"); + elseif($post['m2'] > (2 * $post['m1'])) + { + // Trade is for less than 0.5x (invalid) + header("Location: build.php?id=".$post['id']."&t=2&e2"); + exit; } - - $total = $wood + $clay + $iron + $crop; - $reqMerc = ceil(($total - 0.1) / $this->maxcarry); - - if($this->merchantAvail() <= 0 || $reqMerc > $this->merchantAvail()) { - $this->safeRedirect("build.php?id=".$buildId."&t=2&e3"); + elseif($post['rid1'] < 1 || $post['rid1'] > 4 || $post['rid2'] < 1 || $post['rid2'] > 4) + { + // Inexistent resources type (invalid) + header("Location: build.php?id=".$post['id']."&t=2&e2"); + exit; } + else + { + $wood = ($post['rid1'] == 1)? $post['m1'] : 0; + $clay = ($post['rid1'] == 2)? $post['m1'] : 0; + $iron = ($post['rid1'] == 3)? $post['m1'] : 0; + $crop = ($post['rid1'] == 4)? $post['m1'] : 0; - if($database->modifyResource($village->wid,$wood,$clay,$iron,$crop,0)) { + // preload all village data, since we're retrieving some of those separately below + $database->getVillage($village->wid); - $time = 0; - if(isset($post['d2'])) { - $time = $this->int($post['d2']) * 3600; + $availableWood = $database->getWoodAvailable($village->wid); + $availableClay = $database->getClayAvailable($village->wid); + $availableIron = $database->getIronAvailable($village->wid); + $availableCrop = $database->getCropAvailable($village->wid); + + if($availableWood >= $wood && $availableClay >= $clay && $availableIron >= $iron && $availableCrop >= $crop) + { + $reqMerc = 1; + + if(($wood+$clay+$iron+$crop) > $this->maxcarry) + { + $reqMerc = round(($wood+$clay+$iron+$crop)/$this->maxcarry); + + if(($wood+$clay+$iron+$crop) > $this->maxcarry*$reqMerc) $reqMerc += 1; + } + if($this->merchantAvail() > 0 && $reqMerc <= $this->merchantAvail()) + { + if($database->modifyResource($village->wid,$wood,$clay,$iron,$crop,0)) + { + $time = 0; + if(isset($_POST['d1'])) $time = $_POST['d2'] * 3600; + $alliance = (isset($post['ally']) && $post['ally'] == 1)? $session->userinfo['alliance'] : 0; + $database->addMarket($village->wid,$post['rid1'],$post['m1'],$post['rid2'],$post['m2'],$time,$alliance,$reqMerc,0); + } + // Enough merchants + header("Location: build.php?id=".$post['id']."&t=2"); + exit; + } + else + { + // Not enough merchants + header("Location: build.php?id=".$post['id']."&t=2&e3"); + exit; + } + } + else + { + // not enough resources + header("Location: build.php?id=".$post['id']."&t=2&e1"); + exit; } - - $alliance = (isset($post['ally']) && $this->int($post['ally']) === 1) - ? $session->userinfo['alliance'] - : 0; - - $database->addMarket( - $village->wid, - $rid1,$m1, - $rid2,$m2, - $time, - $alliance, - $reqMerc, - 0 - ); } - - $this->safeRedirect("build.php?id=".$buildId."&t=2"); } - /* ========================================================= - ACCEPT OFFER (ANTI DUPLICATE / FULL HARDENED) - ========================================================== */ - private function acceptOffer($get) { global $database,$village,$session,$logging,$generator; - if(!is_array($get) || !isset($get['g'])) return; - - $g = $this->int($get['g']); - $buildId = isset($get['id']) ? $this->int($get['id']) : 0; - - $infoarray = $database->getMarketInfo($g); - if(empty($infoarray)) { - $this->safeRedirect("build.php?id=".$buildId."&t=1"); + $infoarray = $database->getMarketInfo($get['g']); + $reqMerc = 1; + if($infoarray['wamt'] > $this->maxcarry) + { + $reqMerc = round($infoarray['wamt']/$this->maxcarry); + if($infoarray['wamt'] > $this->maxcarry*$reqMerc) + { + $reqMerc += 1; + } } - - $reqMerc = ceil(($infoarray['wamt'] - 0.1) / $this->maxcarry); - - $myResources = array( - 1 => $village->awood, - 2 => $village->aclay, - 3 => $village->airon, - 4 => $village->acrop - ); - - if($infoarray['wamt'] > $myResources[$infoarray['wtype']]) { - $this->safeRedirect("build.php?id=".$buildId."&t=1&e1"); + + // We don't have enough resources + if($infoarray['wamt'] > ([$village->awood, $village->aclay, $village->airon, $village->acrop])[$infoarray['wtype'] - 1]) + { + header("Location: build.php?id=".$get['id']."&t=1&e1"); + exit; + } // We're accepting the offering from the same village/of another alliance/with a too high maxtime + elseif + (($infoarray['vref'] == $village->wid) || + ($infoarray['alliance'] > 0 && $infoarray['alliance'] != $session->alliance) || + ($infoarray['maxtime'] > 0 && ($infoarray['maxtime'] * 3600) < $generator->procDistanceTime($database->getCoor($infoarray['vref']), $village->coor, $session->tribe, 0))) + { + header("Location: build.php?id=".$get['id']."&t=1&e2"); + exit; + } // We don't have enough merchants + elseif($reqMerc > $this->merchantAvail()){ + header("Location: build.php?id=".$get['id']."&t=1&e3"); + exit; } - - if( - $infoarray['vref'] == $village->wid || - ($infoarray['alliance'] > 0 && $infoarray['alliance'] != $session->alliance) - ) { - $this->safeRedirect("build.php?id=".$buildId."&t=1&e2"); - } - - if($reqMerc > $this->merchantAvail()) { - $this->safeRedirect("build.php?id=".$buildId."&t=1&e3"); - } - - /* =========================== - EXECUTE TRADE ATOMICALLY - ============================ */ - - $mySend = array(1=>0,0,0,0); - $mySend[$infoarray['wtype']] = $infoarray['wamt']; - - $hisSend = array(1=>0,0,0,0); - $hisSend[$infoarray['gtype']] = $infoarray['gamt']; - - $mysendid = $database->sendResource( - $mySend[1],$mySend[2],$mySend[3],$mySend[4], - $reqMerc,0 - ); - - $hissendid = $database->sendResource( - $hisSend[1],$hisSend[2],$hisSend[3],$hisSend[4], - $infoarray['merchant'],0 - ); - + + $myresource = $hisresource = [ 1=> 0, 0, 0, 0]; + $myresource[$infoarray['wtype']] = $infoarray['wamt']; + $mysendid = $database->sendResource($myresource[1],$myresource[2],$myresource[3],$myresource[4],$reqMerc,0); + $hisresource[$infoarray['gtype']] = $infoarray['gamt']; + $hissendid = $database->sendResource($hisresource[1],$hisresource[2],$hisresource[3],$hisresource[4],$infoarray['merchant'],0); $hiscoor = $database->getCoor($infoarray['vref']); - - $mytime = $generator->procDistanceTime( - $hiscoor,$village->coor,$session->tribe,0 - ); - - $targettribe = $database->getUserField( - $database->getVillageField($infoarray['vref'],"owner"), - "tribe", - 0 - ); - - $histime = $generator->procDistanceTime( - $village->coor,$hiscoor,$targettribe,0 - ); - + $mytime = $generator->procDistanceTime($hiscoor,$village->coor,$session->tribe,0); + $targettribe = $database->getUserField($database->getVillageField($infoarray['vref'],"owner"),"tribe",0); + $histime = $generator->procDistanceTime($village->coor,$hiscoor,$targettribe,0); $timestamp = time(); - $database->addMovement( - array(0,0), - array($village->wid,$infoarray['vref']), - array($infoarray['vref'],$village->wid), - array($mysendid,$hissendid), - array($timestamp,$timestamp), - array($mytime+$timestamp,$histime+$timestamp) + [0, 0], + [$village->wid, $infoarray['vref']], + [$infoarray['vref'], $village->wid], + [$mysendid, $hissendid], + [$timestamp, $timestamp], + [$mytime + $timestamp, $histime + $timestamp] ); - - $database->modifyResource( - $village->wid, - $mySend[1],$mySend[2],$mySend[3],$mySend[4], - 0 - ); - - $database->setMarketAcc($g); - $database->removeAcceptedOffer($g); - - $logging->addMarketLog( - $village->wid, - 2, - array($infoarray['vref'],$g) - ); - - $this->safeRedirect("build.php?id=".$buildId); + $resource = [1 => 0, 0, 0, 0]; + $resource[$infoarray['wtype']] = $infoarray['wamt']; + $database->modifyResource($village->wid, $resource[1], $resource[2], $resource[3], $resource[4], 0); + $database->setMarketAcc($get['g']); + $database->removeAcceptedOffer($get['g']); + $logging->addMarketLog($village->wid, 2, [$infoarray['vref'], $get['g']]); + header("Location: build.php?id=" . $get['id']); + exit; } - /* ========================================================= - LOAD ONSALE (SAFE FILTERED) - ========================================================== */ - private function loadOnsale() { global $database,$village,$session,$multisort,$generator; $displayarray = $database->getMarket($village->wid,1); - $holderarray = array(); - - foreach($displayarray as $value) { - + $holderarray = []; + foreach($displayarray as $value) + { $targetcoor = $database->getCoor($value['vref']); - - $duration = $generator->procDistanceTime( - $targetcoor, - $village->coor, - $session->tribe, - 0 - ); - - if($duration <= ($value['maxtime'] * 3600) || $value['maxtime'] == 0) { + $duration = $generator->procDistanceTime($targetcoor, $village->coor, $session->tribe, 0); + if($duration <= ($value['maxtime'] * 3600) || $value['maxtime'] == 0) + { $value['duration'] = $duration; - $holderarray[] = $value; + array_push($holderarray,$value); } } - $this->onsale = $multisort->sorte($holderarray, "duration", true, 2); } - /* ========================================================= - FILTER NEED (SAFE) - ========================================================== */ - private function filterNeed($get) { - if(empty($this->onsale)) return; - - $v = isset($get['v']) ? $this->str($get['v']) : null; - $s = isset($get['s']) ? $this->int($get['s']) : null; - $b = isset($get['b']) ? $this->int($get['b']) : null; - - $holder = array(); - - foreach($this->onsale as $sale) { - - if($v === "1:1" && $sale['wamt'] > $sale['gamt']) continue; - if($s && $sale['gtype'] != $s) continue; - if($b && $sale['wtype'] != $b) continue; - - $holder[] = $sale; + if(isset($get['v']) || isset($get['s']) || isset($get['b'])){ + $holder = $holder2 = []; + if(isset($get['v']) && $get['v'] == "1:1"){ + foreach($this->onsale as $equal){ + if($equal['wamt'] <= $equal['gamt']){ + array_push($holder, $equal); + } + } + } + else $holder = $this->onsale; + + foreach($holder as $sale){ + if(isset($get['s']) && isset($get['b'])){ + if($sale['gtype'] == $get['s'] && $sale['wtype'] == $get['b']){ + array_push($holder2, $sale); + } + }else if(isset($get['s']) && !isset($get['b'])){ + if($sale['gtype'] == $get['s']){ + array_push($holder2, $sale); + } + }else if(isset($get['b']) && !isset($get['s'])){ + if($sale['wtype'] == $get['b']){ + array_push($holder2, $sale); + } + } + else $holder2 = $holder; + } + $this->onsale = $holder2; } - - $this->onsale = $holder; + else $this->loadOnsale(); } - /* ========================================================= - GOLD TRADE (HARDENED) - ========================================================== */ - private function tradeResource($post) { global $session,$database,$village; - if(!is_array($post) || !isset($post['m2']) || !is_array($post['m2'])) return; + $wwvillage = $database->getResourceLevel($village->wid); + if($wwvillage['f99t'] != 40){ + if($session->userinfo['gold'] >= 3){ + // check that we're not trying to sell more resources that we actually have + if ( + (int) $post['m2'][0] < 0 && round($village->awood) + (int) $post['m2'][0] < 0 + || + (int) $post['m2'][1] < 0 && round($village->aclay) + (int) $post['m2'][1] < 0 + || + (int) $post['m2'][2] < 0 && round($village->airon) + (int) $post['m2'][2] < 0 + || + (int) $post['m2'][3] < 0 && round($village->acrop) + (int) $post['m2'][3] < 0 + ) { + header("Location: build.php?id=".$post['id']."&t=3"); + exit; + } - $buildId = isset($post['id']) ? $this->int($post['id']) : 0; - - if($session->userinfo['gold'] < 3) { - $this->safeRedirect("build.php?id=".$buildId."&t=3"); + //Check if there are too many resources + if ( ((int) $post['m2'][0] + (int) $post['m2'][1] + (int) $post['m2'][2] + (int) $post['m2'][3] ) <= ( round($village->awood) + round($village->aclay) + round($village->airon) + round($village->acrop) ) ) { + $database->setVillageField( + $village->wid, + ["wood", "clay", "iron", "crop"], + [$post['m2'][0], $post['m2'][1], $post['m2'][2], $post['m2'][3]] + ); + $database->modifyGold($session->uid, 3, 0); + header("Location: build.php?id=".$post['id']."&t=3&c"); + exit; + } else { + header("Location: build.php?id=".$post['id']."&t=3"); + exit; + } + }else{ + header("Location: build.php?id=".$post['id']."&t=3"); + exit; + } } - - $m2 = array( - isset($post['m2'][0]) ? $this->int($post['m2'][0]) : 0, - isset($post['m2'][1]) ? $this->int($post['m2'][1]) : 0, - isset($post['m2'][2]) ? $this->int($post['m2'][2]) : 0, - isset($post['m2'][3]) ? $this->int($post['m2'][3]) : 0 - ); - - $database->setVillageField( - $village->wid, - array("wood","clay","iron","crop"), - $m2 - ); - - $database->modifyGold($session->uid, 3, 0); - - $this->safeRedirect("build.php?id=".$buildId."&t=3&c"); } }; $market = new Market; ?> - diff --git a/GameEngine/Message.php b/GameEngine/Message.php index 399738c3..f8e40995 100755 --- a/GameEngine/Message.php +++ b/GameEngine/Message.php @@ -5,960 +5,682 @@ +---------------------------------------------------------+ | Credits: All the developers including the leaders: | | Advocaite & Dzoki & Donnchadh | -| Refactored by : Shadow | | | | Copyright: TravianZ Project All rights reserved | \** --------------------------------------------------- **/ class Message { - public $unread; - public $nunread = false; - public $note; - - public $inbox = array(); - public $inbox1 = array(); - public $sent = array(); - public $sent1 = array(); - public $archived = array(); - public $archived1 = array(); - - public $reading = array(); - public $reply = ''; - public $noticearray = array(); - public $readingNotice = array(); - - private $totalMessage = 0; - - /* ===================================================== */ - /* ================= CONSTRUCTOR ======================= */ - /* ===================================================== */ - - function __construct() { - - global $session; + public $unread, $nunread = false; + public $note; + public $inbox, $inbox1, $sent, $sent1, $reading, $reply, $archived, $archived1, $noticearray, $readingNotice = []; + private $totalMessage; + function __construct() { $req_file = basename($_SERVER['PHP_SELF']); - - $this->unread = $this->checkUnread(); + $this->unread = $this->checkUnread(); $this->nunread = $this->checkNUnread(); - if($req_file == 'nachrichten.php') { - - $t = isset($_GET['t']) ? trim($_GET['t']) : 1; - - switch($t) { - - case 2: - case '2a': - $this->getMessages(2); - break; - - case 3: - $this->getMessages(3); - break; - - default: - $this->getMessages(1); - break; - } - } - - if($req_file == 'berichte.php') { - $this->getNotice(); - } - - if(isset($_SESSION['reply'])) { - $this->reply = $_SESSION['reply']; - unset($_SESSION['reply']); - } - } - - /* ===================================================== */ - /* ================= SAFE HELPERS ====================== */ - /* ===================================================== */ - - private function sanitizeText($text) { - return htmlspecialchars(trim($text), ENT_QUOTES, 'UTF-8'); - } - - private function sanitizeInt($value) { - return (int)$value; - } - - private function preventFlood($uid) { - global $database; - - $uid = (int)$uid; - $limitTime = time() - 60; - - $query = "SELECT COUNT(*) as total - FROM ".TB_PREFIX."mdata - WHERE owner = {$uid} - AND time > {$limitTime}"; - - $result = mysqli_fetch_assoc(mysqli_query($database->dblink, $query)); - - if($result && $result['total'] > 5) { - return false; - } - - return true; - } - - private function safeRedirect($url) { - header("Location: ".$url); - exit; - } - - /* ===================================================== */ - /* ================= UNREAD ============================ */ - /* ===================================================== */ - - private function checkUnread() { - global $database, $session; - return (int)$database->getUnreadMessagesCount($session->uid); - } - - private function checkNUnread() { - global $database, $session; - return (int)$database->getUnreadNoticesCount($session->uid); - } - - /* ===================================================== */ - /* ================= NOTICE SYSTEM ===================== */ - /* ===================================================== */ - - public function noticeType($get) { - - global $session, $database; - - if(isset($get['t'])) { - - $type = null; - $t = (int)$get['t']; - - if($t == 1) $type = array(8,15,16,17); - if($t == 2) $type = array(10,11,12,13); - if($t == 3) $type = array(1,2,3,4,5,6,7); - if($t == 4) $type = array(0,18,19,20,21); - - if($t == 5) { - if(!$session->plus) { - $this->safeRedirect("berichte.php"); - } - $type = array(9); - } - - if($type !== null) { - $all = $database->getNotice($session->uid); - $this->noticearray = $this->filter_by_value($all, "ntype", $type); - } - } - - if(isset($get['id'])) { - $this->readingNotice = $this->getReadNotice((int)$get['id']); - } - } - - public function procNotice($post) { - - if(isset($post["del_x"])) $this->removeNotice($post); - if(isset($post['archive_x'])) $this->archiveNotice($post); - if(isset($post['start_x'])) $this->unarchiveNotice($post); - } - - private function getNotice() { - - global $database, $session; - - $all = $database->getNotice($session->uid); - $this->noticearray = $this->filter_by_value_except($all, "ntype", 9); - } - - private function getReadNotice($id) { - - global $database, $session; - - $id = (int)$id; - if($id <= 0) return null; - - $notice = $database->getNotice2($id); - - if(!$notice) return null; - - if($notice['uid'] == $session->uid || $notice['ally'] == $session->alliance) { - - if($notice['uid'] == $session->uid) { - $database->noticeViewed($notice['id']); - } - - return $notice; - } - - return null; - } - - /* ===================================================== */ - /* ================= FILTER HELPERS ==================== */ - /* ===================================================== */ - - private function filter_by_value_except($array, $index, $value) { - - $newarray = array(); - - if(is_array($array)) { - foreach($array as $row) { - if(isset($row[$index]) && $row[$index] != $value) { - $newarray[] = $row; - } - } - } - - return $newarray; - } - - private function filter_by_value($array, $index, $values) { - - $newarray = array(); - - if(!is_array($values)) { - $values = array($values); - } - - if(is_array($array)) { - foreach($array as $row) { - if(isset($row[$index]) && in_array($row[$index], $values)) { - $newarray[] = $row; - } - } - } - - return $newarray; - } - - /* ===================================================== */ - /* ================= MESSAGE LOADING =================== */ - /* ===================================================== */ - - public function loadMessage($id) { - - global $database, $session; - - $id = (int)$id; - if($id <= 0) return; - - if($this->findInbox($id)) { - foreach($this->inbox as $message) { - if($message['id'] == $id) { - $this->reading = $message; - break; - } - } - } - - if($this->findSent($id)) { - foreach($this->sent as $message) { - if($message['id'] == $id) { - $this->reading = $message; - break; - } - } - } - - if($session->plus && $this->findArchive($id)) { - foreach($this->archived as $message) { - if($message['id'] == $id) { - $this->reading = $message; - break; - } - } - } - - if(!empty($this->reading) && $this->reading['viewed'] == 0) { - $database->getMessage($id, 4); - } - } - - /* ===================================================== */ - /* ================= REPORT TYPE ======================= */ - /* ===================================================== */ - - public function getReportType($type) { - - $type = (int)$type; - - switch($type) { - - case 2: - case 4: - case 5: - case 6: - case 7: - case 18: - case 20: - case 21: - return 1; - - case 11: - case 12: - case 13: - case 14: - return 10; - - case 16: - case 17: - return 15; - - case 19: - return 3; - - case 23: - return 22; - } - - return $type; - } - - /* ===================================================== */ - /* ================= NOTES ============================= */ - /* ===================================================== */ - - public function loadNotes() { - - global $session; - - $file = "GameEngine/Notes/".md5($session->username).".txt"; - - if(file_exists($file)) { - $this->note = file_get_contents($file); - } else { - $this->note = ""; - } - } + if($req_file == 'nachrichten.php'){ + if(isset($_GET['t'])){ + switch($_GET['t']){ + // send messages page or a single sent message + case 2 : + case '2a' : + $this->getMessages(2); + break; + + // archived messages page + case 3 : + $this->getMessages(3); + break; + } + } + else $this->getMessages(1); // inbox - received messages page + } + + if ($req_file == 'berichte.php') $this->getNotice(); + + if(isset($_SESSION['reply'])) { + $this->reply = $_SESSION['reply']; + unset($_SESSION['reply']); + } + } + + public function procMessage($post) { + + if(isset($post['ft'])) { + switch($post['ft']) { + case "m1": + $this->quoteMessage($post['id']); + break; + case "m2": + if ($post['an'] == "[ally]") $this->sendAMessage($post['be'],addslashes($post['message'])); + else $this->sendMessage($post['an'],$post['be'],addslashes($post['message'])); + header("Location: nachrichten.php?t=2"); + exit; + case "m3": + case "m4": + case "m5": + if(isset($post['delmsg']))$this->removeMessage($post); + if(isset($post['archive'])) $this->archiveMessage($post); + if(isset($post['start'])) $this->unarchiveMessage($post); + break; + case "m6": + $this->createNote($post); + break; + case "m7": + $this->addFriends($post); + break; + } + } + } + + public function noticeType($get) { + global $session, $database; + if(isset($get['t'])) { + if($get['t'] == 1) $type = [8, 15, 16, 17]; + if($get['t'] == 2) $type = [10, 11, 12, 13]; + if($get['t'] == 3) $type = [1, 2, 3, 4, 5, 6, 7]; + if($get['t'] == 4) $type = [0, 18, 19, 20, 21]; + if($get['t'] == 5) { + if(!$session->plus){ + header("Location: berichte.php"); + exit; + } + else $type = 9; + } + if (!is_array($type)) $type = [$type]; + $this->noticearray = $this->filter_by_value($database->getNotice($session->uid), "ntype", $type); + } + + if(isset($get['id'])) $this->readingNotice = $this->getReadNotice($get['id']); + } + + public function procNotice($post) { + if(isset($post["del_x"])) $this->removeNotice($post); + if(isset($post['archive_x'])) $this->archiveNotice($post); + if(isset($post['start_x'])) $this->unarchiveNotice($post); + } + + public function quoteMessage($id) { + foreach($this->inbox as $message) { + if($message['id'] == $id) { + $message = preg_replace('/\[message\]/', '', $message); + $message = preg_replace('/\[\/message\]/', '', $message); + + for($i = 1; $i <= $message['alliance']; $i++){ + $message = preg_replace('/\[alliance'.$i.'\]/', '[alliance0]', $message); + $message = preg_replace('/\[\/alliance'.$i.'\]/', '[/alliance0]', $message); + } + + for($i = 0; $i <= $message['player']; $i++){ + $message = preg_replace('/\[player'.$i.'\]/', '[player0]', $message); + $message = preg_replace('/\[\/player'.$i.'\]/', '[/player0]', $message); + } + + for($i = 0; $i <= $message['coor']; $i++){ + $message = preg_replace('/\[coor'.$i.'\]/', '[coor0]', $message); + $message = preg_replace('/\[\/coor'.$i.'\]/', '[/coor0]', $message); + } + + for($i = 0; $i <= $message['report']; $i++){ + $message = preg_replace('/\[report'.$i.'\]/', '[report0]', $message); + $message = preg_replace('/\[\/report'.$i.'\]/', '[/report0]', $message); + } + + $this->reply = $_SESSION['reply'] = $message; + header("Location: nachrichten.php?t=1&id=" . $message['owner'] . "&mid=" . $message['id'] . "&tid=" . $message['target']); + exit; + } + } + } + + public function loadMessage($id) { + global $database, $session; + + if($this->findInbox($id)) { + foreach($this->inbox as $message) { + if($message['id'] == $id) { + $this->reading = $message; + break; + } + } + } + + if($this->findSent($id)) { + foreach($this->sent as $message) { + if($message['id'] == $id) { + $this->reading = $message; + break; + } + } + } + + if($session->plus && $this->findArchive($id)) { + foreach($this->archived as $message) { + if($message['id'] == $id) { + $this->reading = $message; + break; + } + } + } + + if($this->reading['viewed'] == 0) $database->getMessage($id, 4); + } + + private function filter_by_value_except($array, $index, $value) { + $newarray = []; + if(is_array($array) && count($array) > 0) { + foreach(array_keys($array) as $key) { + $temp[$key] = $array[$key][$index]; + + if($temp[$key] != $value) { + array_push($newarray, $array[$key]); + //$newarray[$key] = $array[$key]; + } + } + } + return $newarray; + } + + private function filter_by_value($array, $index, $value) { + $newarray = []; + if(is_array($array) && count($array) > 0) { + foreach(array_keys($array) as $key) { + $temp[$key] = $array[$key][$index]; + + if(in_array($temp[$key], $value)) { + array_push($newarray, $array[$key]); + //$newarray[$key] = $array[$key]; + } + } + } + return $newarray; + } + + private function getNotice() { + global $database, $session; + + $this->noticearray = $this->filter_by_value_except($database->getNotice($session->uid), "ntype", 9); + } + + private function removeMessage($post) { + global $database, $session; + + $post = $database->escape($post); + $mode5updates = $mode7updates = $mode8updates = []; + + for($i = 1; $i <= 10; $i++){ + if(isset($post['n' . $i])){ + $message1 = mysqli_query($database->dblink, "SELECT target, owner FROM " . TB_PREFIX . "mdata where id = " . (int)$post['n' . $i] . ""); + $message = mysqli_fetch_array($message1); + + if($message['target'] == $session->uid && $message['owner'] == $session->uid) $mode8updates[] = $post['n' . $i]; + else if($message['target'] == $session->uid) $mode5updates[] = $post['n' . $i]; + else if($message['owner'] == $session->uid) $mode7updates[] = $post['n' . $i]; + } + } + + if(count($mode5updates)) $database->getMessage($mode5updates, 5); + if(count($mode7updates)) $database->getMessage($mode7updates, 7); + if(count($mode8updates)) $database->getMessage($mode8updates, 8); + + header("Location: nachrichten.php"); + exit; + } + + private function archiveMessage($post) { + global $database; + + $archIDs = []; + for($i = 1; $i <= 10; $i++) { + if(isset($post['n'.$i])) $archIDs[] = $post['n'.$i]; + } + $database->setArchived($archIDs); + + header("Location: nachrichten.php"); + exit; + } + + private function unarchiveMessage($post) { + global $database; + + $normIDs = []; + for($i = 1; $i <= 10; $i++) { + if(isset($post['n'.$i])) $normIDs[] = $post['n'.$i]; + } + $database->setNorm($normIDs); + + header("Location: nachrichten.php"); + exit; + } + + private function removeNotice($post) { + global $database; + + $removeIDs = []; + for($i = 1; $i <= 10; $i++) { + if(isset($post['n' . $i])) { + $removeIDs[] = $post['n' . $i]; + } + } + + $database->removeNotice($removeIDs); + + header("Location: berichte.php"); + exit; + } + + private function archiveNotice($post) { + global $database; + + $archiveIDs = []; + for($i = 1; $i <= 10; $i++) { + if(isset($post['n' . $i])) { + $archiveIDs[] = $post['n' . $i]; + } + } + + $database->archiveNotice($archiveIDs); + + header("Location: berichte.php"); + exit; + } + + private function unarchiveNotice($post) { + global $database; + + $unarchIDs = []; + for($i = 1; $i <= 10; $i++) { + if(isset($post['n' . $i])) { + $unarchIDs[] = $post['n' . $i]; + } + } + + $database->unarchiveNotice($unarchIDs); + + header("Location: berichte.php"); + exit; + } + + private function getReadNotice($id) { + global $database, $session; + + $notice = $database->getNotice2($id); + if($notice['uid'] == $session->uid || $notice['ally'] == $session->alliance){ + if($notice['uid'] == $session->uid) $database->noticeViewed($notice['id']); + return $notice; + } + else return null; + } + + /** + * Not all notices have a corresponding .tpl file but with this method it's like they have it + * + * @param int $type The type of the report (notice) + * @return int Returns the new report type + */ - /* ===================================================== */ - /* ================= DELETE MESSAGES =================== */ - /* ===================================================== */ - - private function removeMessage($post) { - - global $database, $session; - - $mode5 = array(); - $mode7 = array(); - $mode8 = array(); - - for($i = 1; $i <= 10; $i++) { - - if(isset($post['n'.$i])) { - - $id = (int)$post['n'.$i]; - if($id <= 0) continue; - - $query = "SELECT target, owner - FROM ".TB_PREFIX."mdata - WHERE id = {$id} LIMIT 1"; - - $res = mysqli_fetch_assoc(mysqli_query($database->dblink, $query)); - if(!$res) continue; - - $target = (int)$res['target']; - $owner = (int)$res['owner']; - - if($target == $session->uid && $owner == $session->uid) { - $mode8[] = $id; - } - elseif($target == $session->uid) { - $mode5[] = $id; - } - elseif($owner == $session->uid) { - $mode7[] = $id; - } - } - } - - if(!empty($mode5)) $database->getMessage($mode5, 5); - if(!empty($mode7)) $database->getMessage($mode7, 7); - if(!empty($mode8)) $database->getMessage($mode8, 8); - - $this->safeRedirect("nachrichten.php"); - } - - /* ===================================================== */ - /* ================= ARCHIVE MESSAGES ================== */ - /* ===================================================== */ - - private function archiveMessage($post) { - - global $database; - - $ids = array(); - - for($i = 1; $i <= 10; $i++) { - if(isset($post['n'.$i])) { - $id = (int)$post['n'.$i]; - if($id > 0) $ids[] = $id; - } - } - - if(!empty($ids)) { - $database->setArchived($ids); - } - - $this->safeRedirect("nachrichten.php"); - } - - private function unarchiveMessage($post) { - - global $database; - - $ids = array(); - - for($i = 1; $i <= 10; $i++) { - if(isset($post['n'.$i])) { - $id = (int)$post['n'.$i]; - if($id > 0) $ids[] = $id; - } - } - - if(!empty($ids)) { - $database->setNorm($ids); - } - - $this->safeRedirect("nachrichten.php"); - } - - /* ===================================================== */ - /* ================= DELETE NOTICES ==================== */ - /* ===================================================== */ - - private function removeNotice($post) { - - global $database; - - $ids = array(); - - for($i = 1; $i <= 10; $i++) { - if(isset($post['n'.$i])) { - $id = (int)$post['n'.$i]; - if($id > 0) $ids[] = $id; - } - } - - if(!empty($ids)) { - $database->removeNotice($ids); - } - - $this->safeRedirect("berichte.php"); - } - - private function archiveNotice($post) { - - global $database; - - $ids = array(); - - for($i = 1; $i <= 10; $i++) { - if(isset($post['n'.$i])) { - $id = (int)$post['n'.$i]; - if($id > 0) $ids[] = $id; - } - } - - if(!empty($ids)) { - $database->archiveNotice($ids); - } - - $this->safeRedirect("berichte.php"); - } - - private function unarchiveNotice($post) { - - global $database; - - $ids = array(); - - for($i = 1; $i <= 10; $i++) { - if(isset($post['n'.$i])) { - $id = (int)$post['n'.$i]; - if($id > 0) $ids[] = $id; - } - } - - if(!empty($ids)) { - $database->unarchiveNotice($ids); - } - - $this->safeRedirect("berichte.php"); - } - - /* ===================================================== */ - /* ================= QUOTE MESSAGE ===================== */ - /* ===================================================== */ - - public function quoteMessage($id) { - - $id = (int)$id; - if($id <= 0) return; - - foreach($this->inbox as $message) { - - if($message['id'] == $id) { - - $text = $message['message']; - - $text = preg_replace('/\[message\]/i', '', $text); - $text = preg_replace('/\[\/message\]/i', '', $text); - - $_SESSION['reply'] = $text; - $this->reply = $text; - - $owner = (int)$message['owner']; - $mid = (int)$message['id']; - $target = (int)$message['target']; - - $this->safeRedirect( - "nachrichten.php?t=1&id=".$owner."&mid=".$mid."&tid=".$target - ); - } - } - } - - /* ===================================================== */ - /* ================= PROCESS MESSAGE =================== */ - /* ===================================================== */ - - public function procMessage($post) { - - if(!isset($post['ft'])) return; - - switch($post['ft']) { - - case "m1": - if(isset($post['id'])) { - $this->quoteMessage((int)$post['id']); - } - break; - - case "m2": - - $receiver = isset($post['an']) ? trim($post['an']) : ''; - $topic = isset($post['be']) ? trim($post['be']) : ''; - $message = isset($post['message']) ? trim($post['message']) : ''; - - if($receiver === "[ally]") { - $this->sendAMessage($topic, $message); - } else { - $this->sendMessage($receiver, $topic, $message); - } - - $this->safeRedirect("nachrichten.php?t=2"); - break; - - case "m3": - case "m4": - case "m5": - - if(isset($post['delmsg'])) $this->removeMessage($post); - if(isset($post['archive'])) $this->archiveMessage($post); - if(isset($post['start'])) $this->unarchiveMessage($post); - break; - - case "m6": - $this->createNote($post); - break; - - case "m7": - $this->addFriends($post); - break; - } - } - - /* ===================================================== */ - /* ================= FLOOD PROTECTION ================== */ - /* ===================================================== */ - - private function checkFlood($uid) { - - global $database; - - $uid = (int)$uid; - - $query = "SELECT COUNT(*) AS total - FROM ".TB_PREFIX."mdata - WHERE owner = {$uid} - AND time > ".(time() - 60); - - $res = mysqli_fetch_assoc(mysqli_query($database->dblink, $query)); - - if($res && $res['total'] > 5) { - return false; - } - - return true; - } - - /* ===================================================== */ - /* ================= SANITIZE TEXT ===================== */ - /* ===================================================== */ - - private function sanitizeMessage($text) { - - $text = trim($text); - - // remove null bytes - $text = str_replace("\0", '', $text); - - // prevent extremely long spam payloads - if(strlen($text) > 15000) { - $text = substr($text, 0, 15000); - } - - return $text; - } - - /* ===================================================== */ - /* ================= SEND ALLY MESSAGE ================= */ - /* ===================================================== */ - - private function sendAMessage($topic, $text) { - - global $session, $database; - - if(!$this->checkFlood($session->uid)) { - return; - } - - $topic = $this->sanitizeMessage($topic); - $text = $this->sanitizeMessage($text); - - if(defined('WORD_CENSOR')) { + public function getReportType($type) + { + switch($type) + { + case 2: + case 4: + case 5: + case 6: + case 7: + case 18: + case 20: + case 21: return 1; //General attacking reports + + case 11: + case 12: + case 13: + case 14: return 10; //Merchants reports + + case 16: + case 17: return 15; //Reinforcements attacked + + case 19: return 3; //No troops have returned + + case 23: return 22; //Festive reports + } + + return $type; + } + + public function loadNotes() { + global $session; + if(file_exists("GameEngine/Notes/".md5($session->username).".txt")) { + $this->note = file_get_contents("GameEngine/Notes/".md5($session->username).".txt"); + } + else $this->note = ""; + } + + private function createNote($post) { + global $session; + if($session->plus) { + $ourFileHandle = fopen("GameEngine/Notes/".md5($session->username).".txt", 'w'); + fwrite($ourFileHandle, $post['notizen']); + fclose($ourFileHandle); + } + } + + private function getMessages($which) { + global $database, $session; + + switch($which){ + case 1 : + $this->inbox = $database->getMessage($session->uid, 1); + $this->inbox1 = $database->getMessage($session->uid, 9); + break; + + case 2 : + $this->sent = $database->getMessage($session->uid, 2); + $this->sent1 = $database->getMessage($session->uid, 10); + break; + + case 3 : + if($session->plus){ + $this->archived = $database->getMessage($session->uid, 6); + $this->archived1 = $database->getMessage($session->uid, 11); + } + break; + } + } + + private function sendAMessage($topic,$text) { + global $session,$database; + + // Vulnerability closed by Shadow + + $q = "SELECT Count(*) as Total FROM ".TB_PREFIX."mdata WHERE owner='".$session->uid."' AND time > ".(time() - 60); + $res = mysqli_fetch_array(mysqli_query($database->dblink,$q), MYSQLI_ASSOC); + if($res['Total'] > 5) return; //flooding prevention + + + // Vulnerability closed by Shadow + + $allmembersQ = mysqli_query($database->dblink,"SELECT id FROM ".TB_PREFIX."users WHERE alliance='".$session->alliance."'"); + $userally = $database->getUserField($session->uid,"alliance",0); + $permission=mysqli_fetch_array(mysqli_query($database->dblink,"SELECT opt7 FROM ".TB_PREFIX."ali_permission WHERE uid='".$session->uid."'")); + + if(defined('WORD_CENSOR')) { $topic = $this->wordCensor($topic); - $text = $this->wordCensor($text); - } + $text = $this->wordCensor($text); + } - if(empty($topic)) { - $topic = "No subject"; - } + if($topic == "") $topic = "No subject"; - if(!preg_match('/\[message\]/i', $text)) { + if(!preg_match('/\[message\]/',$text) && !preg_match('/\[\/message\]/',$text)){ $text = "[message]".$text."[/message]"; - } - - $topic = htmlspecialchars($topic, ENT_QUOTES, 'UTF-8'); - $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); - - $userally = (int)$session->alliance; - - if($userally <= 0) return; - - $membersQ = mysqli_query( - $database->dblink, - "SELECT id FROM ".TB_PREFIX."users WHERE alliance = {$userally}" - ); - - while($row = mysqli_fetch_assoc($membersQ)) { - - $receiver = (int)$row['id']; - - $database->sendMessage( - $receiver, - $session->uid, - $topic, - $text, - 0, - 0,0,0,0 - ); - } - } - - /* ===================================================== */ - /* ================= SEND PRIVATE MESSAGE ============== */ - /* ===================================================== */ - - private function sendMessage($receiverName, $topic, $text) { - - global $session, $database; - - if(!$this->checkFlood($session->uid)) { - return; - } - - $receiverName = trim($receiverName); - - if(empty($receiverName)) return; - - // get receiver safely - $receiverID = $database->getUserField($receiverName, "id", 1); - $receiverID = (int)$receiverID; - - if($receiverID <= 0) return; - - $topic = $this->sanitizeMessage($topic); - $text = $this->sanitizeMessage($text); - - if(defined('WORD_CENSOR')) { - $topic = $this->wordCensor($topic); - $text = $this->wordCensor($text); - } - - if(empty($topic)) { - $topic = "No subject"; - } - - if(!preg_match('/\[message\]/i', $text)) { - $text = "[message]".$text."[/message]"; - } - - $topic = htmlspecialchars($topic, ENT_QUOTES, 'UTF-8'); - $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); - - $send_as = $session->uid; - - $support_allowed = ( - $session->access == ADMIN && - defined('ADMIN_RECEIVE_SUPPORT_MESSAGES') && - ADMIN_RECEIVE_SUPPORT_MESSAGES - ); - - if(!empty($_POST['as_support']) && $support_allowed) { - $send_as = 1; - } - - if(!empty($_POST['as_multihunter']) && $session->access == MULTIHUNTER) { - $send_as = 5; - } - - $database->sendMessage( - $receiverID, - (int)$send_as, - $topic, - $text, - 0, - 0,0,0,0 - ); - } - - /* ===================================================== */ - /* ================= SEND WELCOME ====================== */ - /* ===================================================== */ - - public function sendWelcome($uid, $username) { - - global $database; - - $uid = (int)$uid; - if($uid <= 0) return false; - - $tplPath = "GameEngine/Admin/welcome.tpl"; - if(!file_exists($tplPath)) return false; - - $username = htmlspecialchars($username, ENT_QUOTES, 'UTF-8'); - - $content = file_get_contents($tplPath); - - $content = preg_replace( - array( - "'%USER%'", - "'%START%'", - "'%TIME%'", - "'%PLAYERS%'", - "'%ALLI%'", - "'%SERVER_NAME%'", - "'%PROTECTION%'" - ), - array( - $username, - date("y.m.d", COMMENCE), - date("H:i", COMMENCE), - (int)$database->countUser(), - (int)$database->countAlli(), - SERVER_NAME, - round((PROTECTION/3600)) - ), - $content - ); - - $content = "[message]".$content."[/message]"; - - return $database->sendMessage( - $uid, - 1, - WEL_TOPIC, - htmlspecialchars($content, ENT_QUOTES, 'UTF-8'), - 0,0,0,0,0 - ); - } - - /* ===================================================== */ - /* ================= SAFE WORD CENSOR ================== */ - /* ===================================================== */ - - private function wordCensor($text) { - - if(!defined('CENSORED') || empty(CENSORED)) { - return $text; - } - - $censorarray = explode(",", CENSORED); - $patterns = array(); - - foreach($censorarray as $word) { - - $word = trim($word); - if(empty($word)) continue; - - $word = preg_quote($word, '/'); - $patterns[] = '/'.$word.'/i'; - } - - if(!empty($patterns)) { - $text = preg_replace($patterns, "****", $text); - } - - return $text; - } - - /* ===================================================== */ - /* ================= SAFE FIND METHODS ================= */ - /* ===================================================== */ - - private function findInbox($id) { - - $id = (int)$id; - - if(!empty($this->inbox)) { - foreach($this->inbox as $msg) { - if((int)$msg['id'] === $id) return true; - } - } - - return false; - } - - private function findSent($id) { - - $id = (int)$id; - - if(!empty($this->sent)) { - foreach($this->sent as $msg) { - if((int)$msg['id'] === $id) return true; - } - } - - return false; - } - - private function findArchive($id) { - - $id = (int)$id; - - if(!empty($this->archived)) { - foreach($this->archived as $msg) { - if((int)$msg['id'] === $id) return true; - } - } - - return false; - } - - /* ===================================================== */ - /* ================= SECURE FRIEND SYSTEM ============== */ - /* ===================================================== */ - - public function addFriends($post){ - - global $database, $session; - - $myID = (int)$session->uid; - if($myID <= 0) return; - - for($i = 0; $i <= 19; $i++){ - - if(empty($post['addfriends'.$i])) continue; - - $username = trim($post['addfriends'.$i]); - $friendID = (int)$database->getUserField($username, "id", 1); - - if($friendID <= 0) continue; - if($friendID == $myID) continue; - - // Check already exists - $exists = false; - for($k = 0; $k <= 19; $k++){ - if((int)$database->getUserField($myID, "friend".$k, 0) === $friendID){ - $exists = true; - break; - } - } - - if($exists) continue; - - // Find empty slot - for($j = 0; $j <= 19; $j++){ - - $slot = (int)$database->getUserField($myID, "friend".$j, 0); - $wait = (int)$database->getUserField($myID, "friend".$j."wait", 0); - - if($slot === 0 && $wait === 0){ - - $database->addFriend($myID, "friend".$j, $friendID); - $database->addFriend($myID, "friend".$j."wait", $friendID); - - // Reciprocal request - for($l = 0; $l <= 19; $l++){ - - $slot2 = (int)$database->getUserField($friendID, "friend".$l, 0); - $wait2 = (int)$database->getUserField($friendID, "friend".$l."wait", 0); - - if($slot2 === 0 && $wait2 === 0){ - $database->addFriend($friendID, "friend".$l."wait", $myID); - break; - } + $alliance = $player = $coor = $report = 0; + + for ( $i = 0; $i <= $alliance; $i ++ ) { + if ( preg_match( '/\[alliance' . $i . '\]/', $text ) && preg_match( '/\[\/alliance' . $i . '\]/', $text ) ) { + $alliance1 = preg_replace( '/\[message\](.*?)\[\/alliance' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[alliance' . $i . '\]/', $alliance1 ) && preg_match( '/\[\/alliance' . $i . '\]/', $alliance1 ) ) { + $j = $i + 1; + $alliance2 = preg_replace( '/\[\/alliance' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $alliance1 = preg_replace( '/\[alliance' . $i . '\]/', '[alliance' . $j . ']', $alliance1 ); + $alliance1 = preg_replace( '/\[\/alliance' . $i . '\]/', '[/alliance' . $j . ']', $alliance1 ); + $text = $alliance2 . "[/alliance" . $i . "]" . $alliance1; + $alliance += 1; } - - break; } } + + for ( $i = 0; $i <= $player; $i ++ ) { + if ( preg_match( '/\[player' . $i . '\]/', $text ) && preg_match( '/\[\/player' . $i . '\]/', $text ) ) { + $player1 = preg_replace( '/\[message\](.*?)\[\/player' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[player' . $i . '\]/', $player1 ) && preg_match( '/\[\/player' . $i . '\]/', $player1 ) ) { + $j = $i + 1; + $player2 = preg_replace( '/\[\/player' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $player1 = preg_replace( '/\[player' . $i . '\]/', '[player' . $j . ']', $player1 ); + $player1 = preg_replace( '/\[\/player' . $i . '\]/', '[/player' . $j . ']', $player1 ); + $text = $player2 . "[/player" . $i . "]" . $player1; + $player += 1; + } + } + } + + for ( $i = 0; $i <= $coor; $i ++ ) { + if ( preg_match( '/\[coor' . $i . '\]/', $text ) && preg_match( '/\[\/coor' . $i . '\]/', $text ) ) { + $coor1 = preg_replace( '/\[message\](.*?)\[\/coor' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[coor' . $i . '\]/', $coor1 ) && preg_match( '/\[\/coor' . $i . '\]/', $coor1 ) ) { + $j = $i + 1; + $coor2 = preg_replace( '/\[\/coor' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $coor1 = preg_replace( '/\[coor' . $i . '\]/', '[coor' . $j . ']', $coor1 ); + $coor1 = preg_replace( '/\[\/coor' . $i . '\]/', '[/coor' . $j . ']', $coor1 ); + $text = $coor2 . "[/coor" . $i . "]" . $coor1; + $coor += 1; + } + } + } + + for ( $i = 0; $i <= $report; $i ++ ) { + if ( preg_match( '/\[report' . $i . '\]/', $text ) && preg_match( '/\[\/report' . $i . '\]/', $text ) ) { + $report1 = preg_replace( '/\[message\](.*?)\[\/report' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[report' . $i . '\]/', $report1 ) && preg_match( '/\[\/report' . $i . '\]/', $report1 ) ) { + $j = $i + 1; + $report2 = preg_replace( '/\[\/report' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $report1 = preg_replace( '/\[report' . $i . '\]/', '[report' . $j . ']', $report1 ); + $report1 = preg_replace( '/\[\/report' . $i . '\]/', '[/report' . $j . ']', $report1 ); + $text = $report2 . "[/report" . $i . "]" . $report1; + $report += 1; + } + } + } + + if($permission['opt7'] == 1){ + if ($userally > 0) { + while ($allmembers = mysqli_fetch_array($allmembersQ)) { + $database->sendMessage($allmembers[id],$session->uid,htmlspecialchars(addslashes($topic)),htmlspecialchars(addslashes($text)),0,$alliance,$player,$coor,$report); + } + } + } + } + } + + private function sendMessage($recieve, $topic, $text, $security_check = true) { + global $session, $database; + $user = $database->getUserField($recieve, "id", 1); + + // Vulnerability closed by Shadow + if ($security_check) { + $q = "SELECT Count(*) as Total FROM ".TB_PREFIX."mdata WHERE owner='".$session->uid."' AND time > ".(time() - 60); + $res = mysqli_fetch_array(mysqli_query($database->dblink,$q), MYSQLI_ASSOC); + if($res['Total'] > 5) return; //flooding prevention + } + + // Vulnerability closed by Shadow + if(defined('WORD_CENSOR')) { + $topic = $this->wordCensor($topic); + $text = $this->wordCensor($text); + } + + if(empty($topic)) $topic = "No subject"; + + if ( ! preg_match( '/\[message\]/', $text ) && ! preg_match( '/\[\/message\]/', $text ) ) { + $text = "[message]" . $text . "[/message]"; + $alliance = $player = $coor = $report = 0; + + for ( $i = 0; $i <= $alliance; $i ++ ) { + if ( preg_match( '/\[alliance' . $i . '\]/', $text ) && preg_match( '/\[\/alliance' . $i . '\]/', $text ) ) { + $alliance1 = preg_replace( '/\[message\](.*?)\[\/alliance' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[alliance' . $i . '\]/', $alliance1 ) && preg_match( '/\[\/alliance' . $i . '\]/', $alliance1 ) ) { + $j = $i + 1; + $alliance2 = preg_replace( '/\[\/alliance' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $alliance1 = preg_replace( '/\[alliance' . $i . '\]/', '[alliance' . $j . ']', $alliance1 ); + $alliance1 = preg_replace( '/\[\/alliance' . $i . '\]/', '[/alliance' . $j . ']', $alliance1 ); + $text = $alliance2 . "[/alliance" . $i . "]" . $alliance1; + $alliance += 1; + } + } + } + + for ( $i = 0; $i <= $player; $i ++ ) { + if ( preg_match( '/\[player' . $i . '\]/', $text ) && preg_match( '/\[\/player' . $i . '\]/', $text ) ) { + $player1 = preg_replace( '/\[message\](.*?)\[\/player' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[player' . $i . '\]/', $player1 ) && preg_match( '/\[\/player' . $i . '\]/', $player1 ) ) { + $j = $i + 1; + $player2 = preg_replace( '/\[\/player' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $player1 = preg_replace( '/\[player' . $i . '\]/', '[player' . $j . ']', $player1 ); + $player1 = preg_replace( '/\[\/player' . $i . '\]/', '[/player' . $j . ']', $player1 ); + $text = $player2 . "[/player" . $i . "]" . $player1; + $player += 1; + } + } + } + + for ( $i = 0; $i <= $coor; $i ++ ) { + if ( preg_match( '/\[coor' . $i . '\]/', $text ) && preg_match( '/\[\/coor' . $i . '\]/', $text ) ) { + $coor1 = preg_replace( '/\[message\](.*?)\[\/coor' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[coor' . $i . '\]/', $coor1 ) && preg_match( '/\[\/coor' . $i . '\]/', $coor1 ) ) { + $j = $i + 1; + $coor2 = preg_replace( '/\[\/coor' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $coor1 = preg_replace( '/\[coor' . $i . '\]/', '[coor' . $j . ']', $coor1 ); + $coor1 = preg_replace( '/\[\/coor' . $i . '\]/', '[/coor' . $j . ']', $coor1 ); + $text = $coor2 . "[/coor" . $i . "]" . $coor1; + $coor += 1; + } + } + } + + for ( $i = 0; $i <= $report; $i ++ ) { + if ( preg_match( '/\[report' . $i . '\]/', $text ) && preg_match( '/\[\/report' . $i . '\]/', $text ) ) { + $report1 = preg_replace( '/\[message\](.*?)\[\/report' . $i . '\]/is', '', $text ); + if ( preg_match( '/\[report' . $i . '\]/', $report1 ) && preg_match( '/\[\/report' . $i . '\]/', $report1 ) ) { + $j = $i + 1; + $report2 = preg_replace( '/\[\/report' . $i . '\](.*?)\[\/message\]/is', '', $text ); + $report1 = preg_replace( '/\[report' . $i . '\]/', '[report' . $j . ']', $report1 ); + $report1 = preg_replace( '/\[\/report' . $i . '\]/', '[/report' . $j . ']', $report1 ); + $text = $report2 . "[/report" . $i . "]" . $report1; + $report += 1; + } + } + } + + // check if we're not sending this as Support or Multihunter + $support_from_admin_allowed = ($session->access == ADMIN && ADMIN_RECEIVE_SUPPORT_MESSAGES); + $send_as = $session->uid; + + // send as Support? + if((!empty($_POST['as_support']) && $support_from_admin_allowed)) $send_as = 1; + + // send as Multihunter + if((!empty($_POST['as_multihunter']) && $session->access == MULTIHUNTER)) $send_as = 5; + + $database->sendMessage($user, $send_as, htmlspecialchars(addslashes($topic)), htmlspecialchars(addslashes($text)), 0, $alliance, $player, $coor, $report); } + } - $this->safeRedirect("nachrichten.php?t=1"); - } - - /* ===================================================== */ - /* ================= LOAD MESSAGES ===================== */ - /* ===================================================== */ + public function sendWelcome($uid, $username) { + global $database; - private function getMessages($which) { + $welcomemsg = file_get_contents("GameEngine/Admin/welcome.tpl"); + $welcomemsg = "[message]".preg_replace( + ["'%USER%'", "'%START%'", "'%TIME%'", "'%PLAYERS%'", "'%ALLI%'", "'%SERVER_NAME%'", "'%PROTECTION%'"], + [$username, date("y.m.d", COMMENCE), date("H:i", COMMENCE), $database->countUser(), $database->countAlli(), SERVER_NAME, round((PROTECTION/3600))], + $welcomemsg + )."[/message]"; + return $database->sendMessage($uid, 1, WEL_TOPIC, addslashes($welcomemsg), 0, 0, 0, 0, 0); + } + + private function wordCensor($text) { + $censorarray = explode(",", CENSORED); + foreach($censorarray as $key => $value) { + $censorarray[$key] = "/" . $value . "/i"; + } + return preg_replace($censorarray, "****", $text); + } + + private function checkUnread() { + global $database, $session; + + return $database->getUnreadMessagesCount($session->uid); + } + + private function checkNUnread() { global $database, $session; - $uid = (int)$session->uid; - if($uid <= 0) return; + return $database->getUnreadNoticesCount($session->uid); + } - switch((int)$which) { + private function findInbox($id) { + if(!empty($this->inbox)){ + foreach($this->inbox as $message){ + if($message['id'] == $id) return true; + } + } + return false; + } - case 1: - // Inbox - $this->inbox = $database->getMessage($uid, 1); - $this->inbox1 = $database->getMessage($uid, 9); - break; + private function findSent($id){ + if(!empty($this->sent)){ + foreach($this->sent as $message){ + if($message['id'] == $id) return true; + } + } + return false; + } - case 2: - // Sent - $this->sent = $database->getMessage($uid, 2); - $this->sent1 = $database->getMessage($uid, 10); - break; + private function findArchive($id){ + if(!empty($this->archived)){ + foreach($this->archived as $message){ + if($message['id'] == $id) return true; + } + } + + return false; + } - case 3: - // Archived (Plus only) - if(!empty($session->plus)) { - $this->archived = $database->getMessage($uid, 6); - $this->archived1 = $database->getMessage($uid, 11); - } - break; - } - } + public function addFriends($post){ + global $database; + for($i = 0; $i <= 19; $i++){ + if($post['addfriends'.$i] != ""){ + $uid = $database->getUserField($post['addfriends'.$i], "id", 1); + $added = 0; + + for($j = 0; $j <= $i; $j++){ + if($added == 0){ + $user = $database->getUserField($post['myid'], "friend".$j, 0); + $userwait = $database->getUserField($post['myid'], "friend".$j."wait", 0); + $exist = 0; + + for($k = 0; $k <= 19; $k++){ + $user1 = $database->getUserField($post['myid'], "friend".$k, 0); + if($user1 == $uid or $uid == $post['myid']){ + $exist = 1; + } + } + + if($user == 0 && $userwait == 0 && $exist == 0){ + $added1 = 0; + + for($l = 0; $l <= 19; $l++){ + $user2 = $database->getUserField($uid, "friend".$l, 0); + $userwait2 = $database->getUserField($uid, "friend".$l."wait", 0); + + if($user2 == 0 && $userwait2 == 0 && $added1 == 0){ + $database->addFriend($uid, "friend".$l."wait", $post['myid']); + $added1 = 1; + } + } + + $database->addFriend($post['myid'], "friend".$j, $uid); + $database->addFriend($post['myid'], "friend".$j."wait", $uid); + $added = 1; + } + } + } + } + } + header("Location: nachrichten.php?t=1"); + exit(); + } -} +}; diff --git a/GameEngine/Profile.php b/GameEngine/Profile.php index 21ab83f0..6401d868 100755 --- a/GameEngine/Profile.php +++ b/GameEngine/Profile.php @@ -5,292 +5,187 @@ ## --------------------------------------------------------------------------- ## ## Filename Profile.php ## ## License: TravianZ Project ## -## Refactor: Shadow ## ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## ## ## ################################################################################# + class Profile { - - /* ===================================================== */ - /* ================= MAIN PROCESS ====================== */ - /* ===================================================== */ - - public function procProfile($post) { - - if(!isset($post['ft'])) return; - - switch($post['ft']) { - - case "p1": - $this->updateProfile($post); - break; - - case "p3": - $this->updateAccount($post); - break; - - case "p4": - $this->setVacationMode($post); - break; - } - - if(isset($post['s']) && (int)$post['s'] === 4) { - $this->gpack($post); - } - } - - public function procSpecial($get) { - - if(!isset($get['e'])) return; - - switch((int)$get['e']) { - - case 2: - $this->removeMeSit($get); - break; - - case 3: - $this->removeSitter($get); - break; - - case 4: - $this->cancelDeleting($get); - break; - } - } - - /* ===================================================== */ - /* ================= UPDATE PROFILE ==================== */ - /* ===================================================== */ - - private function updateProfile($post) { - - global $database, $session; - - $uid = (int)$session->uid; - - $year = (int)$post['jahr']; - $month = (int)$post['monat']; - $day = (int)$post['tag']; - - $birthday = $year.'-'.$month.'-'.$day; - - $mw = $database->RemoveXSS(trim($post['mw'])); - $ort = $database->RemoveXSS(trim($post['ort'])); - $be2 = $database->RemoveXSS(trim($post['be2'])); - $be1 = $database->RemoveXSS(trim($post['be1'])); - - $database->submitProfile($uid, $mw, $ort, $birthday, $be2, $be1); - - $villages = $database->getProfileVillages($uid); - - if(is_array($villages)) { - for($i = 0; $i < count($villages); $i++) { - - if(isset($post['dname'.$i])) { - $name = trim($post['dname'.$i]); - $name = $database->RemoveXSS($name); - - $database->setVillageName( - (int)$villages[$i]['wref'], - $name - ); - } - } - } - - header("Location: spieler.php?uid=".$uid); - exit; - } - - /* ===================================================== */ - /* ================= GP PACK =========================== */ - /* ===================================================== */ - - private function gpack($post) { - - global $database, $session; - - $uid = (int)$session->uid; - - if(isset($post['custom_url'])) { - - $url = trim($post['custom_url']); - $url = $database->RemoveXSS($url); - - $database->gpack($uid, $url); - } - - header("Location: spieler.php?uid=".$uid); - exit; - } - - /* ===================================================== */ - /* ================= VACATION MODE ===================== */ - /* ===================================================== */ - - private function setVacationMode($post){ - - global $database, $session, $form; - - $days = isset($post['vac_days']) ? (int)$post['vac_days'] : 0; - - if(isset($post['vac']) && $post['vac'] && $days >= 2 && $days <= 14){ - - unset($_SESSION['wid']); - - $database->setvacmode((int)$session->uid, $days); - $database->activeModify($session->username, 1); - $database->UpdateOnline("logout"); - - $session->Logout(); - - header("Location: login.php"); - exit; - } - - $form->addError("vac", VAC_MODE_WRONG_DAYS); - - header("Location: spieler.php?s=".$session->uid); - exit; - } - - /* ===================================================== */ - /* ================= UPDATE ACCOUNT ==================== */ - /* ===================================================== */ - - private function updateAccount($post) { - - global $database, $session, $form; - - $uid = (int)$session->uid; - - /* ---- PASSWORD CHANGE ---- */ - - if(!empty($post['pw1']) && !empty($post['pw2']) && !empty($post['pw3'])) { - - if($post['pw2'] === $post['pw3']) { - - if($database->login($session->username, $post['pw1'])) { - - $hash = password_hash($post['pw2'], PASSWORD_BCRYPT, array('cost' => 12)); - $database->updateUserField($uid, "password", $hash, 1); - - } else { - $form->addError("pw", LOGIN_PW_ERROR); - } - - } else { - $form->addError("pw", PASS_MISMATCH); - } - } - - /* ---- EMAIL CHANGE ---- */ - - if(!empty($post['email_alt']) && !empty($post['email_neu'])) { - - $newEmail = filter_var($post['email_neu'], FILTER_VALIDATE_EMAIL); - - if($post['email_alt'] === $session->userinfo['email'] && $newEmail) { - $database->updateUserField($uid, "email", $newEmail, 1); - } else { - $form->addError("email", EMAIL_ERROR); - } - } - - /* ---- ACCOUNT DELETE ---- */ - - if(!empty($post['del_pw']) && !empty($post['del'])) { - - if(password_verify($post['del_pw'], $session->userinfo['password'])) { - $database->setDeleting($uid, 0); - } else { - $form->addError("del", PASS_MISMATCH); - } - } - - /* ---- SITTER ADD ---- */ - - if(!empty($post['v1'])) { - - $sitID = (int)$database->getUserField($post['v1'], "id", 1); - - if($sitID > 0 && $sitID !== $uid) { - - if($sitID == $session->userinfo['sit1'] || - $sitID == $session->userinfo['sit2']) { - - $form->addError("sit", SIT_ERROR); - - } else { - - if((int)$session->userinfo['sit1'] === 0) { - $database->updateUserField($uid, "sit1", $sitID, 1); - } elseif((int)$session->userinfo['sit2'] === 0) { - $database->updateUserField($uid, "sit2", $sitID, 1); - } - } - } - } - - if($form->returnErrors() > 0) { - $_SESSION['errorarray'] = $form->getErrors(); - $_SESSION['valuearray'] = $_POST; - } - - header("Location: spieler.php?s=3"); - exit; - } - - /* ===================================================== */ - /* ================= REMOVE SITTER ===================== */ - /* ===================================================== */ - - private function removeSitter($get) { - - global $database, $session; - - $type = isset($get['type']) ? (int)$get['type'] : 0; - $id = isset($get['id']) ? (int)$get['id'] : 0; - - if(isset($get['a']) && $get['a'] == $session->checker) { - - if((int)$session->userinfo['sit'.$type] === $id) { - $database->updateUserField($session->uid, "sit".$type, 0, 1); - } - - $session->changeChecker(); - } - - header("Location: spieler.php?s=".(int)$get['s']); - exit; - } - - private function cancelDeleting($get) { - - global $database, $session; - - $database->setDeleting((int)$session->uid, 1); - - header("Location: spieler.php?s=".(int)$get['s']); - exit; - } - - private function removeMeSit($get) { - - global $database, $session; - - if(isset($get['a']) && $get['a'] == $session->checker) { - - $database->removeMeSit((int)$get['id'], (int)$session->uid); - $session->changeChecker(); - } - - header("Location: spieler.php?s=".(int)$get['s']); - exit; - } - -} + public function procProfile($post) { + global $session; + + if(isset($post['ft'])) { + switch($post['ft']) { + case "p1" : + $this->updateProfile($post); + break; + case "p3" : + $this->updateAccount($post); + break; + case "p4" : + $this->setvactionmode($post); + break; + } + } + + if(isset($post['s']) && $post['s'] == 4) $this->gpack($post); + } + + public function procSpecial($get) { + global $session; + + if(isset($get['e'])) { + switch($get['e']) { + case 2 : + $this->removeMeSit($get); + break; + case 3 : + $this->removeSitter($get); + break; + case 4 : + $this->cancelDeleting($get); + break; + } + } + } + + private function updateProfile($post) { + global $database, $session; + + $birthday = $post['jahr'].'-'.$post['monat'].'-'.$post['tag']; + $database->submitProfile($session->uid, $database->RemoveXSS($post['mw']), $database->RemoveXSS($post['ort']), $database->RemoveXSS($birthday), $database->RemoveXSS($post['be2']), $database->RemoveXSS($post['be1'])); + $varray = $database->getProfileVillages($session->uid); + + for($i = 0; $i < count($varray); $i++){ + $database->setVillageName($varray[$i]['wref'], $database->RemoveXSS(trim($post['dname'.$i]))); + } + + header("Location: spieler.php?uid=".$session->uid); + exit; + } + + private function gpack($post) { + global $database, $session; + + $database->gpack($database->RemoveXSS($session->uid),$database->RemoveXSS($post['custom_url'])); + header("Location: spieler.php?uid=".$session->uid); + exit; + } + + /** + * Function to vacation mode - by advocaite and Shadow + * + * @param array $post The $_POST array + */ + + private function setvactionmode($post){ + global $database, $session, $form; + + if(isset($post['vac']) && $post['vac'] && isset($post['vac_days']) && $post['vac_days'] >= 2 && $post['vac_days'] <= 14){ + unset($_SESSION['wid']); + $database->setvacmode($session->uid, $post['vac_days']); + $database->activeModify(addslashes($session->username), 1); + $database->UpdateOnline("logout"); + $session->Logout(); + header("Location: login.php"); + exit; + }else{ + $form->add("vac", VAC_MODE_WRONG_DAYS); + header("Location: spieler.php?s=".$session->uid); + exit; + } + + } + + /** + * Function to vacation mode - by advocaite and Shadow + * + * @param array $post The $_POST array + */ + + private function updateAccount($post) { + global $database, $session, $form; + + if(!empty($post['pw1']) && !empty($post['pw2']) && !empty($post['pw3'])){ + if($post['pw2'] == $post['pw3']){ + if($database->login($session->username, $post['pw1'])){ + $database->updateUserField($session->uid, "password", password_hash($post['pw2'], PASSWORD_BCRYPT, ['cost' => 12]), 1); + } + else $form->addError("pw", LOGIN_PW_ERROR); + } + else $form->addError("pw", PASS_MISMATCH); + } + + if(!empty($post['email_alt']) && !empty($post['email_neu'])){ + if($post['email_alt'] == $session->userinfo['email']){ + $database->updateUserField($session->uid, "email", $post['email_neu'], 1); + } + else $form->addError("email", EMAIL_ERROR); + } + + if(!empty($post['del_pw']) && $post['del']){ + if(password_verify($post['del_pw'], $session->userinfo['password'])){ + $database->setDeleting($session->uid, 0); + } + else $form->addError("del", PASS_MISMATCH); + } + + if(!empty($post['v1'])){ + $sitid = $database->getUserField($post['v1'], "id", 1); + if($sitid == $session->userinfo['sit1'] || $sitid == $session->userinfo['sit2']){ + $form->addError("sit", SIT_ERROR); + }else if($sitid != $session->uid){ + if($session->userinfo['sit1'] == 0){ + $database->updateUserField($session->uid, "sit1", $sitid, 1); + }else if($session->userinfo['sit2'] == 0){ + $database->updateUserField($session->uid, "sit2", $sitid, 1); + } + } + } + + if($form->returnErrors() > 0){ + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $_POST; + } + + header("Location: spieler.php?s=3"); + exit; + } + + private function removeSitter($get) { + global $database,$session; + + if($get['a'] == $session->checker) { + if($session->userinfo['sit'.$get['type']] == $get['id']) { + $database->updateUserField($session->uid,"sit".$get['type'],0,1); + } + $session->changeChecker(); + } + + header("Location: spieler.php?s=".$get['s']); + exit; + } + + private function cancelDeleting($get) { + global $database, $session; + + $database->setDeleting($session->uid,1); + header("Location: spieler.php?s=".$get['s']); + exit; + } + + private function removeMeSit($get) { + global $database, $session; + + if($get['a'] == $session->checker) { + $database->removeMeSit($get['id'],$session->uid); + $session->changeChecker(); + } + + header("Location: spieler.php?s=".$get['s']); + exit; + } +}; $profile = new Profile; +?> diff --git a/GameEngine/Protection.php b/GameEngine/Protection.php index 442288c1..c295b420 100755 --- a/GameEngine/Protection.php +++ b/GameEngine/Protection.php @@ -5,97 +5,22 @@ ## Filename Protection.php ## ## Developed by: SlimShady ## ## Edited by: Dzoki & Dixie ## -## Enterprise hardening by Shadow ## ## License: TravianZ Project ## ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## +## ## ################################################################################# -/* -|-------------------------------------------------------------------------- -| Enterprise Superglobal Sanitizer -|-------------------------------------------------------------------------- -| - Does NOT corrupt numeric values -| - Recursive array support -| - Keeps rsargs intact -| - Does not break AJAX -| - Does not break NPC -| - Prevents XSS vectors -|-------------------------------------------------------------------------- -*/ - -if(!function_exists('secure_input_recursive')) { - - function secure_input_recursive($data) { - - if(is_array($data)) { - - $clean = array(); - - foreach($data as $key => $value) { - $clean[$key] = secure_input_recursive($value); - } - - return $clean; - } - - if(is_numeric($data)) { - return $data; - } - - if(is_string($data)) { - - // remove null bytes - $data = str_replace("\0", '', $data); - - // trim whitespace - $data = trim($data); - - // basic XSS protection - $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); - - return $data; - } - - return $data; - } -} - -/* -|-------------------------------------------------------------------------- -| Preserve rsargs (used by SAJAX) -|-------------------------------------------------------------------------- -*/ - -$rsargs_backup = null; - -if(isset($_GET['rsargs'])) { - $rsargs_backup = $_GET['rsargs']; -} - -/* -|-------------------------------------------------------------------------- -| Sanitize superglobals safely -|-------------------------------------------------------------------------- -*/ - -if(!empty($_POST)) { - $_POST = secure_input_recursive($_POST); -} - -if(!empty($_GET)) { - $_GET = secure_input_recursive($_GET); -} - -if(!empty($_COOKIE)) { - $_COOKIE = secure_input_recursive($_COOKIE); -} - -/* -|-------------------------------------------------------------------------- -| Restore rsargs if needed -|-------------------------------------------------------------------------- -*/ - -if($rsargs_backup !== null) { - $_GET['rsargs'] = $rsargs_backup; +//heef npc uitzondering omdat die met speciaal $_post werken +if(isset($_POST)){ + if(!isset($_POST['ft'])){ + //$_POST = @array_map('mysqli_real_escape_string', $_POST); + $_POST = array_map('htmlspecialchars', $_POST); + } } + $rsargs=$_GET['rsargs']; +//$_GET = array_map('mysqli_real_escape_string', $_GET); +$_GET = array_map('htmlspecialchars', $_GET); + $_GET['rsargs']=$rsargs; +//$_COOKIE = array_map('mysqli_real_escape_string', $_COOKIE); +$_COOKIE = array_map('htmlspecialchars', $_COOKIE); +?> \ No newline at end of file diff --git a/GameEngine/Ranking.php b/GameEngine/Ranking.php index 2a6b3dec..008549e8 100755 --- a/GameEngine/Ranking.php +++ b/GameEngine/Ranking.php @@ -9,678 +9,584 @@ | Copyright: TravianZ Project All rights reserved | \** --------------------------------------------------- **/ -class Ranking { + class Ranking { - public $rankarray = array(); - private $rlastupdate = 0; + public $rankarray = []; + private $rlastupdate; - public function getRank() { - return $this->rankarray; - } + public function getRank() { + return $this->rankarray; + } - public function getUserRank($id) { - global $database; + public function getUserRank($id) { + global $database; + + $ranking = $this->getRank(); + $users = "SELECT Count(*) as Total FROM " . TB_PREFIX . "users WHERE access < " . (INCLUDE_ADMIN ? "10" : "8"); + $users2 = mysqli_fetch_array(mysqli_query($database->dblink,$users), MYSQLI_ASSOC); + $users2 = $users2['Total']; + $users3 = $users2 + 1; + $myrank = 0; + if(count($ranking) > 0) { + for($i = 0;$i < $users3; $i++) { + if( isset( $ranking[$i]['userid'] ) ) { + if($ranking[$i]['userid'] == $id && $ranking[$i] != "pad") { + $myrank = $i; + } + } + } + } + return $myrank; + } - $id = (int)$id; - $ranking = $this->getRank(); + public function procRankReq($get) { + global $village, $session; + if(isset($get['id'])) { + switch($get['id']) { + case 1: + $this->procRankArray(); + break; + case 8: + $this->procHeroRankArray(); + if($get['hero'] == 0) { + $this->getStart(1); + } else { + $this->getStart($this->searchRank($session->uid, "uid")); + } + break; + case 11: + $this->procRankRaceArray(1); + if($this->searchRank($session->uid, "userid") != 0){ + $this->getStart($this->searchRank($session->uid, "userid")); + }else{ + $this->getStart(1); + } + break; + case 12: + $this->procRankRaceArray(2); + if($this->searchRank($session->uid, "userid") != 0){ + $this->getStart($this->searchRank($session->uid, "userid")); + }else{ + $this->getStart(1); + } + break; + case 13: + $this->procRankRaceArray(3); + if($this->searchRank($session->uid, "userid") != 0){ + $this->getStart($this->searchRank($session->uid, "userid")); + }else{ + $this->getStart(1); + } + break; + case 31: + $this->procAttRankArray(); + $this->getStart($this->searchRank($session->uid, "userid")); + break; + case 32: + $this->procDefRankArray(); + $this->getStart($this->searchRank($session->uid, "userid")); + break; + case 2: + $this->procVRankArray(); + $this->getStart($this->searchRank($village->wid, "wref")); + break; + case 4: + $this->procARankArray(); + if($get['aid'] == 0) { + $this->getStart(1); + } else { + $this->getStart($this->searchRank($get['aid'], "id")); + } + break; + case 41: + $this->procAAttRankArray(); + if($get['aid'] == 0) { + $this->getStart(1); + } else { + $this->getStart($this->searchRank($get['aid'], "id")); + } + break; + case 42: + $this->procADefRankArray(); + if($get['aid'] == 0) { + $this->getStart(1); + } else { + $this->getStart($this->searchRank($get['aid'], "id")); + } + break; + } + } else { + $this->procRankArray(); + $this->getStart($this->searchRank($session->uid, "userid")); + } + } - $usersQuery = "SELECT Count(*) as Total FROM " . TB_PREFIX . "users - WHERE access < " . (INCLUDE_ADMIN ? "10" : "8"); + public function procRank($post) { + if(isset($post['ft'])) { + switch($post['ft']) { + case "r1": + case "r11": + case "r12": + case "r13": + case "r31": + case "r32": + if(isset($post['rank']) && $post['rank'] != "") { + $this->getStart($post['rank']); + } + if(isset($post['name']) && $post['name'] != "") { + $this->getStart($this->searchRank(stripslashes($post['name']), "username")); + } + break; + case "r4": + case "r42": + case "r41": + if(isset($post['rank']) && $post['rank'] != "") { + $this->getStart($post['rank']); + } + if(isset($post['name']) && $post['name'] != "") { + $this->getStart($this->searchRank(stripslashes($post['name']), "tag")); + } + break; + case "r2": + case "r8": + if(isset($post['rank']) && $post['rank'] != "") { + $this->getStart($post['rank']); + } + if(isset($post['name']) && $post['name'] != "") { + $this->getStart($this->searchRank(stripslashes($post['name']), "name")); + } + break; + } + } + } - $usersResult = mysqli_query($database->dblink, $usersQuery); - if(!$usersResult) return 0; + private function getStart($search) { + $multiplier = 1; + if(!is_numeric($search)) { + $_SESSION['search'] = htmlspecialchars($search); + } else { + if($search > count($this->rankarray)) { + $search = count($this->rankarray) - 1; + } + while($search > (20 * $multiplier)) { + $multiplier += 1; + } + $start = 20 * $multiplier - 19 - 1; + $_SESSION['search'] = htmlspecialchars($search); + $_SESSION['start'] = htmlspecialchars($start); + } + } - $usersRow = mysqli_fetch_array($usersResult, MYSQLI_ASSOC); - $totalUsers = isset($usersRow['Total']) ? (int)$usersRow['Total'] : 0; + public function getAllianceRank($id) { + $this->procARankArray(); + while(1) { + if(count($this->rankarray) > 1) { + $key = key($this->rankarray); + if(isset ($this->rankarray[$key]["id"]) && $this->rankarray[$key]["id"] === $id) { + return $key; + break; + } else { + if(!next($this->rankarray)) { + return false; + break; + } + } + } else { + return 1; + } + } + } - $limit = $totalUsers + 1; - $myrank = 0; + public function searchRank($name, $field) { + + while(1) { + //$key = key($this->rankarray); + for($key = 0; $key < count($this->rankarray); $key++){ + if($this->rankarray[$key]!="pad") { + if($this->rankarray[$key][$field] == $name) return $key; + } + } + if(!next($this->rankarray)) { + if($field != "userid") return $name; + else return 0; + } + + } + } - if(!empty($ranking)) { - for($i = 0; $i < $limit; $i++) { - if(isset($ranking[$i]['userid']) && $ranking[$i] !== "pad") { - if((int)$ranking[$i]['userid'] === $id) { - $myrank = $i; - break; + public function procRankArray() { + global $multisort, $database; + + if($GLOBALS['db']->countUser() > 0){ + $holder = array(); + if(SHOW_NATARS == True){ + $q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.username username, " . TB_PREFIX . "users.oldrank oldrank, " . TB_PREFIX . "users.alliance alliance, ( + + SELECT SUM( " . TB_PREFIX . "vdata.pop ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid + )totalpop, ( + + SELECT COUNT( " . TB_PREFIX . "vdata.wref ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid AND type != 99 + )totalvillages, ( + + SELECT " . TB_PREFIX . "alidata.tag + FROM " . TB_PREFIX . "alidata, " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "alidata.id = " . TB_PREFIX . "users.alliance + AND " . TB_PREFIX . "users.id = userid + )allitag + FROM " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "users.access < " . (INCLUDE_ADMIN ? "10" : "8") . " + AND (" . TB_PREFIX . "users.tribe <= 5 OR " . TB_PREFIX . "users.tribe = 5) + AND (" . TB_PREFIX . "users.id > 5 OR " . TB_PREFIX . "users.id = 3) + ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; + } else { + $q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.username username, " . TB_PREFIX . "users.oldrank oldrank, " . TB_PREFIX . "users.alliance alliance, ( + + SELECT SUM( " . TB_PREFIX . "vdata.pop ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid + )totalpop, ( + + SELECT COUNT( " . TB_PREFIX . "vdata.wref ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid AND type != 99 + )totalvillages, ( + + SELECT " . TB_PREFIX . "alidata.tag + FROM " . TB_PREFIX . "alidata, " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "alidata.id = " . TB_PREFIX . "users.alliance + AND " . TB_PREFIX . "users.id = userid + )allitag + FROM " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "users.access < " . (INCLUDE_ADMIN ? "10" : "8") . " + AND " . TB_PREFIX . "users.tribe <= 3 + AND " . TB_PREFIX . "users.id > 5 + ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; + } + + $datas = []; + + $result = (mysqli_query($database->dblink,$q)); + while($row = mysqli_fetch_assoc($result)) $datas[] = $row; + + if (count($datas)) { + foreach($datas as $result) { + $value['userid'] = $result['userid']; + $value['username'] = $result['username']; + $value['oldrank'] = $result['oldrank']; + $value['alliance'] = $result['alliance']; + $value['aname'] = $result['allitag']; + $value['totalpop'] = $result['totalpop']; + $value['totalvillage'] = $result['totalvillages']; + array_push($holder, $value); + } + } + + $newholder = ["pad"]; + foreach($holder as $key) array_push($newholder, $key); + + $this->rankarray = $newholder; + + } + } + + public function procRankRaceArray($race) { + global $multisort, $database; + $race = $database->escape((int) $race); + //$array = $GLOBALS['db']->getRanking(); + $holder = array(); + //$value['totalvillage'] = count($GLOBALS['db']->getVillagesID($value['id'])); + //$value['totalvillage'] = count($GLOBALS['db']->getVillagesID($value['id'])); + //$value['totalpop'] = $GLOBALS['db']->getVSumField($value['id'],"pop"); + //$value['aname'] = $GLOBALS['db']->getAllianceName($value['alliance']); + $q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.tribe tribe, " . TB_PREFIX . "users.username username," . TB_PREFIX . "users.alliance alliance, ( + + SELECT SUM( " . TB_PREFIX . "vdata.pop ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid + )totalpop, ( + + SELECT COUNT( " . TB_PREFIX . "vdata.wref ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid AND type != 99 + )totalvillages, ( + + SELECT " . TB_PREFIX . "alidata.tag + FROM " . TB_PREFIX . "alidata, " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "alidata.id = " . TB_PREFIX . "users.alliance + AND " . TB_PREFIX . "users.id = userid + )allitag + FROM " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "users.tribe = $race AND " . TB_PREFIX . "users.access < " . (INCLUDE_ADMIN ? "10" : "8") . " + AND " . TB_PREFIX . "users.id > 5 + ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; + + + $result = (mysqli_query($database->dblink,$q)); + while($row = mysqli_fetch_assoc($result)) { + $datas[] = $row; + } + + if(mysqli_num_rows($result)) { + + + foreach($datas as $result) { + $value['userid'] = $result['userid']; + $value['username'] = $result['username']; + $value['alliance'] = $result['alliance']; + $value['aname'] = $result['allitag']; + $value['totalpop'] = $result['totalpop']; + $value['totalvillage'] = $result['totalvillages']; + //SELECT (SELECT SUM(".TB_PREFIX."vdata.pop) FROM ".TB_PREFIX."vdata WHERE ".TB_PREFIX."vdata.owner = 2) totalpop, (SELECT COUNT(".TB_PREFIX."vdata.wref) FROM ".TB_PREFIX."vdata WHERE ".TB_PREFIX."vdata.owner = 2) totalvillages, (SELECT ".TB_PREFIX."alidata.tag FROM ".TB_PREFIX."alidata WHERE ".TB_PREFIX."alidata.id = ".TB_PREFIX."users.alliance AND ".TB_PREFIX."users.id = 2); + array_push($holder, $value); + } + } else { + $value['userid'] = 0; + $value['username'] = "No User"; + $value['alliance'] = ""; + $value['aname'] = ""; + $value['totalpop'] = ""; + $value['totalvillage'] = ""; + array_push($holder, $value); + } + //$holder = $multisort->sorte($holder, "'totalvillage'", false, 2, "'totalpop'", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } + + public function procAttRankArray() { + global $multisort, $database; + //$array = $GLOBALS['db']->getRanking(); + $holder = array(); + + //$value['totalvillage'] = count($GLOBALS['db']->getVillagesID($value['id'])); + //$value['totalpop'] = $GLOBALS['db']->getVSumField($value['id'],"pop"); + $q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.username username, " . TB_PREFIX . "users.apall, ( + + SELECT COUNT( " . TB_PREFIX . "vdata.wref ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid AND type != 99 + )totalvillages, ( + + SELECT SUM( " . TB_PREFIX . "vdata.pop ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid + )pop + FROM " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "users.apall >=0 AND " . TB_PREFIX . "users.access < " . (INCLUDE_ADMIN ? "10" : "8") . " AND " . TB_PREFIX . "users.tribe <= 3 + AND " . TB_PREFIX . "users.id > 5 + ORDER BY " . TB_PREFIX . "users.apall DESC, pop DESC, userid DESC"; + $result = mysqli_query($database->dblink,$q) or die(mysqli_error($database->dblink)); + while($row = mysqli_Fetch_assoc($result)) { + $datas[] = $row; + } + + foreach($datas as $key => $row) { + $value['userid'] = $row['userid']; + $value['username'] = $row['username']; + $value['totalvillages'] = $row['totalvillages']; + $value['id'] = $row['userid']; + $value['totalpop'] = $row['pop']; + $value['apall'] = $row['apall']; + array_push($holder, $value); + printf("\n\n", $value['username'], $value['totalvillages'], $value['totalpop'], $value['apall']); + } + + //$holder = $multisort->sorte($holder, "'ap'", false, 2, "'totalvillages'", false, 2, "'ap'", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } + + public function procDefRankArray() { + global $database; + //global $GLOBALS['db'], $multisort; + //$array = $GLOBALS['db']->getRanking(); + $holder = array(); + $q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.username username, " . TB_PREFIX . "users.dpall, ( + + SELECT COUNT( " . TB_PREFIX . "vdata.wref ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid AND type != 99 + )totalvillages, ( + + SELECT SUM( " . TB_PREFIX . "vdata.pop ) + FROM " . TB_PREFIX . "vdata + WHERE " . TB_PREFIX . "vdata.owner = userid + )pop + FROM " . TB_PREFIX . "users + WHERE " . TB_PREFIX . "users.dpall >=0 AND " . TB_PREFIX . "users.access < " . (INCLUDE_ADMIN ? "10" : "8") . " AND " . TB_PREFIX . "users.tribe <= 3 + AND " . TB_PREFIX . "users.id > 5 + ORDER BY " . TB_PREFIX . "users.dpall DESC, pop DESC, userid DESC"; + $result = mysqli_query($database->dblink,$q) or die(mysqli_error($database->dblink)); + while($row = mysqli_Fetch_assoc($result)) { + $datas[] = $row; + } + + foreach($datas as $key => $row) { + $value['userid'] = $row['userid']; + $value['username'] = $row['username']; + $value['totalvillages'] = $row['totalvillages']; + $value['id'] = $row['userid']; + $value['totalpop'] = $row['pop']; + $value['dpall'] = $row['dpall']; + array_push($holder, $value); + + } + + //$holder = $multisort->sorte($holder, "'dpall'", false, 2, "'totalvillage'", false, 2, "'dpall'", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } + + public function procVRankArray() { + global $multisort; + $array = $GLOBALS['db']->getVRanking(); + $holder = array(); + foreach($array as $value) { + $coor = $GLOBALS['db']->getCoor($value['wref']); + $value['x'] = $coor['x']; + $value['y'] = $coor['y']; + $value['user'] = $GLOBALS['db']->getUserField($value['owner'], "username", 0); + + array_push($holder, $value); + } + $holder = $multisort->sorte($holder, "x", true, 2, "y", true, 2, "pop", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } + + public function procARankArray() { + global $multisort, $database; + $array = $GLOBALS['db']->getARanking(); + $holder = array(); + + foreach($array as $value) { + $memberlist = $GLOBALS['db']->getAllMember($value['id']); + $totalpop = 0; + + $memberIDs = []; + foreach($memberlist as $member) { + $memberIDs[] = $member['id']; } - } - } - } + $data = $database->getVSumField($memberIDs,"pop"); - return $myrank; - } - - public function procRankReq($get) { - global $village, $session; - - if(isset($get['id'])) { - - $id = (int)$get['id']; - - switch($id) { - - case 1: - $this->procRankArray(); - break; - - case 8: - $this->procHeroRankArray(); - if(isset($get['hero']) && (int)$get['hero'] !== 0) { - $this->getStart($this->searchRank($session->uid, "uid")); - } else { - $this->getStart(1); - } - break; - - case 11: - case 12: - case 13: - $this->procRankRaceArray($id - 10); - $rank = $this->searchRank($session->uid, "userid"); - $this->getStart($rank !== 0 ? $rank : 1); - break; - - case 31: - $this->procAttRankArray(); - $this->getStart($this->searchRank($session->uid, "userid")); - break; - - case 32: - $this->procDefRankArray(); - $this->getStart($this->searchRank($session->uid, "userid")); - break; - - case 2: - $this->procVRankArray(); - $this->getStart($this->searchRank($village->wid, "wref")); - break; - - case 4: - case 41: - case 42: - if($id == 4) $this->procARankArray(); - if($id == 41) $this->procAAttRankArray(); - if($id == 42) $this->procADefRankArray(); - - $aid = isset($get['aid']) ? (int)$get['aid'] : 0; - if($aid === 0) { - $this->getStart(1); - } else { - $this->getStart($this->searchRank($aid, "id")); - } - break; - } - - } else { - $this->procRankArray(); - $this->getStart($this->searchRank($session->uid, "userid")); - } - } - - public function procRank($post) { - - if(!isset($post['ft'])) return; - - $ft = $post['ft']; - - if(isset($post['rank']) && $post['rank'] !== "") { - $this->getStart((int)$post['rank']); - } - - if(isset($post['name']) && $post['name'] !== "") { - - $name = stripslashes($post['name']); - - switch($ft) { - case "r1": - case "r11": - case "r12": - case "r13": - case "r31": - case "r32": - $this->getStart($this->searchRank($name, "username")); - break; - - case "r4": - case "r42": - case "r41": - $this->getStart($this->searchRank($name, "tag")); - break; - - case "r2": - case "r8": - $this->getStart($this->searchRank($name, "name")); - break; - } - } - } - - private function getStart($search) { - - if(!is_numeric($search)) { - $_SESSION['search'] = htmlspecialchars($search, ENT_QUOTES, 'UTF-8'); - return; - } - - $search = (int)$search; - $count = count($this->rankarray); - - if($count <= 1) return; - - if($search > $count) { - $search = $count - 1; - } - - $multiplier = 1; - - while($search > (20 * $multiplier)) { - $multiplier++; - } - - $start = (20 * $multiplier) - 19 - 1; - - $_SESSION['search'] = htmlspecialchars($search, ENT_QUOTES, 'UTF-8'); - $_SESSION['start'] = htmlspecialchars($start, ENT_QUOTES, 'UTF-8'); - } - - public function getAllianceRank($id) { - - $id = (int)$id; - $this->procARankArray(); - - if(count($this->rankarray) <= 1) return 1; - - foreach($this->rankarray as $key => $row) { - if($row !== "pad" && isset($row['id']) && (int)$row['id'] === $id) { - return $key; - } - } - - return false; - } - - public function searchRank($name, $field) { - - if(empty($this->rankarray)) return 0; - - foreach($this->rankarray as $key => $row) { - if($row !== "pad" && isset($row[$field])) { - if($row[$field] == $name) { - return $key; - } - } - } - - return ($field !== "userid") ? $name : 0; - } - public function procRankArray() { - global $database; - - if($GLOBALS['db']->countUser() <= 0) { - $this->rankarray = array("pad"); - return; - } - - $holder = array(); - - if(SHOW_NATARS == true) { - - $q = "SELECT u.id userid, u.username username, u.oldrank oldrank, - u.alliance alliance, - - (SELECT SUM(v.pop) FROM ".TB_PREFIX."vdata v WHERE v.owner = u.id) totalpop, - - (SELECT COUNT(v.wref) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id AND v.type != 99) totalvillages, - - (SELECT a.tag FROM ".TB_PREFIX."alidata a - WHERE a.id = u.alliance) allitag - - FROM ".TB_PREFIX."users u - WHERE u.access < ".(INCLUDE_ADMIN ? "10" : "8")." - AND (u.tribe <= 5 OR u.tribe = 5) - AND (u.id > 5 OR u.id = 3) - ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; - - } else { - - $q = "SELECT u.id userid, u.username username, u.oldrank oldrank, - u.alliance alliance, - - (SELECT SUM(v.pop) FROM ".TB_PREFIX."vdata v WHERE v.owner = u.id) totalpop, - - (SELECT COUNT(v.wref) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id AND v.type != 99) totalvillages, - - (SELECT a.tag FROM ".TB_PREFIX."alidata a - WHERE a.id = u.alliance) allitag - - FROM ".TB_PREFIX."users u - WHERE u.access < ".(INCLUDE_ADMIN ? "10" : "8")." - AND u.tribe <= 3 - AND u.id > 5 - ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; - } - - $result = mysqli_query($database->dblink, $q); - if(!$result) { - $this->rankarray = array("pad"); - return; - } - - while($row = mysqli_fetch_assoc($result)) { - - $value = array(); - $value['userid'] = (int)$row['userid']; - $value['username'] = $row['username']; - $value['oldrank'] = (int)$row['oldrank']; - $value['alliance'] = (int)$row['alliance']; - $value['aname'] = $row['allitag']; - $value['totalpop'] = (int)$row['totalpop']; - $value['totalvillage'] = (int)$row['totalvillages']; - - $holder[] = $value; - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procRankRaceArray($race) { - global $database; - - $race = (int)$race; - $holder = array(); - - $q = "SELECT u.id userid, u.tribe tribe, u.username username, - u.alliance alliance, - - (SELECT SUM(v.pop) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id) totalpop, - - (SELECT COUNT(v.wref) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id AND v.type != 99) totalvillages, - - (SELECT a.tag FROM ".TB_PREFIX."alidata a - WHERE a.id = u.alliance) allitag - - FROM ".TB_PREFIX."users u - WHERE u.tribe = $race - AND u.access < ".(INCLUDE_ADMIN ? "10" : "8")." - AND u.id > 5 - ORDER BY totalpop DESC, totalvillages DESC, userid DESC"; - - $result = mysqli_query($database->dblink, $q); - - if($result && mysqli_num_rows($result) > 0) { - - while($row = mysqli_fetch_assoc($result)) { - - $value = array(); - $value['userid'] = (int)$row['userid']; - $value['username'] = $row['username']; - $value['alliance'] = (int)$row['alliance']; - $value['aname'] = $row['allitag']; - $value['totalpop'] = (int)$row['totalpop']; - $value['totalvillage'] = (int)$row['totalvillages']; - - $holder[] = $value; - } - - } else { - - $holder[] = array( - 'userid' => 0, - 'username' => "No User", - 'alliance' => "", - 'aname' => "", - 'totalpop' => "", - 'totalvillage' => "" - ); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procAttRankArray() { - global $database; - - $holder = array(); - - $q = "SELECT u.id userid, u.username username, u.apall, - - (SELECT COUNT(v.wref) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id AND v.type != 99) totalvillages, - - (SELECT SUM(v.pop) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id) pop - - FROM ".TB_PREFIX."users u - WHERE u.apall >= 0 - AND u.access < ".(INCLUDE_ADMIN ? "10" : "8")." - AND u.tribe <= 3 - AND u.id > 5 - ORDER BY u.apall DESC, pop DESC, userid DESC"; - - $result = mysqli_query($database->dblink, $q); - - if(!$result) { - $this->rankarray = array("pad"); - return; - } - - while($row = mysqli_fetch_assoc($result)) { - - $value = array(); - $value['userid'] = (int)$row['userid']; - $value['username'] = $row['username']; - $value['totalvillages'] = (int)$row['totalvillages']; - $value['id'] = (int)$row['userid']; - $value['totalpop'] = (int)$row['pop']; - $value['apall'] = (int)$row['apall']; - - $holder[] = $value; - - // păstrăm debug comment original (nu afectează logica) - printf("\n\n", - $value['username'], - $value['totalvillages'], - $value['totalpop'], - $value['apall'] - ); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procDefRankArray() { - global $database; - - $holder = array(); - - $q = "SELECT u.id userid, u.username username, u.dpall, - - (SELECT COUNT(v.wref) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id AND v.type != 99) totalvillages, - - (SELECT SUM(v.pop) FROM ".TB_PREFIX."vdata v - WHERE v.owner = u.id) pop - - FROM ".TB_PREFIX."users u - WHERE u.dpall >= 0 - AND u.access < ".(INCLUDE_ADMIN ? "10" : "8")." - AND u.tribe <= 3 - AND u.id > 5 - ORDER BY u.dpall DESC, pop DESC, userid DESC"; - - $result = mysqli_query($database->dblink, $q); - - if(!$result) { - $this->rankarray = array("pad"); - return; - } - - while($row = mysqli_fetch_assoc($result)) { - - $value = array(); - $value['userid'] = (int)$row['userid']; - $value['username'] = $row['username']; - $value['totalvillages'] = (int)$row['totalvillages']; - $value['id'] = (int)$row['userid']; - $value['totalpop'] = (int)$row['pop']; - $value['dpall'] = (int)$row['dpall']; - - $holder[] = $value; - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procVRankArray() { - global $multisort; - - $array = $GLOBALS['db']->getVRanking(); - $holder = array(); - - if(!is_array($array)) { - $this->rankarray = array("pad"); - return; - } - - foreach($array as $value) { - - $coor = $GLOBALS['db']->getCoor($value['wref']); - - if(!is_array($coor)) { - $coor = array('x' => 0, 'y' => 0); - } - - $value['x'] = isset($coor['x']) ? (int)$coor['x'] : 0; - $value['y'] = isset($coor['y']) ? (int)$coor['y'] : 0; - $value['user'] = $GLOBALS['db']->getUserField($value['owner'], "username", 0); - - $holder[] = $value; - } - - if(is_array($holder) && count($holder) > 0) { - $holder = $multisort->sorte($holder, "x", true, 2, "y", true, 2, "pop", false, 2); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procARankArray() { - global $multisort, $database; - - $array = $GLOBALS['db']->getARanking(); - $holder = array(); - - if(!is_array($array)) { - $this->rankarray = array("pad"); - return; - } - - foreach($array as $value) { - - $memberlist = $GLOBALS['db']->getAllMember($value['id']); - $totalpop = 0; - - if(!is_array($memberlist)) { - $memberlist = array(); - } - - $memberIDs = array(); - foreach($memberlist as $member) { - if(isset($member['id'])) { - $memberIDs[] = (int)$member['id']; - } - } - - if(count($memberIDs) > 0) { - - $data = $database->getVSumField($memberIDs, "pop"); - - if(is_array($data)) { - foreach($data as $row) { - if(isset($row['Total'])) { - $totalpop += (int)$row['Total']; + if (count($data)) { + foreach ($data as $row) { + $totalpop += $row['Total']; } } - } - } - $value['players'] = count($memberlist); - $value['totalpop'] = $totalpop; + $value['players'] = count($memberlist); + $value['totalpop'] = $totalpop; + if(!isset($value['avg'])) { + $value['avg'] = @round($totalpop / count($memberlist)); + } else { + $value['avg'] = 0; + } - if(count($memberlist) > 0) { - $value['avg'] = (int)round($totalpop / count($memberlist)); - } else { - $value['avg'] = 0; - } + array_push($holder, $value); + } + $holder = $multisort->sorte($holder, "totalpop", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } - $holder[] = $value; - } + public function procHeroRankArray() { + global $multisort; + $array = $GLOBALS['db']->getHeroRanking(); + $holder = array(); + foreach($array as $value) { + $value['owner'] = $GLOBALS['db']->getUserField($value['uid'], "username", 0); + $value['level']; + $value['name']; + $value['uid']; - if(is_array($holder) && count($holder) > 0) { - $holder = $multisort->sorte($holder, "totalpop", false, 2); - } + array_push($holder, $value); + } + $holder = $multisort->sorte($holder, "experience", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } + public function procAAttRankArray() { + global $multisort; + $array = $GLOBALS['db']->getARanking(); + $holder = array(); + foreach($array as $value) { + $memberlist = $GLOBALS['db']->getAllMember($value['id']); + $totalap = 0; + foreach($memberlist as $member) { + $totalap += $member['ap']; + } + $value['players'] = count($memberlist); + $value['totalap'] = $totalap; + if($value['avg'] > 0) { + $value['avg'] = round($totalap / count($memberlist)); + } else { + $value['avg'] = 0; + } - $this->rankarray = $newholder; - } - public function procHeroRankArray() { - global $multisort; + array_push($holder, $value); + } + $holder = $multisort->sorte($holder, "Aap", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } - $array = $GLOBALS['db']->getHeroRanking(); - $holder = array(); + public function procADefRankArray() { + global $multisort; + $array = $GLOBALS['db']->getARanking(); + $holder = array(); + foreach($array as $value) { + $memberlist = $GLOBALS['db']->getAllMember($value['id']); + $totaldp = 0; + foreach($memberlist as $member) { + $totaldp += $member['dp']; + } + $value['players'] = count($memberlist); + $value['totaldp'] = $totaldp; + if($value['avg'] > 0) { + $value['avg'] = round($totalap / count($memberlist)); + } else { + $value['avg'] = 0; + } - if(!is_array($array)) { - $this->rankarray = array("pad"); - return; - } + array_push($holder, $value); + } + $holder = $multisort->sorte($holder, "Adp", false, 2); + $newholder = array("pad"); + foreach($holder as $key) { + array_push($newholder, $key); + } + $this->rankarray = $newholder; + } + } + ; - foreach($array as $value) { - - $value['owner'] = $GLOBALS['db']->getUserField($value['uid'], "username", 0); - - $holder[] = $value; - } - - if(count($holder) > 0) { - $holder = $multisort->sorte($holder, "experience", false, 2); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procAAttRankArray() { - global $multisort; - - $array = $GLOBALS['db']->getARanking(); - $holder = array(); - - if(!is_array($array)) { - $this->rankarray = array("pad"); - return; - } - - foreach($array as $value) { - - $memberlist = $GLOBALS['db']->getAllMember($value['id']); - $totalap = 0; - - if(!is_array($memberlist)) { - $memberlist = array(); - } - - foreach($memberlist as $member) { - if(isset($member['ap'])) { - $totalap += (int)$member['ap']; - } - } - - $value['players'] = count($memberlist); - $value['totalap'] = $totalap; - - if(count($memberlist) > 0) { - $value['avg'] = (int)round($totalap / count($memberlist)); - } else { - $value['avg'] = 0; - } - - $holder[] = $value; - } - - if(count($holder) > 0) { - $holder = $multisort->sorte($holder, "Aap", false, 2); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - public function procADefRankArray() { - global $multisort; - - $array = $GLOBALS['db']->getARanking(); - $holder = array(); - - if(!is_array($array)) { - $this->rankarray = array("pad"); - return; - } - - foreach($array as $value) { - - $memberlist = $GLOBALS['db']->getAllMember($value['id']); - $totaldp = 0; - - if(!is_array($memberlist)) { - $memberlist = array(); - } - - foreach($memberlist as $member) { - if(isset($member['dp'])) { - $totaldp += (int)$member['dp']; - } - } - - $value['players'] = count($memberlist); - $value['totaldp'] = $totaldp; - - if(count($memberlist) > 0) { - $value['avg'] = (int)round($totaldp / count($memberlist)); // FIX BUG (era $totalap) - } else { - $value['avg'] = 0; - } - - $holder[] = $value; - } - - if(count($holder) > 0) { - $holder = $multisort->sorte($holder, "Adp", false, 2); - } - - $newholder = array("pad"); - foreach($holder as $row) { - $newholder[] = $row; - } - - $this->rankarray = $newholder; - } - } - ; - - $ranking = new Ranking; + $ranking = new Ranking; ?> diff --git a/GameEngine/Session.php b/GameEngine/Session.php index abdc0117..8d4d0235 100755 --- a/GameEngine/Session.php +++ b/GameEngine/Session.php @@ -8,25 +8,26 @@ mb_internal_encoding("UTF-8"); // Add for utf8 varriables. ## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ## ## --------------------------------------------------------------------------- ## ## Project: TravianZ ## -## Version: 22.06.2015 ## +## Version: 22.06.2015 ## ## Filename Session.php ## ## Developed by: Mr.php , Advocaite , brainiacX , yi12345 , Shadow , ronix ## -## Fixed by: Shadow - STARVATION , HERO FIXED COMPL. ## -## Fixed by: InCube - double troops ## -## Refactored TravianZ Enterprise Hardened Core by Shadow ## +## Fixed by: Shadow - STARVATION , HERO FIXED COMPL. ## +## Fixed by: InCube - double troops ## ## License: TravianZ Project ## ## Copyright: TravianZ (c) 2010-2015. All rights reserved. ## -## URLs: http://travian.shadowss.ro ## -## Source code: https://github.com/Shadowss/TravianZ ## +## URLs: http://travian.shadowss.ro ## +## Source code: https://github.com/Shadowss/TravianZ ## ## ## ################################################################################# global $autoprefix; +// go max 5 levels up - we don't have folders that go deeper than that $autoprefix = ''; for ($i = 0; $i < 5; $i++) { $autoprefix = str_repeat('../', $i); if (file_exists($autoprefix.'autoloader.php')) { + // we have our path, let's leave break; } } @@ -37,7 +38,6 @@ if(!file_exists($autoprefix.'GameEngine/config.php')) { } $script_name = ($_SERVER['REQUEST_URI'] == 'karte.php') ? 'karte' : $_SERVER['REQUEST_URI']; - include_once ("Battle.php"); include_once ("Data/buidata.php"); include_once ("Data/cp.php"); @@ -60,440 +60,324 @@ include_once ("Profile.php"); class Session { - private $time; - var $logged_in = false; - var $referrer, $url; - var $username, $uid, $access, $plus, $tribe, $isAdmin, $alliance, $gold, $oldrank, $gpack, $goldclub; - var $bonus = 0; - var $bonus1 = 0; - var $bonus2 = 0; - var $bonus3 = 0; - var $bonus4 = 0; - var $timer = 0; - var $sharedForums = array(); - var $checker, $mchecker; - public $userinfo = array(); - private $userarray = array(); - var $villages = array(); + private $time; + var $logged_in = false; + var $referrer, $url; + var $username, $uid, $access, $plus, $tribe, $isAdmin, $alliance, $gold, $oldrank, $gpack, $goldclub; + var $bonus = 0; + var $bonus1 = 0; + var $bonus2 = 0; + var $bonus3 = 0; + var $bonus4 = 0; + var $timer = 0; + var $sharedForums = []; + var $checker, $mchecker; + public $userinfo = []; + private $userarray = []; + var $villages = []; - function __construct() { - global $database; + function __construct() { + global $database; //TienTN fix - $this->time = time(); + $this->time = time(); + if (!isset($_SESSION)) { + session_start(); + } - if (session_status() == PHP_SESSION_NONE) { - session_start(); - } + $this->logged_in = $this->checkLogin(); - session_regenerate_id(true); // 🔒 Session fixation protection + if($this->logged_in && TRACK_USR) $database->updateActiveUser($this->username, $this->time); + + if(isset($_SESSION['url'])) $this->referrer = $_SESSION['url']; + else $this->referrer = "/"; + + $this->url = $_SESSION['url'] = $_SERVER['PHP_SELF']; + $this->SurfControl(); + } - $this->logged_in = $this->checkLogin(); + public function Login($user) { + global $database, $generator, $logging; + + $this->logged_in = true; + $_SESSION['sessid'] = $generator->generateRandID(); + $_SESSION['username'] = $user; + $user_sanitized = $database->escape($user); + $_SESSION['checker'] = $generator->generateRandStr(3); + $_SESSION['mchecker'] = $generator->generateRandStr(5); - if($this->logged_in && TRACK_USR) { - $database->updateActiveUser($this->username, $this->time); - } + $userFields = $database->getUserFields($user_sanitized, "quest, id", 1, true); + $_SESSION['qst'] = $userFields["quest"]; - $this->referrer = isset($_SESSION['url']) ? $_SESSION['url'] : "/"; - $this->url = $_SESSION['url'] = $_SERVER['PHP_SELF']; + $dbarray = $database->getUserFields($user_sanitized, 'id, village_select', 1); + $selected_village=(int) $dbarray['village_select']; - $this->SurfControl(); - } - public function Login($user) { - global $database, $generator, $logging; + if ($dbarray['id'] > 1) { + if(!isset($_SESSION['wid'])) { + if(!empty($selected_village)) $data = $database->getVillage($selected_village); + else $data = $database->getVillage($userFields["id"]); + $_SESSION['wid'] = $data['wref']; + } else + if(empty($_SESSION['wid'])) { + if(!empty($selected_village)) $data = $database->getVillage($selected_village); + else $data = $database->getVillage($userFields["id"]); + $_SESSION['wid'] = $data['wref']; + } + $this->PopulateVar(); - if(empty($user)) { - header("Location: login.php"); - exit; - } + $database->updateActiveUser($user_sanitized, $this->time); + $database->updateUserField($user_sanitized, "sessid", $_SESSION['sessid'], 0); + } - $this->logged_in = true; + $logging->addLoginLog($dbarray['id'], $_SERVER['REMOTE_ADDR']); - $_SESSION['sessid'] = $generator->generateRandID(); - $_SESSION['username'] = $user; - $_SESSION['checker'] = $generator->generateRandStr(3); - $_SESSION['mchecker'] = $generator->generateRandStr(5); + if ($dbarray['id'] == 1) { + header("Location: nachrichten.php"); + exit; + } else { + header("Location: dorf1.php"); + exit; + } + } - // 🔒 Prepared statement (critical zone) - $stmt = $database->dblink->prepare( - "SELECT id, quest, village_select FROM " . TB_PREFIX . "users WHERE username = ? LIMIT 1" - ); - $stmt->bind_param("s", $user); - $stmt->execute(); - $result = $stmt->get_result(); - $dbarray = $result->fetch_assoc(); - $stmt->close(); + public function Logout() { + global $database; + $this->logged_in = false; + $database->updateUserField($_SESSION['username'], "sessid", "", 0); + if(ini_get("session.use_cookies")) { + $params = session_get_cookie_params(); + setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]); + } + session_destroy(); + session_start(); + } - if(!$dbarray) { - $this->Logout(); - header("Location: login.php"); - exit; - } + public function changeChecker() { + global $generator; + + $this->checker = $_SESSION['checker'] = $generator->generateRandStr(3); + $this->mchecker = $_SESSION['mchecker'] = $generator->generateRandStr(5); + } - $_SESSION['id_user'] = (int)$dbarray['id']; - $_SESSION['qst'] = $dbarray['quest']; + private function checkLogin(){ + global $database; + + $user = $id = ''; + $admin = false; + $inAdmin = (strpos($_SERVER['REQUEST_URI'], '/Admin') !== false); - $selected_village = (int)$dbarray['village_select']; + if (!$inAdmin && isset($_SESSION['username'])) { + $user = $_SESSION['username']; + $id = (int) $_SESSION['id_user']; + } else if ($inAdmin && isset($_SESSION['admin_username'])) { + $user = $_SESSION['admin_username']; + $id = (int) $_SESSION['id']; + $admin = true; + } - if(!isset($_SESSION['wid']) || empty($_SESSION['wid'])) { + if($user && ($admin || isset($_SESSION['sessid']))) { + $this->maintenance(); + $this->isWinner(); + + // check if this is not a support user, for who only messages and statistics are available + if ($user == 'Support') { + $req_file = basename($_SERVER['PHP_SELF']); + if (!in_array($req_file, ['nachrichten.php', 'logout.php', 'statistiken.php', 'rules.php', 'karte.php', 'karte2.php', 'spieler.php'])) { + header('Location: nachrichten.php'); + exit; + } + } - if(!empty($selected_village)) { - $data = $database->getVillage($selected_village); - } else { - $data = $database->getVillage($dbarray['id']); - } + //Get and Populate Data + $this->PopulateVar(); + + //Check if the player is banned + $this->isBanned(); + + //update database + $database->updateActiveUser($user, $this->time); + return true; + } + else return false; + } - if(isset($data['wref'])) { - $_SESSION['wid'] = (int)$data['wref']; - } - } + /** + * Called if the player is banned + * + */ + + function isBanned(){ + if($this->access == BANNED && !in_array(basename($_SERVER['PHP_SELF']), ['banned.php', 'nachrichten.php', 'rules.php'])){ + header('Location: banned.php'); + exit; + } + } + + /** + * Called when the server is under maintenance + * + */ + + function maintenance(){ + if($_SESSION['ok'] == 2 && basename($_SERVER['PHP_SELF']) != 'maintenance.php'){ + header('Location: maintenance.php'); + exit; + } + } + + /** + * Called when there's a player who built a WW to level 100 + * + */ + + function isWinner(){ + global $database; + + $requiredPage = basename($_SERVER['PHP_SELF']); + if($database->isThereAWinner() && (in_array($requiredPage, ['build.php', 'plus1.php']) || + (in_array($requiredPage, ['plus.php']) && isset($_GET['id']) && !empty($_GET['id'] && $_GET['id'] >= 7)))) + { + header('Location: winner.php'); + exit; + } + } + + /** + * Function to check Real Hero + * Made by: Shadow and brainiacX + * + */ - $this->PopulateVar(); + function CheckHeroReal () { + global $database,$link; - $database->updateActiveUser($user, $this->time); - $database->updateUserField($user, "sessid", $_SESSION['sessid'], 0); + $villageIDs = implode(', ', $this->villages); + if (!count($this->villages)) { + $this->Logout(); + header('login.php'); + exit; + } - $logging->addLoginLog($dbarray['id'], $_SERVER['REMOTE_ADDR']); + // check if hero unit for this player is present anywhere on the map + $q = ' + SELECT + IFNULL((SELECT SUM(hero) from '.TB_PREFIX.'enforcement where `from` IN('.$villageIDs.')), 0) + + IFNULL((SELECT SUM(hero) from '.TB_PREFIX.'units where `vref` IN('.$villageIDs.')), 0) + + IFNULL((SELECT SUM(t11) from '.TB_PREFIX.'prisoners where `from` IN('.$villageIDs.')), 0) + + IFNULL((SELECT SUM(t11) FROM '.TB_PREFIX.'movement, '.TB_PREFIX.'attacks WHERE '.TB_PREFIX.'movement.`from` IN('.$villageIDs.') and '.TB_PREFIX.'movement.ref = '.TB_PREFIX.'attacks.id and '.TB_PREFIX.'movement.proc = 0 and '.TB_PREFIX.'movement.sort_type = 3), 0) + + IFNULL((SELECT SUM(t11) FROM '.TB_PREFIX.'movement, '.TB_PREFIX.'attacks where '.TB_PREFIX.'movement.`to` IN('.$villageIDs.') and '.TB_PREFIX.'movement.ref = '.TB_PREFIX.'attacks.id and '.TB_PREFIX.'movement.proc = 0 and '.TB_PREFIX.'movement.sort_type = 4), 0) + as herocount'; + $heroUnitRegisters = mysqli_fetch_array( mysqli_query($database->dblink, $q, MYSQLI_ASSOC ))['herocount']; - if ($dbarray['id'] == 1) { - header("Location: nachrichten.php"); - } else { - header("Location: dorf1.php"); - } - exit; - } + // check if the actual hero is alive or being trained/revived into a living state + $isHeroLivingOrRaising = $database->getHeroDeadReviveOrInTraining($this->uid); - public function Logout() { - global $database; - - $this->logged_in = false; - - if(isset($_SESSION['username'])) { - $database->updateUserField($_SESSION['username'], "sessid", "", 0); - } - - $_SESSION = array(); - - if (ini_get("session.use_cookies")) { - $params = session_get_cookie_params(); - setcookie(session_name(), '', time() - 42000, - $params["path"], - $params["domain"], - $params["secure"], - $params["httponly"] - ); - } - - session_destroy(); - session_start(); - } - - public function changeChecker() { - global $generator; - - $this->checker = $_SESSION['checker'] = $generator->generateRandStr(3); - $this->mchecker = $_SESSION['mchecker'] = $generator->generateRandStr(5); - } - private function checkLogin() { - global $database; - - $user = ''; - $id = 0; - $admin = false; - $inAdmin = (strpos($_SERVER['REQUEST_URI'], '/Admin') !== false); - - if (!$inAdmin && isset($_SESSION['username'])) { - $user = $_SESSION['username']; - $id = isset($_SESSION['id_user']) ? (int)$_SESSION['id_user'] : 0; - } - else if ($inAdmin && isset($_SESSION['admin_username'])) { - $user = $_SESSION['admin_username']; - $id = isset($_SESSION['id']) ? (int)$_SESSION['id'] : 0; - $admin = true; - } - - if ($user && ($admin || isset($_SESSION['sessid']))) { - - $this->maintenance(); - $this->isWinner(); - - // 🔒 Support restriction hardening - if ($user === 'Support') { - $req_file = basename($_SERVER['PHP_SELF']); - $allowed = array( - 'nachrichten.php', - 'logout.php', - 'statistiken.php', - 'rules.php', - 'karte.php', - 'karte2.php', - 'spieler.php' - ); - - if (!in_array($req_file, $allowed)) { - header('Location: nachrichten.php'); - exit; + // if he doesn't register anywhere on the map but is marked as alive, + // we need to kill him + if(!$heroUnitRegisters && $isHeroLivingOrRaising) { + $database->KillMyHero($this->uid); } } - // Populate user data - $this->PopulateVar(); + private function PopulateVar() { + global $database; + + $this->userarray = $this->userinfo = $database->getUserArray($_SESSION['username'], 0); + $this->username = $this->userarray['username']; + $this->uid = $_SESSION['id_user'] = $this->userarray['id']; + $this->gpack = $this->userarray['gpack']; + $this->access = $this->userarray['access']; + $this->plus = ($this->userarray['plus'] > $this->time); + $this->goldclub = $this->userarray['goldclub']; + $this->villages = $database->getVillagesID($this->uid); + $this->tribe = $this->userarray['tribe']; + $this->isAdmin = $this->access >= MODERATOR; + $this->alliance = $_SESSION['alliance_user'] = $this->userarray['alliance']; + $this->checker = $_SESSION['checker']; + $this->mchecker = $_SESSION['mchecker']; + $this->sit = $database->GetOnline($this->uid); + $this->sit1 = $this->userarray['sit1']; + $this->sit2 = $this->userarray['sit2']; + $this->cp = floor($this->userarray['cp']); + $this->gold = $this->userarray['gold']; + $this->oldrank = $this->userarray['oldrank']; + $this->sharedForums = $database->getSharedForums($this->uid, $this->alliance); + $_SESSION['ok'] = $this->userarray['ok']; + + if($this->userarray['b1'] > $this->time) $this->bonus1 = 1; + if($this->userarray['b2'] > $this->time) $this->bonus2 = 1; + if($this->userarray['b3'] > $this->time) $this->bonus3 = 1; + if($this->userarray['b4'] > $this->time) $this->bonus4 = 1; - // Ban check - $this->isBanned(); + if (!in_array($this->username, ['Support', 'Multihunter'])) $this->CheckHeroReal(); + } + + /** + * Creates an array with the vrefs of attacked/scouted/reinforced villages and oasis + * + */ + + public function populateAttacks(){ + global $database, $village; + + $troopsMovement = $database->getMovement(3, $village->wid, 0); + if(count($troopsMovement) > 0){ + foreach($troopsMovement as $movement) + { + switch($movement['attack_type']){ + case 1: + $_SESSION['troops_movement']['scouts'][] = $movement['to']; + break; + case 2: + $_SESSION['troops_movement']['enforcements'][] = $movement['to']; + break; + case 3: + case 4: + $_SESSION['troops_movement']['attacks'][] = $movement['to']; + break; + } + } + } + } + + private function SurfControl(){ + if(SERVER_WEB_ROOT) { + $page = $_SERVER['SCRIPT_NAME']; + } else { + $explode = explode("/", $_SERVER['SCRIPT_NAME']); + $i = count($explode) - 1; + $page = $explode[$i]; - $database->updateActiveUser($user, $this->time); + } + $pagearray = array("index.php", "anleitung.php", "tutorial.php", "login.php", "activate.php", "anmelden.php", "xaccount.php"); + if(!$this->logged_in) { + if(!in_array($page, $pagearray) || $page == "logout.php") { + header("Location: login.php"); + exit; + } + } else { + if(in_array($page, $pagearray)) { + if ($this->uid == 1) { + header("Location: nachrichten.php"); + exit; + } else { + header("Location: dorf1.php"); + exit; + } + } - return true; - } + } + } +}; +$session = new Session; +$form = new Form; - return false; - } +// if there is no user, we'd try to load messages for user with ID 0, which is wrong +if (!empty($_SESSION['id_user'])) { + $message = new Message; - /** - * Ban control - */ - function isBanned() { - $current = basename($_SERVER['PHP_SELF']); - - if ($this->access == BANNED && - !in_array($current, array('banned.php','nachrichten.php','rules.php'))) { - - header('Location: banned.php'); - exit; - } - } - - /** - * Maintenance control - */ - function maintenance() { - $current = basename($_SERVER['PHP_SELF']); - - if (isset($_SESSION['ok']) && - $_SESSION['ok'] == 2 && - $current != 'maintenance.php') { - - header('Location: maintenance.php'); - exit; - } - } - - /** - * Winner check (WW level 100) - */ - function isWinner() { - global $database; - - $requiredPage = basename($_SERVER['PHP_SELF']); - - if ($database->isThereAWinner()) { - - $restricted = array('build.php', 'plus1.php'); - - if (in_array($requiredPage, $restricted) || - ($requiredPage == 'plus.php' && - isset($_GET['id']) && - is_numeric($_GET['id']) && - (int)$_GET['id'] >= 7)) { - - header('Location: winner.php'); - exit; - } - } - } - /** - * Hero integrity verification - * (Enterprise hardened – logic 1:1) - */ - function CheckHeroReal() { - global $database; - - if (!is_array($this->villages) || !count($this->villages)) { - $this->Logout(); - header('Location: login.php'); - exit; - } - - // 🔒 sanitize village IDs (critical SQL protection) - $safeVillageIDs = array(); - foreach ($this->villages as $v) { - $safeVillageIDs[] = (int)$v; - } - - $villageIDs = implode(',', $safeVillageIDs); - - $q = " - SELECT - IFNULL((SELECT SUM(hero) FROM ".TB_PREFIX."enforcement WHERE `from` IN($villageIDs)),0) + - IFNULL((SELECT SUM(hero) FROM ".TB_PREFIX."units WHERE `vref` IN($villageIDs)),0) + - IFNULL((SELECT SUM(t11) FROM ".TB_PREFIX."prisoners WHERE `from` IN($villageIDs)),0) + - IFNULL((SELECT SUM(t11) FROM ".TB_PREFIX."movement m - JOIN ".TB_PREFIX."attacks a ON m.ref = a.id - WHERE m.`from` IN($villageIDs) - AND m.proc = 0 AND m.sort_type = 3),0) + - IFNULL((SELECT SUM(t11) FROM ".TB_PREFIX."movement m - JOIN ".TB_PREFIX."attacks a ON m.ref = a.id - WHERE m.`to` IN($villageIDs) - AND m.proc = 0 AND m.sort_type = 4),0) - AS herocount - "; - - $res = mysqli_query($database->dblink, $q); - $row = mysqli_fetch_assoc($res); - $heroUnitRegisters = isset($row['herocount']) ? (int)$row['herocount'] : 0; - - $isHeroLivingOrRaising = $database->getHeroDeadReviveOrInTraining($this->uid); - - if (!$heroUnitRegisters && $isHeroLivingOrRaising) { - $database->KillMyHero($this->uid); - } - } - - /** - * Populate session variables (NO LOGIC CHANGE) - */ - private function PopulateVar() { - global $database; - - $this->userarray = $this->userinfo = - $database->getUserArray($_SESSION['username'], 0); - - if (!is_array($this->userarray)) { - $this->Logout(); - header('Location: login.php'); - exit; - } - - $this->username = $this->userarray['username']; - $this->uid = $_SESSION['id_user'] = (int)$this->userarray['id']; - $this->gpack = $this->userarray['gpack']; - $this->access = (int)$this->userarray['access']; - $this->plus = ($this->userarray['plus'] > $this->time); - $this->goldclub = (int)$this->userarray['goldclub']; - $this->tribe = (int)$this->userarray['tribe']; - $this->isAdmin = ($this->access >= MODERATOR); - $this->alliance = $_SESSION['alliance_user'] = (int)$this->userarray['alliance']; - - $this->checker = $_SESSION['checker']; - $this->mchecker = $_SESSION['mchecker']; - - $this->villages = $database->getVillagesID($this->uid); - $this->sit = $database->GetOnline($this->uid); - $this->sit1 = (int)$this->userarray['sit1']; - $this->sit2 = (int)$this->userarray['sit2']; - $this->cp = floor($this->userarray['cp']); - $this->gold = (int)$this->userarray['gold']; - $this->oldrank = (int)$this->userarray['oldrank']; - $this->sharedForums = $database->getSharedForums($this->uid, $this->alliance); - - $_SESSION['ok'] = $this->userarray['ok']; - - // bonuses - if ($this->userarray['b1'] > $this->time) $this->bonus1 = 1; - if ($this->userarray['b2'] > $this->time) $this->bonus2 = 1; - if ($this->userarray['b3'] > $this->time) $this->bonus3 = 1; - if ($this->userarray['b4'] > $this->time) $this->bonus4 = 1; - - if (!in_array($this->username, array('Support','Multihunter'))) { - $this->CheckHeroReal(); - } - } - - /** - * Populate attack indicators - */ - public function populateAttacks() { - global $database, $village; - - $_SESSION['troops_movement'] = array( - 'scouts' => array(), - 'enforcements' => array(), - 'attacks' => array() - ); - - $troopsMovement = $database->getMovement(3, $village->wid, 0); - - if (is_array($troopsMovement) && count($troopsMovement) > 0) { - - foreach ($troopsMovement as $movement) { - - switch ((int)$movement['attack_type']) { - - case 1: - $_SESSION['troops_movement']['scouts'][] = $movement['to']; - break; - - case 2: - $_SESSION['troops_movement']['enforcements'][] = $movement['to']; - break; - - case 3: - case 4: - $_SESSION['troops_movement']['attacks'][] = $movement['to']; - break; - } - } - } - } - /** - * Page access control - * Enterprise hardened – logic 1:1 - */ - private function SurfControl() { - - if (SERVER_WEB_ROOT) { - $page = basename($_SERVER['SCRIPT_NAME']); - } else { - $explode = explode("/", $_SERVER['SCRIPT_NAME']); - $page = end($explode); - } - - $allowedWithoutLogin = array( - "index.php", - "anleitung.php", - "tutorial.php", - "login.php", - "activate.php", - "anmelden.php", - "xaccount.php" - ); - - if (!$this->logged_in) { - - if (!in_array($page, $allowedWithoutLogin) || $page == "logout.php") { - header("Location: login.php"); - exit; - } - - } else { - - if (in_array($page, $allowedWithoutLogin)) { - - if ($this->uid == 1) { - header("Location: nachrichten.php"); - } else { - header("Location: dorf1.php"); - } - exit; - } - } - } - -} // END CLASS - -$session = new Session(); -$form = new Form(); - -/** - * Message + User init - * Enterprise safe instantiation - */ - -if (!empty($_SESSION['id_user']) && is_numeric($_SESSION['id_user'])) { - - $message = new Message(); - - // Safe casting - $user = new User((int)$_SESSION['id_user'], $database); + // create a global user variable which will later be removed from here + // and created + retrieved either via Service Locator or other DI concept + $user = new User((int) $_SESSION['id_user'], $database); } +?> diff --git a/GameEngine/Units.php b/GameEngine/Units.php index 33ff82a5..b80ccaac 100755 --- a/GameEngine/Units.php +++ b/GameEngine/Units.php @@ -88,6 +88,13 @@ class Units { else return $post; } + /** + * Gets an error if the user did a mistake + * + * @param array $post The array containing all of the needed informations + * @return string Returns the errors, or empty if no errors was found + */ + public function checkErrors(&$post){ global $database, $village, $session, $generator; @@ -227,1006 +234,584 @@ class Units { $database->deleteReinf($enforce['id']); } - private function sendTroops($post){ - global $form, $database, $village, $session; + private function sendTroops($post) { + global $form, $database, $village, $session; - /* - ========================================================= - = 1 LOAD ATTACK DATA - ========================================================= - */ - - $data = $database->getA2b($post['timestamp_checksum']); - $Gtribe = ($session->tribe == 1) ? "" : $session->tribe - 1; - - - /* - ========================================================= - = 2 BASIC UNIT VALIDATION - ========================================================= - */ - - for ($i = 1; $i < 10; $i++) { - - if (!isset($data['u' . $i])) { - continue; - } - - if ($data['u' . $i] > $village->unitarray['u' . $Gtribe . $i]) { - $form->addError("error", "You can't send more units than you have"); - break; - } - - if ($data['u' . $i] < 0) { - $form->addError("error", "You can't send negative units."); - break; - } - } - - - /* - ========================================================= - = 3️ RATE LIMIT PROTECTION - ========================================================= - */ - - if (!$database->checkAttackRateLimit($session->uid, 30)) { - - $form->addError("error", "Too many attacks. Please wait."); - - $_SESSION['errorarray'] = $form->getErrors(); - header("Location: a2b.php"); - exit; - } - - - /* - ========================================================= - = 4️ HERO VALIDATION - ========================================================= - */ - - if ($data['u11'] > $village->unitarray['hero']) { - $form->addError("error", "You can't send more units than you have"); - } - - if ($data['u11'] < 0) { - $form->addError("error", "You can't send negative units."); - } - - if ($data['type'] != 1 && $post['spy'] != 0) { - $post['spy'] = 0; - } - - - /* - ========================================================= - = 5️ ERROR CHECKPOINT - ========================================================= - */ - - if ($form->returnErrors() > 0) { - - $_SESSION['errorarray'] = $form->getErrors(); - $_SESSION['valuearray'] = $_POST; - - header("Location: a2b.php"); - exit; - } - - - /* - ========================================================= - = 6️ REMOVE UNITS FROM VILLAGE - ========================================================= - */ - - $u = ($session->tribe == 1) ? "" : $session->tribe - 1; - - $database->modifyUnit( - $village->wid, - [ - $u."1", $u."2", $u."3", $u."4", $u."5", - $u."6", $u."7", $u."8", $u."9", - $u.$session->tribe."0", - "hero" - ], - [ - $data['u1'], $data['u2'], $data['u3'], - $data['u4'], $data['u5'], $data['u6'], - $data['u7'], $data['u8'], $data['u9'], - $data['u10'], $data['u11'] - ], - array_fill(0, 11, 0) - ); - - - /* - ========================================================= - = 7️ CALCULATE MOVEMENT TIME - ========================================================= - */ - - $troopsTime = $this->getWalkingTroopsTime( - $village->wid, - $data['to_vid'], - $session->uid, - $session->tribe, - $data, - 1, - 'u' - ); - - $time = $database->getArtifactsValueInfluence( - $session->uid, - $village->wid, - 2, - $troopsTime - ); - - - /* - ========================================================= - = 8️ CATAPULT TARGET VALIDATION - ========================================================= - */ - - $to_owner = $database->getVillageField($data['to_vid'], "owner"); - $rivalsGreatConfusion = $database->getArtifactsSumByKind($to_owner, $data['to_vid'], 7); - - $rallyPointLevel = ($village->resarray)['f39']; - $invalidBuildings = []; - - if ($rallyPointLevel >= 3 && $rallyPointLevel < 5) { - - for ($i = 1; $i <= 37; $i++) { - if (!in_array($i, [10, 11])) { - $invalidBuildings[] = $i; - } - } - - } elseif ($rallyPointLevel >= 5 && $rallyPointLevel < 10) { - - for ($i = 12; $i <= 37; $i++) { - $invalidBuildings[] = $i; - } - - } elseif ($rallyPointLevel >= 10) { - - $invalidBuildings = [23, 31, 32, 33, 34, 36]; - } - - - /* - ========================================================= - = 9️ CTAR1 VALIDATION - ========================================================= - */ - - if (isset($post['ctar1']) && $post['ctar1'] != 0) { - - if ( - $rallyPointLevel < 3 || - $data['u8'] == 0 || - in_array($post['ctar1'], $invalidBuildings) || - $post['ctar1'] < 0 || - $post['ctar1'] > 40 - ) { - $post['ctar1'] = 0; - } - } - - - /* - ========================================================= - = 10 CREATE ATTACK + MOVEMENT - ========================================================= - */ - - $abdata = $database->getABTech($village->wid); - - $reference = $database->addAttack( - $village->wid, - $data['u1'], $data['u2'], $data['u3'], $data['u4'], $data['u5'], - $data['u6'], $data['u7'], $data['u8'], $data['u9'], $data['u10'], $data['u11'], - $data['type'], - $post['ctar1'] ?? 0, - $post['ctar2'] ?? 0, - $post['spy'] ?? 0, - $abdata['b1'], $abdata['b2'], $abdata['b3'], $abdata['b4'], - $abdata['b5'], $abdata['b6'], $abdata['b7'], $abdata['b8'] - ); - - $checkexist = $database->checkVilExist($data['to_vid']); - $checkoexist = $database->checkOasisExist($data['to_vid']); - - if ($checkexist || $checkoexist) { - - $database->addMovement( - 3, - $village->wid, - $data['to_vid'], - $reference, - time(), - ($time + time()) - ); - - if ($database->hasBeginnerProtection($village->wid) == 1 && $checkexist) { - - mysqli_query( - $database->dblink, - "UPDATE " . TB_PREFIX . "users - SET protect = 0 - WHERE id = " . (int)$session->uid - ); - } - } - - - /* - ========================================================= - = 11️ FINAL CHECK + CLEANUP - ========================================================= - */ - - if ($form->returnErrors() > 0) { - - $_SESSION['errorarray'] = $form->getErrors(); - $_SESSION['valuearray'] = $_POST; - - header("Location: a2b.php"); - exit; - } - - $database->remA2b($data['id']); - - header("Location: build.php?id=39"); - exit; -} - - -/* -========================================================= -= SEND TROOPS BACK -========================================================= -*/ - -private function sendTroopsBack($post) -{ - global $form, $database, $village, $session, $technology; - - /* - ----------------------------------------------------- - LOAD ENFORCEMENT DATA - ----------------------------------------------------- - */ - - $enforce = $database->getEnforceArray($post['ckey'], 0); - $enforceoasis = $database->getOasisEnforceArray($post['ckey'], 0); - - /* - ----------------------------------------------------- - PERMISSION CHECK - ----------------------------------------------------- - */ - - if ( - ($enforce['from'] == $village->wid) || - ($enforce['vref'] == $village->wid) || - ($enforceoasis['conqured'] == $village->wid) - ) { - - $to = $database->getVillage($enforce['from']); - - $Gtribe = ( - ($ownerTribe = $database->getUserField($to['owner'], 'tribe', 0)) == 1 - ) ? "" : $ownerTribe - 1; - - - /* - ----------------------------------------------------- - UNIT VALIDATION - ----------------------------------------------------- - */ + $data = $database->getA2b($post['timestamp_checksum']); + $Gtribe = ($session->tribe == 1) ? "" : $session->tribe - 1; for ($i = 1; $i < 10; $i++) { - - if (isset($post['t'.$i])) { - - if ($post['t'.$i] > $enforce['u'.$Gtribe.$i]) { - $form->addError("error", "You can't send back more units than you have"); + if (isset($data['u'.$i])) { + if ($data['u'.$i] > $village->unitarray['u'.$Gtribe.$i]) { + $form->addError("error", "You can't send more units than you have"); break; } - if ($post['t'.$i] < 0) { - $form->addError("error", "You can't send back negative units."); + if ($data['u'.$i] < 0) { + $form->addError("error", "You can't send negative units."); break; } - - } else { - $post['t'.$i] = '0'; } } - /* - ----------------------------------------------------- - HERO VALIDATION - ----------------------------------------------------- - */ - - if (isset($post['t11'])) { - - if ($post['t11'] > $enforce['hero']) { - $form->addError("error", "You can't send back more units than you have"); - } - - if ($post['t11'] < 0) { - $form->addError("error", "You can't send back negative units."); - } - - } else { - $post['t11'] = '0'; - } - - - /* - ----------------------------------------------------- - ERROR HANDLING - ----------------------------------------------------- - */ - - if ($form->returnErrors() > 0) { - + if($data['u11'] > $village->unitarray['hero']) $form->addError("error", "You can't send more units than you have"); + if($data['u11'] < 0) $form->addError("error", "You can't send negative units."); + if($data['type'] != 1 && $post['spy'] != 0) $post['spy'] = 0; + + if($form->returnErrors() > 0){ $_SESSION['errorarray'] = $form->getErrors(); $_SESSION['valuearray'] = $_POST; - - header("Location: a2b.php"); + header( "Location: a2b.php" ); + exit; + }else{ + $u = ($session->tribe == 1) ? "" : $session->tribe - 1; + + $database->modifyUnit( + $village->wid, + [ + $u . "1", + $u . "2", + $u . "3", + $u . "4", + $u . "5", + $u . "6", + $u . "7", + $u . "8", + $u . "9", + $u . $session->tribe . "0", + "hero" + ], + [ + $data['u1'], + $data['u2'], + $data['u3'], + $data['u4'], + $data['u5'], + $data['u6'], + $data['u7'], + $data['u8'], + $data['u9'], + $data['u10'], + $data['u11'] + ], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ); + + $troopsTime = $this->getWalkingTroopsTime($village->wid, $data['to_vid'], $session->uid, $session->tribe, $data, 1, 'u'); + $time = $database->getArtifactsValueInfluence($session->uid, $village->wid, 2, $troopsTime); + + // Check if have WW owner have artefact Rivals great confusion or Artefact of the unique fool with that effect + // If is a WW village you can target on WW , if is not a WW village catapults will target randomly. + // Like it says : Exceptions are the WW which can always be targeted and the treasure chamber which can always be targeted, except with the unique artifact. + // Fixed by Advocaite and Shadow - Optimized by iopietro + + $to_owner = $database->getVillageField($data['to_vid'], "owner"); + $rivalsGreatConfusion = $database->getArtifactsSumByKind($to_owner, $data['to_vid'], 7); + + $rallyPointLevel = ($village->resarray)['f39']; + $invalidBuildings = []; + + // fill the array with the invalid buildings + if($rallyPointLevel >= 3 && $rallyPointLevel < 5){ + for($i = 1; $i <= 37; $i++){ + if(!in_array($i, [10, 11])) $invalidBuildings[] = $i; + } + } + else if($rallyPointLevel >= 5 && $rallyPointLevel < 10){ + for($i = 12; $i <= 37; $i++) $invalidBuildings[] = $i; + } + else if($rallyPointLevel >= 10){ + $invalidBuildings = [23, 31, 32, 33, 34, 36]; + } + + if(isset($post['ctar1']) && $post['ctar1'] != 0){ + // check if the player has selected a valid building + if($rallyPointLevel < 3 || $data['u8'] == 0 || in_array($post['ctar1'], $invalidBuildings) || $post['ctar1'] < 0 || $post['ctar1'] > 40){ + $post['ctar1'] = 0; + } + } + + if(isset($post['ctar2']) && $post['ctar2'] != 0){ + // check if there are atleast 20 catapults + if($data['u8'] < 20 || $rallyPointLevel != 20){ + $post['ctar2'] = 0; + }else{ + // check if the player has selected a valid building + if(in_array($post['ctar2'], $invalidBuildings) || ($post['ctar2'] < 0 || $post['ctar2'] > 40 && $post['ctar2'] != 99)){ + $post['ctar2'] = 99; + } + } + } + + if(isset($post['ctar1'])) { + //Is the Brewery built? + if($session->tribe != 2 || $database->getFieldLevelInVillage($village->wid, 35) == 0){ + if($rivalsGreatConfusion['totals'] > 0) { + if($post['ctar1'] != 40 && ($post['ctar1'] != 27 || ($post['ctar1'] == 27 && $rivalsGreatConfusion['unique'] > 0))) { + $post['ctar1'] = 0; + } + } + } + else $post['ctar1'] = 0; + } + else $post['ctar1'] = 0; + + if(isset($post['ctar2']) && $post['ctar2'] > 0) { + //Is the Brewery built? + if($session->tribe != 2 || $database->getFieldLevelInVillage($village->wid, 35) == 0){ + if($rivalsGreatConfusion['totals'] > 0) { + if ($post['ctar2'] != 40 && ($post['ctar2'] != 27 || ($post['ctar2'] == 27 && $rivalsGreatConfusion['unique'] > 0))) { + $post['ctar2'] = 99; + } + } + } + else $post['ctar2'] = 99; + } + else $post['ctar2'] = 0; + + if(!isset($post['spy'])) $post['spy'] = 0; + + $abdata = $database->getABTech($village->wid); + $reference = $database->addAttack(($village->wid), $data['u1'], $data['u2'], $data['u3'], $data['u4'], $data['u5'], $data['u6'], $data['u7'], $data['u8'], $data['u9'], $data['u10'], $data['u11'], $data['type'], $post['ctar1'], $post['ctar2'], $post['spy'], $abdata['b1'], $abdata['b2'], $abdata['b3'], $abdata['b4'], $abdata['b5'], $abdata['b6'], $abdata['b7'], $abdata['b8']); + $checkexist = $database->checkVilExist($data['to_vid']); + $checkoexist = $database->checkOasisExist($data['to_vid']); + if($checkexist || $checkoexist) { + $database->addMovement(3, $village->wid, $data['to_vid'], $reference, time(), ($time + time())); + if ($database->hasBeginnerProtection($village->wid) == 1 && $checkexist) { + mysqli_query($database->dblink, "UPDATE " . TB_PREFIX . "users SET protect = 0 WHERE id = ".(int) $session->uid); + } + } + + if($form->returnErrors() > 0) { + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $_POST; + header("Location: a2b.php" ); + exit; + } + + // prevent re-use of the same attack via re-POSTing the same data + $database->remA2b($data['id']); + + header("Location: build.php?id=39"); exit; } - - - /* - ----------------------------------------------------- - APPLY UNIT CHANGES - ----------------------------------------------------- - */ - - $tribe = $database->getUserField($to['owner'], 'tribe', 0); - - $start = ($tribe - 1) * 10 + 1; - $end = $tribe * 10; - - $units = []; - $amounts = []; - $modes = []; - - $j = 1; - - for ($i = $start; $i <= $end; $i++) { - $units[] = $i; - $amounts[] = $post['t'.$j]; - $modes[] = 0; - $j++; - } - - $units[] = 'hero'; - $amounts[] = $post['t11']; - $modes[] = 0; - - $database->modifyEnforce($post['ckey'], $units, $amounts, $modes); - - - /* - ----------------------------------------------------- - CREATE RETURN MOVEMENT - ----------------------------------------------------- - */ - - $troopsTime = $this->getWalkingTroopsTime( - $enforce['from'], - $enforce['vref'], - $to['owner'], - $tribe, - $post, - 1, - 't' - ); - - $time = $database->getArtifactsValueInfluence( - $session->uid, - $village->wid, - 2, - $troopsTime - ); - - $reference = $database->addAttack( - $enforce['from'], - $post['t1'], $post['t2'], $post['t3'], - $post['t4'], $post['t5'], $post['t6'], - $post['t7'], $post['t8'], $post['t9'], - $post['t10'], $post['t11'], - 2, 0, 0, 0, 0 - ); - - $database->addMovement( - 4, - $village->wid, - $enforce['from'], - $reference, - time(), - ($time + time()) - ); - - $technology->checkReinf($post['ckey'], false); - - header("Location: build.php?id=39&refresh=1"); - exit; - - } else { - - $form->addError("error", "You cant change someones troops."); - - $_SESSION['errorarray'] = $form->getErrors(); - $_SESSION['valuearray'] = $_POST; - - header("Location: a2b.php"); - exit; } -} + private function sendTroopsBack($post) { + global $form, $database, $village, $session, $technology; + + $enforce = $database->getEnforceArray( $post['ckey'], 0 ); + $enforceoasis = $database->getOasisEnforceArray( $post['ckey'], 0 ); + if ( ( $enforce['from'] == $village->wid ) || ( $enforce['vref'] == $village->wid ) || ( $enforceoasis['conqured'] == $village->wid ) ) { + $to = $database->getVillage( $enforce['from'] ); + $Gtribe = ($ownerTribe = $database->getUserField( $to['owner'], 'tribe', 0)) == 1 ? "" : $ownerTribe - 1; + + for ( $i = 1; $i < 10; $i ++ ) { + if ( isset( $post[ 't' . $i ] ) ) { + if ( $i != 10 ) { + if ( $post[ 't' . $i ] > $enforce[ 'u' . $Gtribe . $i ] ) { + $form->addError( "error", "You can't send back more units than you have" ); + break; + } + + if ( $post[ 't' . $i ] < 0 ) { + $form->addError( "error", "You can't send back negative units." ); + break; + } + } + } else { + $post[ 't' . $i . '' ] = '0'; + } + } + if ( isset( $post['t11'] ) ) { + if ( $post['t11'] > $enforce['hero'] ) { + $form->addError( "error", "You can't send back more units than you have" ); + } + + if ( $post['t11'] < 0 ) { + $form->addError( "error", "You can't send back negative units." ); + } + } else { + $post['t11'] = '0'; + } + + if ( $form->returnErrors() > 0 ) { + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $_POST; + header( "Location: a2b.php" ); + exit; + } else { + + //change units + $tribe = $database->getUserField($to['owner'], 'tribe', 0); + $start = ($tribe - 1 ) * 10 + 1; + $end = $tribe * 10 ; + + $units = []; + $amounts = []; + $modes = []; + + $j = 1; + for ( $i = $start; $i <= $end; $i ++ ) { + $units[] = $i; + $amounts[] = $post[ 't' . $j . '' ]; + $modes[] = 0; + $j ++; + } + + $units[] = 'hero'; + $amounts[] = $post['t11']; + $modes[] = 0; + + $database->modifyEnforce($post['ckey'], $units, $amounts, $modes); + $j++; + + $troopsTime = $this->getWalkingTroopsTime($enforce['from'], $enforce['vref'], $to['owner'], $tribe, $post, 1, 't'); + $time = $database->getArtifactsValueInfluence($session->uid, $village->wid, 2, $troopsTime); + + $reference = $database->addAttack($enforce['from'], $post['t1'], $post['t2'], $post['t3'], $post['t4'], $post['t5'], $post['t6'], $post['t7'], $post['t8'], $post['t9'], $post['t10'], $post['t11'], 2, 0, 0, 0, 0); + $database->addMovement(4, $village->wid, $enforce['from'], $reference, time(), ($time + time())); + $technology->checkReinf($post['ckey'], false); + + header("Location: build.php?id=39&refresh=1"); + exit(); + } + }else{ + $form->addError("error", "You cant change someones troops."); + if($form->returnErrors() > 0){ + $_SESSION['errorarray'] = $form->getErrors(); + $_SESSION['valuearray'] = $_POST; + header("Location: a2b.php"); + exit(); + } + } + } -/* -========================================================= -= SETTLERS - FOUND NEW VILLAGE -========================================================= -*/ + public function Settlers($post) { + global $form, $database, $village, $session; -public function Settlers($post) -{ - global $form, $database, $village, $session; - - $mode = CP; - $total = count($database->getProfileVillages($session->uid)); - $need_cps = ${'cp'.$mode}[$total + 1]; - $cps = $session->cp; - - $rallypoint = $database->getResourceLevel($village->wid); - - - /* - ----------------------------------------------------- - VALIDATION CONDITIONS - ----------------------------------------------------- - */ - - $validVillage = - isset($post['s']) && - ($newvillage = $database->getMInfo($post['s']))['id'] > 0 && - $newvillage['occupied'] == 0 && - $newvillage['oasistype'] == 0; - - $hasSettlers = - $village->unitarray['u'.$session->tribe.'0'] >= 3; - - $hasRally = - $rallypoint['f39'] > 0; - - - /* - ----------------------------------------------------- - EXECUTION - ----------------------------------------------------- - */ - - if ($hasRally && $hasSettlers && $validVillage) { - - if ($cps >= $need_cps) { - - $troopsTime = $this->getWalkingTroopsTime( - $village->wid, - $newvillage['id'], - 0, - 0, - [300], - 0 - ); - - $time = $database->getArtifactsValueInfluence( - $session->uid, - $village->wid, - 2, - $troopsTime - ); - - $unit = ($session->tribe * 10); - - $database->modifyResource($village->wid, 750, 750, 750, 750, 0); - $database->modifyUnit($village->wid, [$unit], [3], [0]); - - $database->addMovement( - 5, - $village->wid, - $post['s'], - 0, - time(), - time() + $time - ); + $mode = CP; + $total = count($database->getProfileVillages($session->uid)); + $need_cps = ${'cp'.$mode}[$total + 1]; + $cps = $session->cp; + $rallypoint = $database->getResourceLevel($village->wid); + + //-- Prevent user from founding a new village if there are not enough settlers or the player put an invalid village ID or an already occupied one + //-- fix by AL-Kateb - Semplified and additions by iopietro + if ($rallypoint['f39'] > 0 && $village->unitarray['u'.$session->tribe.'0'] >= 3 && isset($post['s']) && ($newvillage = $database->getMInfo($post['s']))['id'] > 0 && $newvillage['occupied'] == 0 && $newvillage['oasistype'] == 0) { + if ($cps >= $need_cps) { + $troopsTime = $this->getWalkingTroopsTime($village->wid, $newvillage['id'], 0, 0, [300], 0); + $time = $database->getArtifactsValueInfluence($session->uid, $village->wid, 2, $troopsTime); + + $unit = ($session->tribe * 10); + $database->modifyResource($village->wid, 750, 750, 750, 750, 0); + $database->modifyUnit($village->wid, [$unit], [3], [0]); + $database->addMovement(5, $village->wid, $post['s'], 0, time(), time() + $time); + } + header("Location: build.php?id=39"); + exit; + } else { + header("Location: dorf1.php"); + exit; } - - header("Location: build.php?id=39"); - exit; - - } else { - - header("Location: dorf1.php"); - exit; - } -} - - -/* -========================================================= -= HERO DATA LOADER -========================================================= -*/ - -public function Hero($uid, $all = 0, $include_dead = false) -{ - global $database; - - $heroarray = $database->getHero($uid, $all, $include_dead); - - if (!count($heroarray)) { - return false; } - /* - ----------------------------------------------------- - SINGLE HERO MODE - ----------------------------------------------------- - */ - - if (!$all) { - + public function Hero($uid, $all = 0, $include_dead = false) { + global $database; + $heroarray = $database->getHero($uid, $all, $include_dead); $herodata = false; $singleHeroArrayID = 0; - foreach ($heroarray as $id => $hero) { - - if (!$herodata && $hero['dead'] != 1) { - $herodata = $GLOBALS["h".$hero['unit']]; - $singleHeroArrayID = $id; - break; - } + // no hero data found + if (!count($heroarray)) { + return false; } - if (!$herodata) { - $herodata = $GLOBALS["h".$heroarray[0]['unit']]; - } - - $hero = $heroarray[$singleHeroArrayID]; - - $h_atk = $herodata['atk'] + 5 * floor($hero['attack'] * $herodata['atkp'] / 5); - $h_di = $herodata['di'] + 5 * floor($hero['defence'] * $herodata['dip'] / 5); - $h_dc = $herodata['dc'] + 5 * floor($hero['defence'] * $herodata['dcp'] / 5); - - return [ - 'heroid' => $hero['heroid'], - 'unit' => $hero['unit'], - 'name' => $hero['name'], - 'level' => $hero['level'], - 'atk' => $h_atk, - 'di' => $h_di, - 'dc' => $h_dc, - 'health' => $hero['health'], - 'dead' => $hero['dead'], - 'experience' => $hero['experience'] - ]; - } - - /* - ----------------------------------------------------- - MULTI HERO MODE - ----------------------------------------------------- - */ - - $heroes = []; - - foreach ($heroarray as $id => $hero) { - - $herodata = $GLOBALS["h".$hero['unit']]; - - $h_atk = $herodata['atk'] + 5 * floor($hero['attack'] * $herodata['atkp'] / 5); - $h_di = $herodata['di'] + 5 * floor($hero['defence'] * $herodata['dip'] / 5); - $h_dc = $herodata['dc'] + 5 * floor($hero['defence'] * $herodata['dcp'] / 5); - - $heroes[] = [ - 'heroid' => $hero['heroid'], - 'unit' => $hero['unit'], - 'level' => $hero['level'], - 'atk' => $h_atk, - 'di' => $h_di, - 'dc' => $h_dc - ]; - } - - return $heroes; -} - -/* -========================================================= -= DELETE / RELEASE PRISONERS -========================================================= -*/ - -public function deletePrisoners($id) -{ - global $village, $database, $session, $building, $bid19, $u99; - - $prisoner = $database->getPrisonersByID($id); - $troops = 0; - - /* - ----------------------------------------------------- - CASE 1: PRISONER IN CURRENT VILLAGE - ----------------------------------------------------- - */ - - if ($prisoner['wref'] == $village->wid) { - - $p_owner = $database->getVillageField($prisoner['from'], "owner"); - $p_tribe = $database->getUserField($p_owner, "tribe", 0); - - $troopsTime = $this->getWalkingTroopsTime( - $prisoner['from'], - $prisoner['wref'], - $p_owner, - $p_tribe, - $prisoner, - 1, - 't' - ); - - $p_time = $database->getArtifactsValueInfluence( - $p_owner, - $prisoner['from'], - 2, - $troopsTime - ); - - $p_reference = $database->addAttack( - $prisoner['from'], - $prisoner['t1'], $prisoner['t2'], $prisoner['t3'], - $prisoner['t4'], $prisoner['t5'], $prisoner['t6'], - $prisoner['t7'], $prisoner['t8'], $prisoner['t9'], - $prisoner['t10'], $prisoner['t11'], - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ); - - $database->addMovement( - 4, - $prisoner['wref'], - $prisoner['from'], - $p_reference, - time(), - ($p_time + time()) - ); - - for ($i = 1; $i <= 11; $i++) { - $troops += $prisoner['t'.$i]; - } - - /* - RESET TRAPS - */ - - $database->modifyUnit($village->wid, ["99", "99o"], [$troops, $troops], [0, 0]); - - $repairDuration = $database->getArtifactsValueInfluence( - $session->uid, - $village->wid, - 5, - round( - ($bid19[max($building->getTypeLevel(36, $village->wid), 1)]['attri'] / 100) - * $u99['time'] / SPEED - ) - ); - - $database->trainUnit($village->wid, 99, $troops, $u99['pop'], $repairDuration, 0); - - $database->deletePrisoners($prisoner['id']); - } - - /* - ----------------------------------------------------- - CASE 2: PRISONER CAPTURED FROM CURRENT VILLAGE - ----------------------------------------------------- - */ - - elseif ($prisoner['from'] == $village->wid) { - - $prisonersToOwner = $database->getVillageField($prisoner['wref'], "owner"); - - for ($i = 1; $i <= 11; $i++) { - $troops += $prisoner['t'.$i]; - } - - /* - HERO DEATH - */ - - if ($prisoner['t11'] > 0) { - - $p_owner = $database->getVillageField($prisoner['from'], "owner"); - - mysqli_query( - $database->dblink, - "UPDATE ".TB_PREFIX."hero - SET `dead` = '1', `health` = '0' - WHERE `uid` = '".$p_owner."' - AND dead = 0" - ); - } - - /* - RESET TRAPS - */ - - $database->modifyUnit($prisoner['wref'], ["99", "99o"], [$troops, $troops], [0, 0]); - - if (($troops = round($troops / 3)) > 0) { - - $repairDuration = $database->getArtifactsValueInfluence( - $prisonersToOwner, - $prisoner['wref'], - 5, - round( - ($bid19[max($building->getTypeLevel(36, $prisoner['wref']), 1)]['attri'] / 100) - * $u99['time'] / SPEED - ) - ); - - $database->trainUnit($prisoner['wref'], 99, $troops, $u99['pop'], $repairDuration, 0); - } - - $database->deletePrisoners($prisoner['id']); - } - - header("Location: build.php?id=39"); - exit; -} - - -/* -========================================================= -= CALCULATE WALKING TIME -========================================================= -*/ - -public function getWalkingTroopsTime( - $from, - $to, - $owner, - $tribe, - $unitArray, - $mode, - $unit = "" -) -{ - global $generator, $database; - - $fromCoor = $database->getCoor($from); - $toCoor = $database->getCoor($to); - - $fromCor = ['x' => $fromCoor['x'], 'y' => $fromCoor['y']]; - $toCor = ['x' => $toCoor['x'], 'y' => $toCoor['y']]; - - if (!$mode) { - return $generator->procDistanceTime( - $fromCor, - $toCor, - $unitArray[0], - $mode, - $from - ); - } - - $start = ($tribe - 1) * 10 + 1; - $end = $tribe * 10; - - $speeds = []; - - /* - FIND SLOWEST UNIT - */ - - if (!empty($unit)) { - - for ($i = 1; $i <= 11; $i++) { - $unitArray[$i - 1] = - (isset($unitArray[$unit.$i]) && $unitArray[$unit.$i] > 0) - ? $unitArray[$unit.$i] - : 0; - } - - } else { - - for ($i = $start; $i <= $end; $i++) { - $unitArray[$i - $start] = - (isset($unitArray['u'.$i]) && $unitArray['u'.$i] > 0) - ? $unitArray['u'.$i] - : 0; - } - - $unitArray[10] = - (isset($unitArray['hero']) && $unitArray['hero'] > 0) - ? $unitArray['hero'] - : 0; - } - - for ($i = 0; $i <= 9; $i++) { - if (isset($unitArray[$i]) && $unitArray[$i] > 0) { - $speeds[] = $GLOBALS['u'.($i + $start)]['speed']; - } - } - - if (isset($unitArray[10]) && $unitArray[10] > 0) { - $heroUnit = $database->getHeroField($owner, 'unit'); - $speeds[] = $GLOBALS['u'.$heroUnit]['speed']; - } - - return $generator->procDistanceTime( - $fromCor, - $toCor, - min($speeds), - $mode, - $from - ); -} - - - /* -========================================================= -= START RAID LIST -========================================================= -*/ - -public function startRaidList($post) -{ - global $database, $generator, $session; - - $slots = $post['slot']; - - if (empty($slots)) { - header("Location: build.php?id=39&t=99"); - exit(); - } - - foreach ($slots as $slot) { - - $raidList = $database->getRaidList($slot); - $getFLData = $database->getFLData($raidList['lid']); - - /* - OWNERSHIP CHECK - */ - - if ($getFLData['owner'] != $session->uid) { - continue; - } - - $villageUnits = $database->getUnit($getFLData['wref'], false); - - $wref = $raidList['towref']; - - for ($i = 1; $i <= 6; $i++) { - ${'t'.$i} = $raidList['t'.$i]; - } - - /* - TARGET ACCESS VALIDATION - */ - - if (!$database->isVillageOases($wref)) - $villageOwner = $database->getVillageField($wref, 'owner'); - else - $villageOwner = $database->getOasisField($wref, 'owner'); - - $userAccess = $database->getUserField($villageOwner, 'access', 0); - $userID = $database->getUserField($villageOwner, 'id', 0); - - if ( - $userAccess != 0 && - !($userAccess == MULTIHUNTER && $userID == 5) && - ($userAccess != ADMIN || - (ADMIN_ALLOW_INCOMING_RAIDS && $userAccess == ADMIN)) - ) { - - $start = ($session->tribe - 1) * 10 + 1; - $end = $start + 5; - - $canSend = true; - - for ($i = $start; $i <= $end; $i++) { - if ($villageUnits['u'.$i] < ${'t'.($i - $start + 1)}) { - $canSend = false; + // check all heroes and load hero data for the one, + // whose data were updated more recently - if we're not getting all of them + if (!$all) { + foreach ($heroarray as $id => $hero) { + // try to load a hero who's alive first + if (!$herodata && $hero['dead'] != 1) { + // this global value comes from GameEngine/Data/unitdata.php + $herodata = $GLOBALS["h".$hero['unit']]; + $singleHeroArrayID = $id; break; } } - if ($canSend) { - - $ckey = $generator->generateRandStr(6); - - $id = $database->addA2b( - $ckey, 0, $wref, - $t1, $t2, $t3, $t4, $t5, $t6, - 0, 0, 0, 0, 0, 4 - ); - - $data = $database->getA2b($ckey); - - $troopsTime = $this->getWalkingTroopsTime( - $getFLData['wref'], - $data['to_vid'], - $session->uid, - $session->tribe, - $data, - 1, - 'u' - ); - - $time = $database->getArtifactsValueInfluence( - $getFLData['owner'], - $getFLData['wref'], - 2, - $troopsTime - ); - - $abdata = $database->getABTech($getFLData['wref']); - - $reference = $database->addAttack( - $getFLData['wref'], - $data['u1'], $data['u2'], $data['u3'], - $data['u4'], $data['u5'], $data['u6'], - 0, 0, 0, 0, 0, - $data['type'], - 0, 0, 0, - $abdata['b1'], $abdata['b2'], - $abdata['b3'], $abdata['b4'], - $abdata['b5'], $abdata['b6'], - $abdata['b7'], $abdata['b8'] - ); - - $troops = []; - $amounts = []; - $modes = []; - - for ($u = $start; $u <= $end; $u++) { - $troops[] = $u; - $amounts[] = $data['u'.($u - $start + 1)]; - $modes[] = 0; - } - - $database->modifyUnit($getFLData['wref'], $troops, $amounts, $modes); - - $database->addMovement( - 3, - $getFLData['wref'], - $data['to_vid'], - $reference, - time(), - ($time + time()) - ); - - $database->remA2b($id); + // if we couldn't get a living hero, + // resort to loading the first one from the list, + // as that would be the one most recently updated/used + if (!$herodata) { + // this global value comes from GameEngine/Data/unitdata.php + $herodata = $GLOBALS["h".$heroarray[0]['unit']]; } + + $h_atk = $herodata['atk'] + 5 * floor($heroarray[$singleHeroArrayID]['attack'] * $herodata['atkp'] / 5); + $h_di = $herodata['di'] + 5 * floor($heroarray[$singleHeroArrayID]['defence'] * $herodata['dip'] / 5); + $h_dc = $herodata['dc'] + 5 * floor($heroarray[$singleHeroArrayID]['defence'] * $herodata['dcp'] / 5); + $h_ob = 1 + 0.002 * $heroarray[$singleHeroArrayID]['attackbonus']; + $h_db = 1 + 0.002 * $heroarray[$singleHeroArrayID]['defencebonus']; + + return [ + 'heroid' => $heroarray[$singleHeroArrayID]['heroid'], + 'unit' => $heroarray[$singleHeroArrayID]['unit'], + 'name' => $heroarray[$singleHeroArrayID]['name'], + 'inrevive' => $heroarray[$singleHeroArrayID]['inrevive'], + 'intraining' => $heroarray[$singleHeroArrayID]['intraining'], + 'trainingtime' => $heroarray[$singleHeroArrayID]['trainingtime'], + 'level' => $heroarray[$singleHeroArrayID]['level'], + 'attack' => $heroarray[$singleHeroArrayID]['attack'], + 'atk' => $h_atk, + 'defence' => $heroarray[$singleHeroArrayID]['defence'], + 'di' => $h_di, + 'dc' => $h_dc, + 'attackbonus' => $heroarray[$singleHeroArrayID]['attackbonus'], + 'ob' => $h_ob, + 'defencebonus' => $heroarray[$singleHeroArrayID]['defencebonus'], + 'db' => $h_db, + 'regeneration' => $heroarray[$singleHeroArrayID]['regeneration'], + 'health' => $heroarray[$singleHeroArrayID]['health'], + 'dead' => $heroarray[$singleHeroArrayID]['dead'], + 'points' => $heroarray[$singleHeroArrayID]['points'], + 'experience' => $heroarray[$singleHeroArrayID]['experience'] + ]; + } else { + // build up a full array of heroes and their stats + $heroes = []; + foreach ($heroarray as $id => $hero) { + $herodata = $GLOBALS["h".$heroarray[$id]['unit']]; + + $h_atk = $herodata['atk'] + 5 * floor($heroarray[$id]['attack'] * $herodata['atkp'] / 5); + $h_di = $herodata['di'] + 5 * floor($heroarray[$id]['defence'] * $herodata['dip'] / 5); + $h_dc = $herodata['dc'] + 5 * floor($heroarray[$id]['defence'] * $herodata['dcp'] / 5); + $h_ob = 1 + 0.002 * $heroarray[$id]['attackbonus']; + $h_db = 1 + 0.002 * $heroarray[$id]['defencebonus']; + + $heroes[] = [ + 'heroid' => $heroarray[$id]['heroid'], + 'unit' => $heroarray[$id]['unit'], + 'name' => $heroarray[$id]['name'], + 'inrevive' => $heroarray[$id]['inrevive'], + 'intraining' => $heroarray[$id]['intraining'], + 'trainingtime' => $heroarray[$id]['trainingtime'], + 'level' => $heroarray[$id]['level'], + 'attack' => $heroarray[$id]['attack'], + 'atk' => $h_atk, + 'defence' => $heroarray[$id]['defence'], + 'di' => $h_di, + 'dc' => $h_dc, + 'attackbonus' => $heroarray[$id]['attackbonus'], + 'ob' => $h_ob, + 'defencebonus' => $heroarray[$id]['defencebonus'], + 'db' => $h_db, + 'regeneration' => $heroarray[$id]['regeneration'], + 'health' => $heroarray[$id]['health'], + 'dead' => $heroarray[$id]['dead'], + 'points' => $heroarray[$id]['points'], + 'experience' => $heroarray[$id]['experience'] + ]; + } + + return $heroes; } } + + /** + * Function to kill/release prisoners + * + * @param int the ID of the prisoners you want to release + */ + + public function deletePrisoners($id){ + global $village, $database, $session, $building, $bid19, $u99; + + $prisoner = $database->getPrisonersByID($id); + $troops = 0; + if($prisoner['wref'] == $village->wid){ + $p_owner = $database->getVillageField($prisoner['from'], "owner"); + $p_tribe = $database->getUserField($p_owner, "tribe", 0); + + $troopsTime = $this->getWalkingTroopsTime($prisoner['from'], $prisoner['wref'], $p_owner, $p_tribe, $prisoner, 1, 't'); + $p_time = $database->getArtifactsValueInfluence($p_owner, $prisoner['from'], 2, $troopsTime); + + $p_reference = $database->addAttack($prisoner['from'], $prisoner['t1'],$prisoner['t2'], $prisoner['t3'], $prisoner['t4'], $prisoner['t5'], $prisoner['t6'], $prisoner['t7'], $prisoner['t8'], $prisoner['t9'], $prisoner['t10'], $prisoner['t11'], 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + $database->addMovement(4, $prisoner['wref'], $prisoner['from'], $p_reference, time(), ($p_time + time())); + + for($i = 1; $i <= 11; $i++) $troops += $prisoner['t'.$i]; + + //Reset traps + $database->modifyUnit($village->wid, ["99", "99o"], [$troops, $troops], [0, 0]); + $repairDuration = $database->getArtifactsValueInfluence($session->uid, $village->wid, 5, round(($bid19[max($building->getTypeLevel(36, $village->wid), 1)]['attri'] / 100) * $u99['time'] / SPEED)); + $database->trainUnit($village->wid, 99, $troops, $u99['pop'], $repairDuration, 0); + + $database->deletePrisoners($prisoner['id']); + }else if($prisoner['from'] == $village->wid){ + $prisonersToOwner = $database->getVillageField($prisoner['wref'], "owner"); + + for($i = 1; $i <= 11; $i++) $troops += $prisoner['t'.$i]; + + if($prisoner['t11'] > 0){ + $p_owner = $database->getVillageField($prisoner['from'], "owner"); + mysqli_query($database->dblink, "UPDATE ".TB_PREFIX."hero SET `dead` = '1', `health` = '0' WHERE `uid` = '".$p_owner."' AND dead = 0"); + } + + //Reset traps + $database->modifyUnit($prisoner['wref'], ["99", "99o"], [$troops, $troops], [0, 0]); + + if(($troops = round($troops / 3)) > 0){ + $repairDuration = $database->getArtifactsValueInfluence($prisonersToOwner, $prisoner['wref'], 5, round(($bid19[max($building->getTypeLevel(36, $prisoner['wref']), 1)]['attri'] / 100) * $u99['time'] / SPEED)); + $database->trainUnit($prisoner['wref'], 99, $troops, $u99['pop'], $repairDuration, 0); + } + + $database->deletePrisoners($prisoner['id']); + } + + header("Location: build.php?id=39"); + exit; + } + + /** + * Get how much time troops spend to walk from a village to another + * + * @param int $from The start village ID + * @param int $to The target village ID + * @param int $owner The owner of the troops + * @param int $tribe The tribe of the owner's troops + * @param array $unitArray The array containing troops count if mode is 0, otherwise it'll contains the troop speed + * @param int $mode How the time should be calculated + * @return int Returns the time troops take to walk from a village to another + */ + + public function getWalkingTroopsTime($from, $to, $owner, $tribe, $unitArray, $mode, $unit = ""){ + global $generator, $database; - header("Location: build.php?id=39&t=99"); - exit(); -} + $fromCoor = $database->getCoor($from); + $toCoor = $database->getCoor($to); + $fromCor = ['x' => $fromCoor['x'], 'y' => $fromCoor['y']]; + $toCor = ['x' => $toCoor['x'], 'y' => $toCoor['y']]; + + if(!$mode) return $generator->procDistanceTime($fromCor, $toCor, $unitArray[0], $mode, $from); + + $start = ($tribe - 1) * 10 + 1; + $end = $tribe * 10; + + $speeds = []; + + //Find slowest unit + if(!empty($unit)){ + for($i = 1; $i <= 11; $i++){ + if(isset($unitArray[$unit.$i]) && $unitArray[$unit.$i] > 0) $unitArray[$i - 1] = $unitArray[$unit.$i]; + else $unitArray[$i - 1] = 0; + } + }else{ + for($i = $start; $i <= $end; $i++){ + if(isset($unitArray['u'.$i]) && $unitArray['u'.$i] > 0) $unitArray[$i - $start] = $unitArray['u'.$i]; + else $unitArray[$i - $start] = 0; + } + + if(isset($unitArray['hero']) && $unitArray['hero'] > 0){ + $unitArray[10] = $unitArray['hero']; + } + else $unitArray[10] = 0; + } + + for($i = 0; $i <= 9; $i++){ + if(isset($unitArray[$i]) && $unitArray[$i] > 0){ + $speeds[] = $GLOBALS['u'.($i + $start)]['speed']; + } + } + + if(isset($unitArray[10]) && $unitArray[10] > 0){ + $heroUnit = $database->getHeroField($owner, 'unit'); + $speeds[] = $GLOBALS['u'.$heroUnit]['speed']; + } + + return $generator->procDistanceTime($fromCor, $toCor, min($speeds), $mode, $from); + } + + public function startRaidList($post){ + global $database, $generator, $session; + + $slots = $post['slot']; + if(empty($slots)){ + header("Location: build.php?id=39&t=99"); + exit(); + } + + $tribe = $session->tribe; + + foreach($slots as $slot){ + $raidList = $database->getRaidList($slot); + $getFLData = $database->getFLData($raidList['lid']); + + //Check if we're trying to start our raidlists or other players raidlist + if($getFLData['owner'] != $session->uid) continue; + + //Get the units in the village + $villageUnits = $database->getUnit($getFLData['wref'], false); + + $sid = $raidList['id']; + $wref = $raidList['towref']; + + for($i = 1; $i <= 6; $i++) ${'t'.$i} = $raidList['t'.$i]; + + if(!$database->isVillageOases($wref)) $villageOwner = $database->getVillageField($wref, 'owner'); + else $villageOwner = $database->getOasisField($wref, 'owner'); + + $userAccess = $database->getUserField($villageOwner, 'access', 0); + $userID = $database->getUserField($villageOwner, 'id', 0); + + if($userAccess != 0 && !($userAccess == MULTIHUNTER && $userID == 5) && ($userAccess != ADMIN || (ADMIN_ALLOW_INCOMING_RAIDS && $userAccess == ADMIN))){ + + //Start = the first troop of the player's tribe + //End = the last selectable troop of the player's tribe + $start = ($session->tribe - 1) * 10 + 1; + $end = $start + 5; + + //Check if we've enough troops + $canSend = true; + for($i = $start; $i <= $end; $i++){ + if($villageUnits['u'.$i] < ${'t'.($i - $start + 1)}){ + $canSend = false; + break; + } + } + + //Send the attack + if($canSend){ + $ckey = $generator->generateRandStr(6); + $id = $database->addA2b($ckey, 0, $wref, $t1, $t2, $t3, $t4, $t5, $t6, 0, 0, 0, 0, 0, 4); + $data = $database->getA2b($ckey); + + $troopsTime = $this->getWalkingTroopsTime($getFLData['wref'], $data['to_vid'], $session->uid, $session->tribe, $data, 1, 'u'); + $time = $database->getArtifactsValueInfluence($getFLData['owner'], $getFLData['wref'], 2, $troopsTime); + + $abdata = $database->getABTech($getFLData['wref']); + $reference = $database->addAttack(($getFLData['wref']), $data['u1'], $data['u2'], $data['u3'], $data['u4'], $data['u5'], $data['u6'], 0, 0, 0, 0, 0, $data['type'], 0, 0, 0, $abdata['b1'], $abdata['b2'], $abdata['b3'], $abdata['b4'], $abdata['b5'], $abdata['b6'], $abdata['b7'], $abdata['b8']); + + $troops = []; + $amounts = []; + $modes = []; + + for($u = $start; $u <= $end; $u++){ + $troops[] = $u; + $amounts[] = $data['u'.($u - $start + 1)]; + $modes[] = 0; + } + + $database->modifyUnit($getFLData['wref'], $troops, $amounts, $modes); + $database->addMovement(3, $getFLData['wref'], $data['to_vid'], $reference, time(), ($time + time())); + + //Prevent re-use of the same attack via re-POSTing the same data + $database->remA2b($id); + } + } + } + header("Location: build.php?id=39&t=99"); + exit(); + } }; $units = new Units; diff --git a/GameEngine/index.php b/GameEngine/index.php index bb8da7d4..a81240cd 100755 --- a/GameEngine/index.php +++ b/GameEngine/index.php @@ -8,22 +8,12 @@ ## Copyright: TravianZ (c) 2010-2025. All rights reserved. ## ## ## ################################################################################# - -// Send proper 404 header if not already sent -if (!headers_sent()) { - header("HTTP/1.1 404 Not Found"); - header("Content-Type: text/html; charset=UTF-8"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Pragma: no-cache"); -} ?>
-
-

404 - File not found

- Not Found
-

We looked 404 times already but can't find anything, Not even an X marking the spot.

-

This system is not complete yet. So the page probably does not exist.


-
+
+

404 - File not found

+ Not Found
+

We looked 404 times already but can't find anything, Not even an X marking the spot.

+

This system is not complete yet. So the page probably does not exist.


+
\ No newline at end of file diff --git a/Templates/a2b/attack.tpl b/Templates/a2b/attack.tpl index adf3643a..257cda58 100644 --- a/Templates/a2b/attack.tpl +++ b/Templates/a2b/attack.tpl @@ -326,63 +326,5 @@ $end = $tribe * 10; class="dynamic_img " src="img/x.gif" alt="OK" type="image" onclick="if (this.disabled==false) {document.getElementsByTagName('form')[0].submit();} this.disabled=true;" onLoad="this.disabled=false;">

- -